blob: 81110c2af69b9640fb5cf4bb73187277c56a73a0 [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 /*
18 * Step 1 of support for weak-linking a number of symbols existing on
19 * 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
76#include <sys/wait.h> /* For WNOHANG */
77#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
Guido van Rossumc5a0f531997-12-02 20:36:02 +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
107#define HAVE_SYSTEM 1
108#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
114#ifdef __BORLANDC__ /* Borland compiler */
115#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
120#define HAVE_SYSTEM 1
121#define HAVE_WAIT 1
122#else
123#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000124#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +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
129#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000130#define HAVE_CWAIT 1
Tim Peters11b23062003-04-23 02:39:17 +0000131#define HAVE_FSYNC 1
132#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 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000136#else /* all other compilers */
137/* Unix functions that the configure script doesn't check for */
138#define HAVE_EXECV 1
139#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000140#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
141#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
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#define HAVE_SYSTEM 1
156#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +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>
Tim Petersee66d0c2002-07-15 16:10:55 +0000274#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000275#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000276#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 */
315#ifdef SIZEOF_PID_T
316#if SIZEOF_PID_T == SIZEOF_INT
317#define PARSE_PID "i"
318#define PyLong_FromPid PyInt_FromLong
319#define PyLong_AsPid PyInt_AsLong
320#elif SIZEOF_PID_T == SIZEOF_LONG
321#define PARSE_PID "l"
322#define PyLong_FromPid PyInt_FromLong
323#define PyLong_AsPid PyInt_AsLong
324#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
325#define PARSE_PID "L"
326#define PyLong_FromPid PyLong_FromLongLong
327#define PyLong_AsPid PyInt_AsLongLong
328#else
329#error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)"
330#endif
331#endif /* SIZEOF_PID_T */
332
Greg Wardb48bc172000-03-01 21:51:56 +0000333/* Don't use the "_r" form if we don't need it (also, won't have a
334 prototype for it, at least on Solaris -- maybe others as well?). */
335#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
336#define USE_CTERMID_R
337#endif
338
339#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
340#define USE_TMPNAM_R
341#endif
342
Fred Drake699f3522000-06-29 21:12:41 +0000343/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000344#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000345#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000346# define STAT win32_stat
347# define FSTAT win32_fstat
348# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000349#else
350# define STAT stat
351# define FSTAT fstat
352# define STRUCT_STAT struct stat
353#endif
354
Tim Peters11b23062003-04-23 02:39:17 +0000355#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000356#include <sys/mkdev.h>
357#else
358#if defined(MAJOR_IN_SYSMACROS)
359#include <sys/sysmacros.h>
360#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000361#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
362#include <sys/mkdev.h>
363#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000364#endif
Fred Drake699f3522000-06-29 21:12:41 +0000365
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000366#if defined _MSC_VER && _MSC_VER >= 1400
367/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
368 * valid and throw an assertion if it isn't.
369 * Normally, an invalid fd is likely to be a C program error and therefore
370 * an assertion can be useful, but it does contradict the POSIX standard
371 * which for write(2) states:
372 * "Otherwise, -1 shall be returned and errno set to indicate the error."
373 * "[EBADF] The fildes argument is not a valid file descriptor open for
374 * writing."
375 * Furthermore, python allows the user to enter any old integer
376 * as a fd and should merely raise a python exception on error.
377 * The Microsoft CRT doesn't provide an official way to check for the
378 * validity of a file descriptor, but we can emulate its internal behaviour
379 * by using the exported __pinfo data member and knowledge of the
380 * internal structures involved.
381 * The structures below must be updated for each version of visual studio
382 * according to the file internal.h in the CRT source, until MS comes
383 * up with a less hacky way to do this.
384 * (all of this is to avoid globally modifying the CRT behaviour using
385 * _set_invalid_parameter_handler() and _CrtSetReportMode())
386 */
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000387/* The actual size of the structure is determined at runtime.
388 * Only the first items must be present.
389 */
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000390typedef struct {
391 intptr_t osfhnd;
392 char osfile;
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000393} my_ioinfo;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000394
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000395extern __declspec(dllimport) char * __pioinfo[];
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000396#define IOINFO_L2E 5
397#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
398#define IOINFO_ARRAYS 64
399#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
400#define FOPEN 0x01
401#define _NO_CONSOLE_FILENO (intptr_t)-2
402
403/* This function emulates what the windows CRT does to validate file handles */
404int
405_PyVerify_fd(int fd)
406{
407 const int i1 = fd >> IOINFO_L2E;
408 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000409
410 static int sizeof_ioinfo = 0;
411
412 /* Determine the actual size of the ioinfo structure,
413 * as used by the CRT loaded in memory
414 */
415 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
416 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
417 }
418 if (sizeof_ioinfo == 0) {
419 /* This should not happen... */
420 goto fail;
421 }
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000422
423 /* See that it isn't a special CLEAR fileno */
424 if (fd != _NO_CONSOLE_FILENO) {
425 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
426 * we check pointer validity and other info
427 */
428 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
429 /* finally, check that the file is open */
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000430 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
431 if (info->osfile & FOPEN) {
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000432 return 1;
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000433 }
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000434 }
435 }
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000436 fail:
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000437 errno = EBADF;
438 return 0;
439}
440
441/* the special case of checking dup2. The target fd must be in a sensible range */
442static int
443_PyVerify_fd_dup2(int fd1, int fd2)
444{
445 if (!_PyVerify_fd(fd1))
446 return 0;
447 if (fd2 == _NO_CONSOLE_FILENO)
448 return 0;
449 if ((unsigned)fd2 < _NHANDLE_)
450 return 1;
451 else
452 return 0;
453}
454#else
455/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
456#define _PyVerify_fd_dup2(A, B) (1)
457#endif
458
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000459/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000460#ifdef WITH_NEXT_FRAMEWORK
461/* On Darwin/MacOSX a shared library or framework has no access to
462** environ directly, we must obtain it with _NSGetEnviron().
463*/
464#include <crt_externs.h>
465static char **environ;
466#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000467extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000468#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000469
Barry Warsaw53699e91996-12-10 23:23:01 +0000470static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000471convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000472{
Barry Warsaw53699e91996-12-10 23:23:01 +0000473 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000474 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000475 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000476 if (d == NULL)
477 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000478#ifdef WITH_NEXT_FRAMEWORK
479 if (environ == NULL)
480 environ = *_NSGetEnviron();
481#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000482 if (environ == NULL)
483 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000484 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000485 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000486 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000487 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000488 char *p = strchr(*e, '=');
489 if (p == NULL)
490 continue;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000491 k = PyString_FromStringAndSize(*e, (int)(p-*e));
Guido van Rossum6a619f41999-08-03 19:41:10 +0000492 if (k == NULL) {
493 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000494 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000495 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000496 v = PyString_FromString(p+1);
Guido van Rossum6a619f41999-08-03 19:41:10 +0000497 if (v == NULL) {
498 PyErr_Clear();
499 Py_DECREF(k);
500 continue;
501 }
502 if (PyDict_GetItem(d, k) == NULL) {
503 if (PyDict_SetItem(d, k, v) != 0)
504 PyErr_Clear();
505 }
506 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000507 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000508 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000509#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000510 {
511 APIRET rc;
512 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
513
514 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000515 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000516 PyObject *v = PyString_FromString(buffer);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000517 PyDict_SetItemString(d, "BEGINLIBPATH", v);
518 Py_DECREF(v);
519 }
520 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
521 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000522 PyObject *v = PyString_FromString(buffer);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000523 PyDict_SetItemString(d, "ENDLIBPATH", v);
524 Py_DECREF(v);
525 }
526 }
527#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000528 return d;
529}
530
531
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000532/* Set a POSIX-specific error from errno, and return NULL */
533
Barry Warsawd58d7641998-07-23 16:14:40 +0000534static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000535posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000536{
Barry Warsawca74da41999-02-09 19:31:45 +0000537 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000538}
Barry Warsawd58d7641998-07-23 16:14:40 +0000539static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000540posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000541{
Barry Warsawca74da41999-02-09 19:31:45 +0000542 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000543}
544
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000545#ifdef MS_WINDOWS
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000546static PyObject *
547posix_error_with_unicode_filename(Py_UNICODE* name)
548{
549 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
550}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000551#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000552
553
Mark Hammondef8b6542001-05-13 08:04:26 +0000554static PyObject *
555posix_error_with_allocated_filename(char* name)
556{
557 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
558 PyMem_Free(name);
559 return rc;
560}
561
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000562#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000563static PyObject *
564win32_error(char* function, char* filename)
565{
Mark Hammond33a6da92000-08-15 00:46:38 +0000566 /* XXX We should pass the function name along in the future.
567 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000568 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000569 Windows error object, which is non-trivial.
570 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000571 errno = GetLastError();
572 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000573 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000574 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000575 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000576}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000577
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000578static PyObject *
579win32_error_unicode(char* function, Py_UNICODE* filename)
580{
581 /* XXX - see win32_error for comments on 'function' */
582 errno = GetLastError();
583 if (filename)
584 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
585 else
586 return PyErr_SetFromWindowsErr(errno);
587}
588
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000589static int
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000590convert_to_unicode(PyObject **param)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000591{
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000592 if (PyUnicode_CheckExact(*param))
593 Py_INCREF(*param);
594 else if (PyUnicode_Check(*param))
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000595 /* For a Unicode subtype that's not a Unicode object,
596 return a true Unicode object with the same data. */
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000597 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
598 PyUnicode_GET_SIZE(*param));
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000599 else
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000600 *param = PyUnicode_FromEncodedObject(*param,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000601 Py_FileSystemDefaultEncoding,
602 "strict");
603 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000604}
605
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000606#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000607
Guido van Rossumd48f2521997-12-05 22:19:34 +0000608#if defined(PYOS_OS2)
609/**********************************************************************
610 * Helper Function to Trim and Format OS/2 Messages
611 **********************************************************************/
612 static void
613os2_formatmsg(char *msgbuf, int msglen, char *reason)
614{
615 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
616
617 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
618 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
619
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000620 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000621 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
622 }
623
624 /* Add Optional Reason Text */
625 if (reason) {
626 strcat(msgbuf, " : ");
627 strcat(msgbuf, reason);
628 }
629}
630
631/**********************************************************************
632 * Decode an OS/2 Operating System Error Code
633 *
634 * A convenience function to lookup an OS/2 error code and return a
635 * text message we can use to raise a Python exception.
636 *
637 * Notes:
638 * The messages for errors returned from the OS/2 kernel reside in
639 * the file OSO001.MSG in the \OS2 directory hierarchy.
640 *
641 **********************************************************************/
642 static char *
643os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
644{
645 APIRET rc;
646 ULONG msglen;
647
648 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
649 Py_BEGIN_ALLOW_THREADS
650 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
651 errorcode, "oso001.msg", &msglen);
652 Py_END_ALLOW_THREADS
653
654 if (rc == NO_ERROR)
655 os2_formatmsg(msgbuf, msglen, reason);
656 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000657 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000658 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000659
660 return msgbuf;
661}
662
663/* Set an OS/2-specific error and return NULL. OS/2 kernel
664 errors are not in a global variable e.g. 'errno' nor are
665 they congruent with posix error numbers. */
666
667static PyObject * os2_error(int code)
668{
669 char text[1024];
670 PyObject *v;
671
672 os2_strerror(text, sizeof(text), code, "");
673
674 v = Py_BuildValue("(is)", code, text);
675 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000676 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000677 Py_DECREF(v);
678 }
679 return NULL; /* Signal to Python that an Exception is Pending */
680}
681
682#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000683
684/* POSIX generic methods */
685
Barry Warsaw53699e91996-12-10 23:23:01 +0000686static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000687posix_fildes(PyObject *fdobj, int (*func)(int))
688{
689 int fd;
690 int res;
691 fd = PyObject_AsFileDescriptor(fdobj);
692 if (fd < 0)
693 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000694 if (!_PyVerify_fd(fd))
695 return posix_error();
Fred Drake4d1e64b2002-04-15 19:40:07 +0000696 Py_BEGIN_ALLOW_THREADS
697 res = (*func)(fd);
698 Py_END_ALLOW_THREADS
699 if (res < 0)
700 return posix_error();
701 Py_INCREF(Py_None);
702 return Py_None;
703}
Guido van Rossum21142a01999-01-08 21:05:37 +0000704
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000705#ifdef MS_WINDOWS
Tim Peters11b23062003-04-23 02:39:17 +0000706static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000707unicode_file_names(void)
708{
709 static int canusewide = -1;
710 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000711 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000712 the Windows NT family. */
713 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
714 }
715 return canusewide;
716}
717#endif
Tim Peters11b23062003-04-23 02:39:17 +0000718
Guido van Rossum21142a01999-01-08 21:05:37 +0000719static PyObject *
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000720posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000721{
Mark Hammondef8b6542001-05-13 08:04:26 +0000722 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000723 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000724 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000725 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000726 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000727 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000728 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000729 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000730 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000731 return posix_error_with_allocated_filename(path1);
732 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000733 Py_INCREF(Py_None);
734 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000735}
736
Barry Warsaw53699e91996-12-10 23:23:01 +0000737static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000738posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000739 char *format,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000740 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000741{
Mark Hammondef8b6542001-05-13 08:04:26 +0000742 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000743 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000744 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000745 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000746 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000747 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000748 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000749 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000750 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000751 PyMem_Free(path1);
752 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000753 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000754 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000755 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000756 Py_INCREF(Py_None);
757 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000758}
759
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000760#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000761static PyObject*
762win32_1str(PyObject* args, char* func,
763 char* format, BOOL (__stdcall *funcA)(LPCSTR),
764 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
765{
766 PyObject *uni;
767 char *ansi;
768 BOOL result;
769 if (unicode_file_names()) {
770 if (!PyArg_ParseTuple(args, wformat, &uni))
771 PyErr_Clear();
772 else {
773 Py_BEGIN_ALLOW_THREADS
774 result = funcW(PyUnicode_AsUnicode(uni));
775 Py_END_ALLOW_THREADS
776 if (!result)
777 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
778 Py_INCREF(Py_None);
779 return Py_None;
780 }
781 }
782 if (!PyArg_ParseTuple(args, format, &ansi))
783 return NULL;
784 Py_BEGIN_ALLOW_THREADS
785 result = funcA(ansi);
786 Py_END_ALLOW_THREADS
787 if (!result)
788 return win32_error(func, ansi);
789 Py_INCREF(Py_None);
790 return Py_None;
791
792}
793
794/* This is a reimplementation of the C library's chdir function,
795 but one that produces Win32 errors instead of DOS error codes.
796 chdir is essentially a wrapper around SetCurrentDirectory; however,
797 it also needs to set "magic" environment variables indicating
798 the per-drive current directory, which are of the form =<drive>: */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000799static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000800win32_chdir(LPCSTR path)
801{
802 char new_path[MAX_PATH+1];
803 int result;
804 char env[4] = "=x:";
805
806 if(!SetCurrentDirectoryA(path))
807 return FALSE;
808 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
809 if (!result)
810 return FALSE;
811 /* In the ANSI API, there should not be any paths longer
812 than MAX_PATH. */
813 assert(result <= MAX_PATH+1);
814 if (strncmp(new_path, "\\\\", 2) == 0 ||
815 strncmp(new_path, "//", 2) == 0)
816 /* UNC path, nothing to do. */
817 return TRUE;
818 env[1] = new_path[0];
819 return SetEnvironmentVariableA(env, new_path);
820}
821
822/* The Unicode version differs from the ANSI version
823 since the current directory might exceed MAX_PATH characters */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000824static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000825win32_wchdir(LPCWSTR path)
826{
827 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
828 int result;
829 wchar_t env[4] = L"=x:";
830
831 if(!SetCurrentDirectoryW(path))
832 return FALSE;
833 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
834 if (!result)
835 return FALSE;
836 if (result > MAX_PATH+1) {
Hirokazu Yamamoto10a018c2008-10-09 10:00:30 +0000837 new_path = malloc(result * sizeof(wchar_t));
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000838 if (!new_path) {
839 SetLastError(ERROR_OUTOFMEMORY);
840 return FALSE;
841 }
Hirokazu Yamamoto10a018c2008-10-09 10:00:30 +0000842 result = GetCurrentDirectoryW(result, new_path);
Hirokazu Yamamoto6c75a302008-10-09 10:11:21 +0000843 if (!result) {
844 free(new_path);
Hirokazu Yamamoto10a018c2008-10-09 10:00:30 +0000845 return FALSE;
Hirokazu Yamamoto6c75a302008-10-09 10:11:21 +0000846 }
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000847 }
848 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
849 wcsncmp(new_path, L"//", 2) == 0)
850 /* UNC path, nothing to do. */
851 return TRUE;
852 env[1] = new_path[0];
853 result = SetEnvironmentVariableW(env, new_path);
854 if (new_path != _new_path)
855 free(new_path);
856 return result;
857}
858#endif
859
Martin v. Löwis14694662006-02-03 12:54:16 +0000860#ifdef MS_WINDOWS
861/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
862 - time stamps are restricted to second resolution
863 - file modification times suffer from forth-and-back conversions between
864 UTC and local time
865 Therefore, we implement our own stat, based on the Win32 API directly.
866*/
867#define HAVE_STAT_NSEC 1
868
869struct win32_stat{
870 int st_dev;
871 __int64 st_ino;
872 unsigned short st_mode;
873 int st_nlink;
874 int st_uid;
875 int st_gid;
876 int st_rdev;
877 __int64 st_size;
878 int st_atime;
879 int st_atime_nsec;
880 int st_mtime;
881 int st_mtime_nsec;
882 int st_ctime;
883 int st_ctime_nsec;
884};
885
886static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
887
888static void
889FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
890{
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000891 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
892 /* Cannot simply cast and dereference in_ptr,
893 since it might not be aligned properly */
894 __int64 in;
895 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000896 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
897 /* XXX Win32 supports time stamps past 2038; we currently don't */
898 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
899}
900
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000901static void
902time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
903{
904 /* XXX endianness */
905 __int64 out;
906 out = time_in + secs_between_epochs;
Martin v. Löwisf43893a2006-10-09 20:44:25 +0000907 out = out * 10000000 + nsec_in / 100;
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000908 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000909}
910
Martin v. Löwis14694662006-02-03 12:54:16 +0000911/* Below, we *know* that ugo+r is 0444 */
912#if _S_IREAD != 0400
913#error Unsupported C library
914#endif
915static int
916attributes_to_mode(DWORD attr)
917{
918 int m = 0;
919 if (attr & FILE_ATTRIBUTE_DIRECTORY)
920 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
921 else
922 m |= _S_IFREG;
923 if (attr & FILE_ATTRIBUTE_READONLY)
924 m |= 0444;
925 else
926 m |= 0666;
927 return m;
928}
929
930static int
931attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
932{
933 memset(result, 0, sizeof(*result));
934 result->st_mode = attributes_to_mode(info->dwFileAttributes);
935 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
936 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
937 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
938 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
939
940 return 0;
941}
942
Martin v. Löwis012bc722006-10-15 09:43:39 +0000943/* Emulate GetFileAttributesEx[AW] on Windows 95 */
944static int checked = 0;
945static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
946static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
947static void
948check_gfax()
949{
950 HINSTANCE hKernel32;
951 if (checked)
952 return;
953 checked = 1;
954 hKernel32 = GetModuleHandle("KERNEL32");
955 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
956 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
957}
958
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000959static BOOL
960attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
961{
962 HANDLE hFindFile;
963 WIN32_FIND_DATAA FileData;
964 hFindFile = FindFirstFileA(pszFile, &FileData);
965 if (hFindFile == INVALID_HANDLE_VALUE)
966 return FALSE;
967 FindClose(hFindFile);
968 pfad->dwFileAttributes = FileData.dwFileAttributes;
969 pfad->ftCreationTime = FileData.ftCreationTime;
970 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
971 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
972 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
973 pfad->nFileSizeLow = FileData.nFileSizeLow;
974 return TRUE;
975}
976
977static BOOL
978attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
979{
980 HANDLE hFindFile;
981 WIN32_FIND_DATAW FileData;
982 hFindFile = FindFirstFileW(pszFile, &FileData);
983 if (hFindFile == INVALID_HANDLE_VALUE)
984 return FALSE;
985 FindClose(hFindFile);
986 pfad->dwFileAttributes = FileData.dwFileAttributes;
987 pfad->ftCreationTime = FileData.ftCreationTime;
988 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
989 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
990 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
991 pfad->nFileSizeLow = FileData.nFileSizeLow;
992 return TRUE;
993}
994
Martin v. Löwis012bc722006-10-15 09:43:39 +0000995static BOOL WINAPI
996Py_GetFileAttributesExA(LPCSTR pszFile,
997 GET_FILEEX_INFO_LEVELS level,
998 LPVOID pv)
999{
1000 BOOL result;
Martin v. Löwis012bc722006-10-15 09:43:39 +00001001 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1002 /* First try to use the system's implementation, if that is
1003 available and either succeeds to gives an error other than
1004 that it isn't implemented. */
1005 check_gfax();
1006 if (gfaxa) {
1007 result = gfaxa(pszFile, level, pv);
1008 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1009 return result;
1010 }
1011 /* It's either not present, or not implemented.
1012 Emulate using FindFirstFile. */
1013 if (level != GetFileExInfoStandard) {
1014 SetLastError(ERROR_INVALID_PARAMETER);
1015 return FALSE;
1016 }
1017 /* Use GetFileAttributes to validate that the file name
1018 does not contain wildcards (which FindFirstFile would
1019 accept). */
1020 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
1021 return FALSE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001022 return attributes_from_dir(pszFile, pfad);
Martin v. Löwis012bc722006-10-15 09:43:39 +00001023}
1024
1025static BOOL WINAPI
1026Py_GetFileAttributesExW(LPCWSTR pszFile,
1027 GET_FILEEX_INFO_LEVELS level,
1028 LPVOID pv)
1029{
1030 BOOL result;
Martin v. Löwis012bc722006-10-15 09:43:39 +00001031 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1032 /* First try to use the system's implementation, if that is
1033 available and either succeeds to gives an error other than
1034 that it isn't implemented. */
1035 check_gfax();
1036 if (gfaxa) {
1037 result = gfaxw(pszFile, level, pv);
1038 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1039 return result;
1040 }
1041 /* It's either not present, or not implemented.
1042 Emulate using FindFirstFile. */
1043 if (level != GetFileExInfoStandard) {
1044 SetLastError(ERROR_INVALID_PARAMETER);
1045 return FALSE;
1046 }
1047 /* Use GetFileAttributes to validate that the file name
1048 does not contain wildcards (which FindFirstFile would
1049 accept). */
1050 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
1051 return FALSE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001052 return attributes_from_dir_w(pszFile, pfad);
Martin v. Löwis012bc722006-10-15 09:43:39 +00001053}
1054
Martin v. Löwis14694662006-02-03 12:54:16 +00001055static int
1056win32_stat(const char* path, struct win32_stat *result)
1057{
1058 WIN32_FILE_ATTRIBUTE_DATA info;
1059 int code;
1060 char *dot;
1061 /* XXX not supported on Win95 and NT 3.x */
Martin v. Löwis012bc722006-10-15 09:43:39 +00001062 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001063 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1064 /* Protocol violation: we explicitly clear errno, instead of
1065 setting it to a POSIX error. Callers should use GetLastError. */
1066 errno = 0;
1067 return -1;
1068 } else {
1069 /* Could not get attributes on open file. Fall back to
1070 reading the directory. */
1071 if (!attributes_from_dir(path, &info)) {
1072 /* Very strange. This should not fail now */
1073 errno = 0;
1074 return -1;
1075 }
1076 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001077 }
1078 code = attribute_data_to_stat(&info, result);
1079 if (code != 0)
1080 return code;
1081 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1082 dot = strrchr(path, '.');
1083 if (dot) {
1084 if (stricmp(dot, ".bat") == 0 ||
1085 stricmp(dot, ".cmd") == 0 ||
1086 stricmp(dot, ".exe") == 0 ||
1087 stricmp(dot, ".com") == 0)
1088 result->st_mode |= 0111;
1089 }
1090 return code;
1091}
1092
1093static int
1094win32_wstat(const wchar_t* path, struct win32_stat *result)
1095{
1096 int code;
1097 const wchar_t *dot;
1098 WIN32_FILE_ATTRIBUTE_DATA info;
1099 /* XXX not supported on Win95 and NT 3.x */
Martin v. Löwis012bc722006-10-15 09:43:39 +00001100 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001101 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1102 /* Protocol violation: we explicitly clear errno, instead of
1103 setting it to a POSIX error. Callers should use GetLastError. */
1104 errno = 0;
1105 return -1;
1106 } else {
1107 /* Could not get attributes on open file. Fall back to
1108 reading the directory. */
1109 if (!attributes_from_dir_w(path, &info)) {
1110 /* Very strange. This should not fail now */
1111 errno = 0;
1112 return -1;
1113 }
1114 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001115 }
1116 code = attribute_data_to_stat(&info, result);
1117 if (code < 0)
1118 return code;
1119 /* Set IFEXEC if it is an .exe, .bat, ... */
1120 dot = wcsrchr(path, '.');
1121 if (dot) {
1122 if (_wcsicmp(dot, L".bat") == 0 ||
1123 _wcsicmp(dot, L".cmd") == 0 ||
1124 _wcsicmp(dot, L".exe") == 0 ||
1125 _wcsicmp(dot, L".com") == 0)
1126 result->st_mode |= 0111;
1127 }
1128 return code;
1129}
1130
1131static int
1132win32_fstat(int file_number, struct win32_stat *result)
1133{
1134 BY_HANDLE_FILE_INFORMATION info;
1135 HANDLE h;
1136 int type;
1137
1138 h = (HANDLE)_get_osfhandle(file_number);
1139
1140 /* Protocol violation: we explicitly clear errno, instead of
1141 setting it to a POSIX error. Callers should use GetLastError. */
1142 errno = 0;
1143
1144 if (h == INVALID_HANDLE_VALUE) {
1145 /* This is really a C library error (invalid file handle).
1146 We set the Win32 error to the closes one matching. */
1147 SetLastError(ERROR_INVALID_HANDLE);
1148 return -1;
1149 }
1150 memset(result, 0, sizeof(*result));
1151
1152 type = GetFileType(h);
1153 if (type == FILE_TYPE_UNKNOWN) {
1154 DWORD error = GetLastError();
1155 if (error != 0) {
1156 return -1;
1157 }
1158 /* else: valid but unknown file */
1159 }
1160
1161 if (type != FILE_TYPE_DISK) {
1162 if (type == FILE_TYPE_CHAR)
1163 result->st_mode = _S_IFCHR;
1164 else if (type == FILE_TYPE_PIPE)
1165 result->st_mode = _S_IFIFO;
1166 return 0;
1167 }
1168
1169 if (!GetFileInformationByHandle(h, &info)) {
1170 return -1;
1171 }
1172
1173 /* similar to stat() */
1174 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1175 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1176 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1177 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1178 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1179 /* specific to fstat() */
1180 result->st_nlink = info.nNumberOfLinks;
1181 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1182 return 0;
1183}
1184
1185#endif /* MS_WINDOWS */
1186
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001187PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001188"stat_result: Result from stat or lstat.\n\n\
1189This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001190 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001191or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1192\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001193Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1194or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001195\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001196See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001197
1198static PyStructSequence_Field stat_result_fields[] = {
1199 {"st_mode", "protection bits"},
1200 {"st_ino", "inode"},
1201 {"st_dev", "device"},
1202 {"st_nlink", "number of hard links"},
1203 {"st_uid", "user ID of owner"},
1204 {"st_gid", "group ID of owner"},
1205 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001206 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1207 {NULL, "integer time of last access"},
1208 {NULL, "integer time of last modification"},
1209 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001210 {"st_atime", "time of last access"},
1211 {"st_mtime", "time of last modification"},
1212 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001213#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001214 {"st_blksize", "blocksize for filesystem I/O"},
1215#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001216#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001217 {"st_blocks", "number of blocks allocated"},
1218#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001219#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001220 {"st_rdev", "device type (if inode device)"},
1221#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001222#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1223 {"st_flags", "user defined flags for file"},
1224#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001225#ifdef HAVE_STRUCT_STAT_ST_GEN
1226 {"st_gen", "generation number"},
1227#endif
1228#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1229 {"st_birthtime", "time of creation"},
1230#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001231 {0}
1232};
1233
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001234#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001235#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001236#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001237#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001238#endif
1239
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001240#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001241#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1242#else
1243#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1244#endif
1245
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001246#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001247#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1248#else
1249#define ST_RDEV_IDX ST_BLOCKS_IDX
1250#endif
1251
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001252#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1253#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1254#else
1255#define ST_FLAGS_IDX ST_RDEV_IDX
1256#endif
1257
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001258#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001259#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001260#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001261#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001262#endif
1263
1264#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1265#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1266#else
1267#define ST_BIRTHTIME_IDX ST_GEN_IDX
1268#endif
1269
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001270static PyStructSequence_Desc stat_result_desc = {
1271 "stat_result", /* name */
1272 stat_result__doc__, /* doc */
1273 stat_result_fields,
1274 10
1275};
1276
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001277PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001278"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1279This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001280 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001281or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001282\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001283See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001284
1285static PyStructSequence_Field statvfs_result_fields[] = {
1286 {"f_bsize", },
1287 {"f_frsize", },
1288 {"f_blocks", },
1289 {"f_bfree", },
1290 {"f_bavail", },
1291 {"f_files", },
1292 {"f_ffree", },
1293 {"f_favail", },
1294 {"f_flag", },
1295 {"f_namemax",},
1296 {0}
1297};
1298
1299static PyStructSequence_Desc statvfs_result_desc = {
1300 "statvfs_result", /* name */
1301 statvfs_result__doc__, /* doc */
1302 statvfs_result_fields,
1303 10
1304};
1305
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001306static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001307static PyTypeObject StatResultType;
1308static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001309static newfunc structseq_new;
1310
1311static PyObject *
1312statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1313{
1314 PyStructSequence *result;
1315 int i;
1316
1317 result = (PyStructSequence*)structseq_new(type, args, kwds);
1318 if (!result)
1319 return NULL;
1320 /* If we have been initialized from a tuple,
1321 st_?time might be set to None. Initialize it
1322 from the int slots. */
1323 for (i = 7; i <= 9; i++) {
1324 if (result->ob_item[i+3] == Py_None) {
1325 Py_DECREF(Py_None);
1326 Py_INCREF(result->ob_item[i]);
1327 result->ob_item[i+3] = result->ob_item[i];
1328 }
1329 }
1330 return (PyObject*)result;
1331}
1332
1333
1334
1335/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001336static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001337
1338PyDoc_STRVAR(stat_float_times__doc__,
1339"stat_float_times([newval]) -> oldval\n\n\
1340Determine whether os.[lf]stat represents time stamps as float objects.\n\
1341If newval is True, future calls to stat() return floats, if it is False,\n\
1342future calls return ints. \n\
1343If newval is omitted, return the current setting.\n");
1344
1345static PyObject*
1346stat_float_times(PyObject* self, PyObject *args)
1347{
1348 int newval = -1;
1349 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1350 return NULL;
1351 if (newval == -1)
1352 /* Return old value */
1353 return PyBool_FromLong(_stat_float_times);
1354 _stat_float_times = newval;
1355 Py_INCREF(Py_None);
1356 return Py_None;
1357}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001358
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001359static void
1360fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1361{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001362 PyObject *fval,*ival;
1363#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001364 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001365#else
1366 ival = PyInt_FromLong((long)sec);
1367#endif
Neal Norwitze0a81af2006-08-12 01:50:38 +00001368 if (!ival)
1369 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001370 if (_stat_float_times) {
1371 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1372 } else {
1373 fval = ival;
1374 Py_INCREF(fval);
1375 }
1376 PyStructSequence_SET_ITEM(v, index, ival);
1377 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001378}
1379
Tim Peters5aa91602002-01-30 05:46:57 +00001380/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001381 (used by posix_stat() and posix_fstat()) */
1382static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001383_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001384{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001385 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001386 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001387 if (v == NULL)
1388 return NULL;
1389
Martin v. Löwis14694662006-02-03 12:54:16 +00001390 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001391#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001392 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001393 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001394#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001395 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001396#endif
1397#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001398 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001399 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001400#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001401 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001402#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001403 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1404 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1405 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001406#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001407 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001408 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001409#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001410 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001411#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001412
Martin v. Löwis14694662006-02-03 12:54:16 +00001413#if defined(HAVE_STAT_TV_NSEC)
1414 ansec = st->st_atim.tv_nsec;
1415 mnsec = st->st_mtim.tv_nsec;
1416 cnsec = st->st_ctim.tv_nsec;
1417#elif defined(HAVE_STAT_TV_NSEC2)
1418 ansec = st->st_atimespec.tv_nsec;
1419 mnsec = st->st_mtimespec.tv_nsec;
1420 cnsec = st->st_ctimespec.tv_nsec;
1421#elif defined(HAVE_STAT_NSEC)
1422 ansec = st->st_atime_nsec;
1423 mnsec = st->st_mtime_nsec;
1424 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001425#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001426 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001427#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001428 fill_time(v, 7, st->st_atime, ansec);
1429 fill_time(v, 8, st->st_mtime, mnsec);
1430 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001431
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001432#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001433 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001434 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001435#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001436#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001437 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001438 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001439#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001440#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001441 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001442 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001443#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001444#ifdef HAVE_STRUCT_STAT_ST_GEN
1445 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001446 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001447#endif
1448#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1449 {
1450 PyObject *val;
1451 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001452 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001453#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001454 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001455#else
1456 bnsec = 0;
1457#endif
1458 if (_stat_float_times) {
1459 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1460 } else {
1461 val = PyInt_FromLong((long)bsec);
1462 }
1463 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1464 val);
1465 }
1466#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001467#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1468 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001469 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001470#endif
Fred Drake699f3522000-06-29 21:12:41 +00001471
1472 if (PyErr_Occurred()) {
1473 Py_DECREF(v);
1474 return NULL;
1475 }
1476
1477 return v;
1478}
1479
Martin v. Löwisd8948722004-06-02 09:57:56 +00001480#ifdef MS_WINDOWS
1481
1482/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1483 where / can be used in place of \ and the trailing slash is optional.
1484 Both SERVER and SHARE must have at least one character.
1485*/
1486
1487#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1488#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001489#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001490#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001491#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001492
Tim Peters4ad82172004-08-30 17:02:04 +00001493static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001494IsUNCRootA(char *path, int pathlen)
1495{
1496 #define ISSLASH ISSLASHA
1497
1498 int i, share;
1499
1500 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1501 /* minimum UNCRoot is \\x\y */
1502 return FALSE;
1503 for (i = 2; i < pathlen ; i++)
1504 if (ISSLASH(path[i])) break;
1505 if (i == 2 || i == pathlen)
1506 /* do not allow \\\SHARE or \\SERVER */
1507 return FALSE;
1508 share = i+1;
1509 for (i = share; i < pathlen; i++)
1510 if (ISSLASH(path[i])) break;
1511 return (i != share && (i == pathlen || i == pathlen-1));
1512
1513 #undef ISSLASH
1514}
1515
Tim Peters4ad82172004-08-30 17:02:04 +00001516static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001517IsUNCRootW(Py_UNICODE *path, int pathlen)
1518{
1519 #define ISSLASH ISSLASHW
1520
1521 int i, share;
1522
1523 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1524 /* minimum UNCRoot is \\x\y */
1525 return FALSE;
1526 for (i = 2; i < pathlen ; i++)
1527 if (ISSLASH(path[i])) break;
1528 if (i == 2 || i == pathlen)
1529 /* do not allow \\\SHARE or \\SERVER */
1530 return FALSE;
1531 share = i+1;
1532 for (i = share; i < pathlen; i++)
1533 if (ISSLASH(path[i])) break;
1534 return (i != share && (i == pathlen || i == pathlen-1));
1535
1536 #undef ISSLASH
1537}
Martin v. Löwisd8948722004-06-02 09:57:56 +00001538#endif /* MS_WINDOWS */
1539
Barry Warsaw53699e91996-12-10 23:23:01 +00001540static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001541posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001542 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001543#ifdef __VMS
1544 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1545#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001546 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001547#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001548 char *wformat,
1549 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001550{
Fred Drake699f3522000-06-29 21:12:41 +00001551 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001552 char *path = NULL; /* pass this to stat; do not free() it */
1553 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001554 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001555 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001556
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001557#ifdef MS_WINDOWS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001558 /* If on wide-character-capable OS see if argument
1559 is Unicode and if so use wide API. */
1560 if (unicode_file_names()) {
1561 PyUnicodeObject *po;
1562 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001563 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1564
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001565 Py_BEGIN_ALLOW_THREADS
1566 /* PyUnicode_AS_UNICODE result OK without
1567 thread lock as it is a simple dereference. */
1568 res = wstatfunc(wpath, &st);
1569 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001570
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001571 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001572 return win32_error_unicode("stat", wpath);
1573 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001574 }
1575 /* Drop the argument parsing error as narrow strings
1576 are also valid. */
1577 PyErr_Clear();
1578 }
1579#endif
1580
Tim Peters5aa91602002-01-30 05:46:57 +00001581 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001582 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001583 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001584 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001585
Barry Warsaw53699e91996-12-10 23:23:01 +00001586 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001587 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001588 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001589
1590 if (res != 0) {
1591#ifdef MS_WINDOWS
1592 result = win32_error("stat", pathfree);
1593#else
1594 result = posix_error_with_filename(pathfree);
1595#endif
1596 }
1597 else
1598 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001599
Tim Peters500bd032001-12-19 19:05:01 +00001600 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001601 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001602}
1603
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001604/* POSIX methods */
1605
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001606PyDoc_STRVAR(posix_access__doc__,
Georg Brandl7a284472007-01-27 19:38:50 +00001607"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001608Use the real uid/gid to test for access to a path. Note that most\n\
1609operations will use the effective uid/gid, therefore this routine can\n\
1610be used in a suid/sgid environment to test if the invoking user has the\n\
1611specified access to the path. The mode argument can be F_OK to test\n\
1612existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001613
1614static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001615posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001616{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001617 char *path;
1618 int mode;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001619
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001620#ifdef MS_WINDOWS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001621 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001622 if (unicode_file_names()) {
1623 PyUnicodeObject *po;
1624 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1625 Py_BEGIN_ALLOW_THREADS
1626 /* PyUnicode_AS_UNICODE OK without thread lock as
1627 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001628 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001629 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001630 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001631 }
1632 /* Drop the argument parsing error as narrow strings
1633 are also valid. */
1634 PyErr_Clear();
1635 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001636 if (!PyArg_ParseTuple(args, "eti:access",
1637 Py_FileSystemDefaultEncoding, &path, &mode))
1638 return 0;
1639 Py_BEGIN_ALLOW_THREADS
1640 attr = GetFileAttributesA(path);
1641 Py_END_ALLOW_THREADS
1642 PyMem_Free(path);
1643finish:
1644 if (attr == 0xFFFFFFFF)
1645 /* File does not exist, or cannot read attributes */
1646 return PyBool_FromLong(0);
1647 /* Access is possible if either write access wasn't requested, or
Martin v. Löwis7b3cc062007-12-03 23:09:04 +00001648 the file isn't read-only, or if it's a directory, as there are
1649 no read-only directories on Windows. */
1650 return PyBool_FromLong(!(mode & 2)
1651 || !(attr & FILE_ATTRIBUTE_READONLY)
1652 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001653#else /* MS_WINDOWS */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001654 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001655 if (!PyArg_ParseTuple(args, "eti:access",
1656 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001657 return NULL;
1658 Py_BEGIN_ALLOW_THREADS
1659 res = access(path, mode);
1660 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001661 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001662 return PyBool_FromLong(res == 0);
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001663#endif /* MS_WINDOWS */
Guido van Rossum94f6f721999-01-06 18:42:14 +00001664}
1665
Guido van Rossumd371ff11999-01-25 16:12:23 +00001666#ifndef F_OK
1667#define F_OK 0
1668#endif
1669#ifndef R_OK
1670#define R_OK 4
1671#endif
1672#ifndef W_OK
1673#define W_OK 2
1674#endif
1675#ifndef X_OK
1676#define X_OK 1
1677#endif
1678
1679#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001680PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001681"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001682Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001683
1684static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001685posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001686{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001687 int id;
1688 char *ret;
1689
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001690 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001691 return NULL;
1692
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001693#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001694 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001695 if (id == 0) {
1696 ret = ttyname();
1697 }
1698 else {
1699 ret = NULL;
1700 }
1701#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001702 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001703#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001704 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001705 return posix_error();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001706 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001707}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001708#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001709
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001710#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001711PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001712"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001713Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001714
1715static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001716posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001717{
1718 char *ret;
1719 char buffer[L_ctermid];
1720
Greg Wardb48bc172000-03-01 21:51:56 +00001721#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001722 ret = ctermid_r(buffer);
1723#else
1724 ret = ctermid(buffer);
1725#endif
1726 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001727 return posix_error();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001728 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001729}
1730#endif
1731
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001732PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001733"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001734Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001735
Barry Warsaw53699e91996-12-10 23:23:01 +00001736static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001737posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001738{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001739#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001740 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001741#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001742 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001743#elif defined(__VMS)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001744 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001745#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001746 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001747#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001748}
1749
Fred Drake4d1e64b2002-04-15 19:40:07 +00001750#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001751PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001752"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001753Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001754opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001755
1756static PyObject *
1757posix_fchdir(PyObject *self, PyObject *fdobj)
1758{
1759 return posix_fildes(fdobj, fchdir);
1760}
1761#endif /* HAVE_FCHDIR */
1762
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001763
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001764PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001765"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001766Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001767
Barry Warsaw53699e91996-12-10 23:23:01 +00001768static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001769posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001770{
Mark Hammondef8b6542001-05-13 08:04:26 +00001771 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001772 int i;
1773 int res;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001774#ifdef MS_WINDOWS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001775 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001776 if (unicode_file_names()) {
1777 PyUnicodeObject *po;
1778 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1779 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001780 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1781 if (attr != 0xFFFFFFFF) {
1782 if (i & _S_IWRITE)
1783 attr &= ~FILE_ATTRIBUTE_READONLY;
1784 else
1785 attr |= FILE_ATTRIBUTE_READONLY;
1786 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1787 }
1788 else
1789 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001790 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001791 if (!res)
1792 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001793 PyUnicode_AS_UNICODE(po));
1794 Py_INCREF(Py_None);
1795 return Py_None;
1796 }
1797 /* Drop the argument parsing error as narrow strings
1798 are also valid. */
1799 PyErr_Clear();
1800 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001801 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1802 &path, &i))
1803 return NULL;
1804 Py_BEGIN_ALLOW_THREADS
1805 attr = GetFileAttributesA(path);
1806 if (attr != 0xFFFFFFFF) {
1807 if (i & _S_IWRITE)
1808 attr &= ~FILE_ATTRIBUTE_READONLY;
1809 else
1810 attr |= FILE_ATTRIBUTE_READONLY;
1811 res = SetFileAttributesA(path, attr);
1812 }
1813 else
1814 res = 0;
1815 Py_END_ALLOW_THREADS
1816 if (!res) {
1817 win32_error("chmod", path);
1818 PyMem_Free(path);
1819 return NULL;
1820 }
Martin v. Löwis9f485bc2006-05-08 05:25:56 +00001821 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001822 Py_INCREF(Py_None);
1823 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001824#else /* MS_WINDOWS */
Mark Hammond817c9292003-12-03 01:22:38 +00001825 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001826 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001827 return NULL;
1828 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001829 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001830 Py_END_ALLOW_THREADS
1831 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001832 return posix_error_with_allocated_filename(path);
1833 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001834 Py_INCREF(Py_None);
1835 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001836#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001837}
1838
Christian Heimes36281872007-11-30 21:11:28 +00001839#ifdef HAVE_FCHMOD
1840PyDoc_STRVAR(posix_fchmod__doc__,
1841"fchmod(fd, mode)\n\n\
1842Change the access permissions of the file given by file\n\
1843descriptor fd.");
1844
1845static PyObject *
1846posix_fchmod(PyObject *self, PyObject *args)
1847{
1848 int fd, mode, res;
1849 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1850 return NULL;
1851 Py_BEGIN_ALLOW_THREADS
1852 res = fchmod(fd, mode);
1853 Py_END_ALLOW_THREADS
1854 if (res < 0)
1855 return posix_error();
1856 Py_RETURN_NONE;
1857}
1858#endif /* HAVE_FCHMOD */
1859
1860#ifdef HAVE_LCHMOD
1861PyDoc_STRVAR(posix_lchmod__doc__,
1862"lchmod(path, mode)\n\n\
1863Change the access permissions of a file. If path is a symlink, this\n\
1864affects the link itself rather than the target.");
1865
1866static PyObject *
1867posix_lchmod(PyObject *self, PyObject *args)
1868{
1869 char *path = NULL;
1870 int i;
1871 int res;
1872 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1873 &path, &i))
1874 return NULL;
1875 Py_BEGIN_ALLOW_THREADS
1876 res = lchmod(path, i);
1877 Py_END_ALLOW_THREADS
1878 if (res < 0)
1879 return posix_error_with_allocated_filename(path);
1880 PyMem_Free(path);
1881 Py_RETURN_NONE;
1882}
1883#endif /* HAVE_LCHMOD */
1884
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001885
Martin v. Löwis382abef2007-02-19 10:55:19 +00001886#ifdef HAVE_CHFLAGS
1887PyDoc_STRVAR(posix_chflags__doc__,
1888"chflags(path, flags)\n\n\
1889Set file flags.");
1890
1891static PyObject *
1892posix_chflags(PyObject *self, PyObject *args)
1893{
1894 char *path;
1895 unsigned long flags;
1896 int res;
1897 if (!PyArg_ParseTuple(args, "etk:chflags",
1898 Py_FileSystemDefaultEncoding, &path, &flags))
1899 return NULL;
1900 Py_BEGIN_ALLOW_THREADS
1901 res = chflags(path, flags);
1902 Py_END_ALLOW_THREADS
1903 if (res < 0)
1904 return posix_error_with_allocated_filename(path);
1905 PyMem_Free(path);
1906 Py_INCREF(Py_None);
1907 return Py_None;
1908}
1909#endif /* HAVE_CHFLAGS */
1910
1911#ifdef HAVE_LCHFLAGS
1912PyDoc_STRVAR(posix_lchflags__doc__,
1913"lchflags(path, flags)\n\n\
1914Set file flags.\n\
1915This function will not follow symbolic links.");
1916
1917static PyObject *
1918posix_lchflags(PyObject *self, PyObject *args)
1919{
1920 char *path;
1921 unsigned long flags;
1922 int res;
1923 if (!PyArg_ParseTuple(args, "etk:lchflags",
1924 Py_FileSystemDefaultEncoding, &path, &flags))
1925 return NULL;
1926 Py_BEGIN_ALLOW_THREADS
1927 res = lchflags(path, flags);
1928 Py_END_ALLOW_THREADS
1929 if (res < 0)
1930 return posix_error_with_allocated_filename(path);
1931 PyMem_Free(path);
1932 Py_INCREF(Py_None);
1933 return Py_None;
1934}
1935#endif /* HAVE_LCHFLAGS */
1936
Martin v. Löwis244edc82001-10-04 22:44:26 +00001937#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001938PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001939"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001940Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001941
1942static PyObject *
1943posix_chroot(PyObject *self, PyObject *args)
1944{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001945 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001946}
1947#endif
1948
Guido van Rossum21142a01999-01-08 21:05:37 +00001949#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001950PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001951"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001952force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001953
1954static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001955posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001956{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001957 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001958}
1959#endif /* HAVE_FSYNC */
1960
1961#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001962
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001963#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001964extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1965#endif
1966
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001967PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001968"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001969force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001970 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001971
1972static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001973posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001974{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001975 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001976}
1977#endif /* HAVE_FDATASYNC */
1978
1979
Fredrik Lundh10723342000-07-10 16:38:09 +00001980#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001981PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001982"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001983Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001984
Barry Warsaw53699e91996-12-10 23:23:01 +00001985static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001986posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001987{
Mark Hammondef8b6542001-05-13 08:04:26 +00001988 char *path = NULL;
Gregory P. Smithf48da8f2008-03-18 19:05:32 +00001989 long uid, gid;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001990 int res;
Gregory P. Smithf48da8f2008-03-18 19:05:32 +00001991 if (!PyArg_ParseTuple(args, "etll:chown",
Tim Peters5aa91602002-01-30 05:46:57 +00001992 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001993 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001994 return NULL;
1995 Py_BEGIN_ALLOW_THREADS
1996 res = chown(path, (uid_t) uid, (gid_t) gid);
1997 Py_END_ALLOW_THREADS
1998 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001999 return posix_error_with_allocated_filename(path);
2000 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00002001 Py_INCREF(Py_None);
2002 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002003}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002004#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002005
Christian Heimes36281872007-11-30 21:11:28 +00002006#ifdef HAVE_FCHOWN
2007PyDoc_STRVAR(posix_fchown__doc__,
2008"fchown(fd, uid, gid)\n\n\
2009Change the owner and group id of the file given by file descriptor\n\
2010fd to the numeric uid and gid.");
2011
2012static PyObject *
2013posix_fchown(PyObject *self, PyObject *args)
2014{
2015 int fd, uid, gid;
2016 int res;
2017 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
2018 return NULL;
2019 Py_BEGIN_ALLOW_THREADS
2020 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2021 Py_END_ALLOW_THREADS
2022 if (res < 0)
2023 return posix_error();
2024 Py_RETURN_NONE;
2025}
2026#endif /* HAVE_FCHOWN */
2027
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002028#ifdef HAVE_LCHOWN
2029PyDoc_STRVAR(posix_lchown__doc__,
2030"lchown(path, uid, gid)\n\n\
2031Change the owner and group id of path to the numeric uid and gid.\n\
2032This function will not follow symbolic links.");
2033
2034static PyObject *
2035posix_lchown(PyObject *self, PyObject *args)
2036{
2037 char *path = NULL;
2038 int uid, gid;
2039 int res;
2040 if (!PyArg_ParseTuple(args, "etii:lchown",
2041 Py_FileSystemDefaultEncoding, &path,
2042 &uid, &gid))
2043 return NULL;
2044 Py_BEGIN_ALLOW_THREADS
2045 res = lchown(path, (uid_t) uid, (gid_t) gid);
2046 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00002047 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002048 return posix_error_with_allocated_filename(path);
2049 PyMem_Free(path);
2050 Py_INCREF(Py_None);
2051 return Py_None;
2052}
2053#endif /* HAVE_LCHOWN */
2054
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002055
Guido van Rossum36bc6801995-06-14 22:54:23 +00002056#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002057PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002058"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002059Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002060
Barry Warsaw53699e91996-12-10 23:23:01 +00002061static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002062posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002063{
Facundo Batista5596b0c2008-06-22 13:36:20 +00002064 int bufsize_incr = 1024;
2065 int bufsize = 0;
2066 char *tmpbuf = NULL;
2067 char *res = NULL;
2068 PyObject *dynamic_return;
Neal Norwitze241ce82003-02-17 18:17:05 +00002069
Barry Warsaw53699e91996-12-10 23:23:01 +00002070 Py_BEGIN_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00002071 do {
2072 bufsize = bufsize + bufsize_incr;
2073 tmpbuf = malloc(bufsize);
2074 if (tmpbuf == NULL) {
2075 break;
2076 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002077#if defined(PYOS_OS2) && defined(PYCC_GCC)
Facundo Batista5596b0c2008-06-22 13:36:20 +00002078 res = _getcwd2(tmpbuf, bufsize);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002079#else
Facundo Batista5596b0c2008-06-22 13:36:20 +00002080 res = getcwd(tmpbuf, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002081#endif
Facundo Batista5596b0c2008-06-22 13:36:20 +00002082
2083 if (res == NULL) {
2084 free(tmpbuf);
2085 }
2086 } while ((res == NULL) && (errno == ERANGE));
Barry Warsaw53699e91996-12-10 23:23:01 +00002087 Py_END_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00002088
Guido van Rossumff4949e1992-08-05 19:58:53 +00002089 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002090 return posix_error();
Facundo Batista5596b0c2008-06-22 13:36:20 +00002091
2092 dynamic_return = PyString_FromString(tmpbuf);
2093 free(tmpbuf);
2094
2095 return dynamic_return;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002096}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002097
Walter Dörwald3b918c32002-11-21 20:18:46 +00002098#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002099PyDoc_STRVAR(posix_getcwdu__doc__,
2100"getcwdu() -> path\n\n\
2101Return a unicode string representing the current working directory.");
2102
2103static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002104posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002105{
2106 char buf[1026];
2107 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002108
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002109#ifdef MS_WINDOWS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002110 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002111 if (unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002112 wchar_t wbuf[1026];
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002113 wchar_t *wbuf2 = wbuf;
2114 PyObject *resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002115 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002116 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2117 /* If the buffer is large enough, len does not include the
2118 terminating \0. If the buffer is too small, len includes
2119 the space needed for the terminator. */
2120 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2121 wbuf2 = malloc(len * sizeof(wchar_t));
2122 if (wbuf2)
2123 len = GetCurrentDirectoryW(len, wbuf2);
2124 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002125 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002126 if (!wbuf2) {
2127 PyErr_NoMemory();
2128 return NULL;
2129 }
2130 if (!len) {
2131 if (wbuf2 != wbuf) free(wbuf2);
2132 return win32_error("getcwdu", NULL);
2133 }
2134 resobj = PyUnicode_FromWideChar(wbuf2, len);
2135 if (wbuf2 != wbuf) free(wbuf2);
2136 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002137 }
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002138#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002139
2140 Py_BEGIN_ALLOW_THREADS
2141#if defined(PYOS_OS2) && defined(PYCC_GCC)
2142 res = _getcwd2(buf, sizeof buf);
2143#else
2144 res = getcwd(buf, sizeof buf);
2145#endif
2146 Py_END_ALLOW_THREADS
2147 if (res == NULL)
2148 return posix_error();
2149 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
2150}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002151#endif /* Py_USING_UNICODE */
2152#endif /* HAVE_GETCWD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002153
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002154
Guido van Rossumb6775db1994-08-01 11:34:53 +00002155#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002156PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002157"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002158Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002159
Barry Warsaw53699e91996-12-10 23:23:01 +00002160static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002161posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002162{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002163 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002164}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002165#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002166
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002167
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002168PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002169"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002170Return a list containing the names of the entries in the directory.\n\
2171\n\
2172 path: path of directory to list\n\
2173\n\
2174The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002175entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002176
Barry Warsaw53699e91996-12-10 23:23:01 +00002177static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002178posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002179{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002180 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002181 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002182#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002183
Barry Warsaw53699e91996-12-10 23:23:01 +00002184 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002185 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002186 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002187 WIN32_FIND_DATA FileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002188 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00002189 char *bufptr = namebuf;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002190 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002191
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002192 /* If on wide-character-capable OS see if argument
2193 is Unicode and if so use wide API. */
2194 if (unicode_file_names()) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002195 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002196 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2197 WIN32_FIND_DATAW wFileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002198 Py_UNICODE *wnamebuf;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002199 /* Overallocate for \\*.*\0 */
2200 len = PyUnicode_GET_SIZE(po);
2201 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2202 if (!wnamebuf) {
2203 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002204 return NULL;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002205 }
2206 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
Hirokazu Yamamoto406d7aa2009-05-04 05:28:39 +00002207 if (len > 0) {
2208 Py_UNICODE wch = wnamebuf[len-1];
2209 if (wch != L'/' && wch != L'\\' && wch != L':')
2210 wnamebuf[len++] = L'\\';
2211 wcscpy(wnamebuf + len, L"*.*");
2212 }
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002213 if ((d = PyList_New(0)) == NULL) {
2214 free(wnamebuf);
2215 return NULL;
2216 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002217 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2218 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002219 int error = GetLastError();
2220 if (error == ERROR_FILE_NOT_FOUND) {
2221 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002222 return d;
2223 }
2224 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002225 win32_error_unicode("FindFirstFileW", wnamebuf);
2226 free(wnamebuf);
2227 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002228 }
2229 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002230 /* Skip over . and .. */
2231 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2232 wcscmp(wFileData.cFileName, L"..") != 0) {
2233 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2234 if (v == NULL) {
2235 Py_DECREF(d);
2236 d = NULL;
2237 break;
2238 }
2239 if (PyList_Append(d, v) != 0) {
2240 Py_DECREF(v);
2241 Py_DECREF(d);
2242 d = NULL;
2243 break;
2244 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002245 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002246 }
Georg Brandl622927b2006-03-07 12:48:03 +00002247 Py_BEGIN_ALLOW_THREADS
2248 result = FindNextFileW(hFindFile, &wFileData);
2249 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00002250 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2251 it got to the end of the directory. */
2252 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2253 Py_DECREF(d);
2254 win32_error_unicode("FindNextFileW", wnamebuf);
2255 FindClose(hFindFile);
2256 free(wnamebuf);
2257 return NULL;
2258 }
Georg Brandl622927b2006-03-07 12:48:03 +00002259 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002260
2261 if (FindClose(hFindFile) == FALSE) {
2262 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002263 win32_error_unicode("FindClose", wnamebuf);
2264 free(wnamebuf);
2265 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002266 }
Martin v. Löwise3edaea2006-05-15 05:51:36 +00002267 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002268 return d;
2269 }
2270 /* Drop the argument parsing error as narrow strings
2271 are also valid. */
2272 PyErr_Clear();
2273 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002274
Tim Peters5aa91602002-01-30 05:46:57 +00002275 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002276 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002277 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002278 if (len > 0) {
2279 char ch = namebuf[len-1];
2280 if (ch != SEP && ch != ALTSEP && ch != ':')
2281 namebuf[len++] = '/';
Hirokazu Yamamoto406d7aa2009-05-04 05:28:39 +00002282 strcpy(namebuf + len, "*.*");
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002283 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002284
Barry Warsaw53699e91996-12-10 23:23:01 +00002285 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002286 return NULL;
2287
2288 hFindFile = FindFirstFile(namebuf, &FileData);
2289 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002290 int error = GetLastError();
2291 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002292 return d;
2293 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002294 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002295 }
2296 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002297 /* Skip over . and .. */
2298 if (strcmp(FileData.cFileName, ".") != 0 &&
2299 strcmp(FileData.cFileName, "..") != 0) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002300 v = PyString_FromString(FileData.cFileName);
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002301 if (v == NULL) {
2302 Py_DECREF(d);
2303 d = NULL;
2304 break;
2305 }
2306 if (PyList_Append(d, v) != 0) {
2307 Py_DECREF(v);
2308 Py_DECREF(d);
2309 d = NULL;
2310 break;
2311 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002312 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002313 }
Georg Brandl622927b2006-03-07 12:48:03 +00002314 Py_BEGIN_ALLOW_THREADS
2315 result = FindNextFile(hFindFile, &FileData);
2316 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00002317 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2318 it got to the end of the directory. */
2319 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2320 Py_DECREF(d);
2321 win32_error("FindNextFile", namebuf);
2322 FindClose(hFindFile);
2323 return NULL;
2324 }
Georg Brandl622927b2006-03-07 12:48:03 +00002325 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002326
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002327 if (FindClose(hFindFile) == FALSE) {
2328 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002329 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002330 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002331
2332 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002333
Tim Peters0bb44a42000-09-15 07:44:49 +00002334#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002335
2336#ifndef MAX_PATH
2337#define MAX_PATH CCHMAXPATH
2338#endif
2339 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002340 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002341 PyObject *d, *v;
2342 char namebuf[MAX_PATH+5];
2343 HDIR hdir = 1;
2344 ULONG srchcnt = 1;
2345 FILEFINDBUF3 ep;
2346 APIRET rc;
2347
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002348 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002349 return NULL;
2350 if (len >= MAX_PATH) {
2351 PyErr_SetString(PyExc_ValueError, "path too long");
2352 return NULL;
2353 }
2354 strcpy(namebuf, name);
2355 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002356 if (*pt == ALTSEP)
2357 *pt = SEP;
2358 if (namebuf[len-1] != SEP)
2359 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002360 strcpy(namebuf + len, "*.*");
2361
2362 if ((d = PyList_New(0)) == NULL)
2363 return NULL;
2364
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002365 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2366 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002367 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002368 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2369 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2370 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002371
2372 if (rc != NO_ERROR) {
2373 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002374 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002375 }
2376
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002377 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002378 do {
2379 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002380 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002381 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002382
2383 strcpy(namebuf, ep.achName);
2384
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002385 /* Leave Case of Name Alone -- In Native Form */
2386 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002387
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002388 v = PyString_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002389 if (v == NULL) {
2390 Py_DECREF(d);
2391 d = NULL;
2392 break;
2393 }
2394 if (PyList_Append(d, v) != 0) {
2395 Py_DECREF(v);
2396 Py_DECREF(d);
2397 d = NULL;
2398 break;
2399 }
2400 Py_DECREF(v);
2401 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2402 }
2403
2404 return d;
2405#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002406
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002407 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002408 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002409 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002410 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002411 int arg_is_unicode = 1;
2412
Georg Brandl05e89b82006-04-11 07:04:06 +00002413 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002414 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2415 arg_is_unicode = 0;
2416 PyErr_Clear();
2417 }
2418 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002419 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002420 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002421 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002422 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002423 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002424 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002425 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002426 return NULL;
2427 }
Georg Brandl622927b2006-03-07 12:48:03 +00002428 for (;;) {
Georg Brandl86cbf812008-07-16 21:31:41 +00002429 errno = 0;
Georg Brandl622927b2006-03-07 12:48:03 +00002430 Py_BEGIN_ALLOW_THREADS
2431 ep = readdir(dirp);
2432 Py_END_ALLOW_THREADS
Georg Brandl86cbf812008-07-16 21:31:41 +00002433 if (ep == NULL) {
2434 if (errno == 0) {
2435 break;
2436 } else {
2437 closedir(dirp);
2438 Py_DECREF(d);
2439 return posix_error_with_allocated_filename(name);
2440 }
2441 }
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002442 if (ep->d_name[0] == '.' &&
2443 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002444 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002445 continue;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002446 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002447 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002448 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002449 d = NULL;
2450 break;
2451 }
Just van Rossum46c97842003-02-25 21:42:15 +00002452#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00002453 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002454 PyObject *w;
2455
2456 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002457 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002458 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002459 if (w != NULL) {
2460 Py_DECREF(v);
2461 v = w;
2462 }
2463 else {
2464 /* fall back to the original byte string, as
2465 discussed in patch #683592 */
2466 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002467 }
Just van Rossum46c97842003-02-25 21:42:15 +00002468 }
2469#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002470 if (PyList_Append(d, v) != 0) {
2471 Py_DECREF(v);
2472 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002473 d = NULL;
2474 break;
2475 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002476 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002477 }
2478 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002479 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002480
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002481 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002482
Tim Peters0bb44a42000-09-15 07:44:49 +00002483#endif /* which OS */
2484} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002485
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002486#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002487/* A helper function for abspath on win32 */
2488static PyObject *
2489posix__getfullpathname(PyObject *self, PyObject *args)
2490{
Mark Dickinson3e4caeb2009-02-21 20:27:01 +00002491 /* assume encoded strings won't more than double no of chars */
Mark Hammondef8b6542001-05-13 08:04:26 +00002492 char inbuf[MAX_PATH*2];
2493 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002494 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002495 char outbuf[MAX_PATH*2];
2496 char *temp;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002497
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002498 if (unicode_file_names()) {
2499 PyUnicodeObject *po;
2500 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
Hirokazu Yamamotoed29bb42008-11-08 03:46:17 +00002501 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2502 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002503 Py_UNICODE *wtemp;
Hirokazu Yamamotoed29bb42008-11-08 03:46:17 +00002504 DWORD result;
2505 PyObject *v;
2506 result = GetFullPathNameW(wpath,
2507 sizeof(woutbuf)/sizeof(woutbuf[0]),
2508 woutbuf, &wtemp);
2509 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2510 woutbufp = malloc(result * sizeof(Py_UNICODE));
2511 if (!woutbufp)
2512 return PyErr_NoMemory();
2513 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2514 }
2515 if (result)
2516 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2517 else
2518 v = win32_error_unicode("GetFullPathNameW", wpath);
2519 if (woutbufp != woutbuf)
2520 free(woutbufp);
2521 return v;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002522 }
2523 /* Drop the argument parsing error as narrow strings
2524 are also valid. */
2525 PyErr_Clear();
2526 }
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002527
Tim Peters5aa91602002-01-30 05:46:57 +00002528 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2529 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002530 &insize))
2531 return NULL;
2532 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2533 outbuf, &temp))
2534 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002535 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2536 return PyUnicode_Decode(outbuf, strlen(outbuf),
2537 Py_FileSystemDefaultEncoding, NULL);
2538 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002539 return PyString_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002540} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002541#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002542
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002543PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002544"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002545Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002546
Barry Warsaw53699e91996-12-10 23:23:01 +00002547static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002548posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002549{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002550 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002551 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002552 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002553
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002554#ifdef MS_WINDOWS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002555 if (unicode_file_names()) {
2556 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002557 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002558 Py_BEGIN_ALLOW_THREADS
2559 /* PyUnicode_AS_UNICODE OK without thread lock as
2560 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002561 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002562 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002563 if (!res)
2564 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002565 Py_INCREF(Py_None);
2566 return Py_None;
2567 }
2568 /* Drop the argument parsing error as narrow strings
2569 are also valid. */
2570 PyErr_Clear();
2571 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002572 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2573 Py_FileSystemDefaultEncoding, &path, &mode))
2574 return NULL;
2575 Py_BEGIN_ALLOW_THREADS
2576 /* PyUnicode_AS_UNICODE OK without thread lock as
2577 it is a simple dereference. */
2578 res = CreateDirectoryA(path, NULL);
2579 Py_END_ALLOW_THREADS
2580 if (!res) {
2581 win32_error("mkdir", path);
2582 PyMem_Free(path);
2583 return NULL;
2584 }
2585 PyMem_Free(path);
2586 Py_INCREF(Py_None);
2587 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002588#else /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002589
Tim Peters5aa91602002-01-30 05:46:57 +00002590 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002591 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002592 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002593 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002594#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002595 res = mkdir(path);
2596#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002597 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002598#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002599 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002600 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002601 return posix_error_with_allocated_filename(path);
2602 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002603 Py_INCREF(Py_None);
2604 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002605#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002606}
2607
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002608
Neal Norwitz1818ed72006-03-26 00:29:48 +00002609/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2610#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002611#include <sys/resource.h>
2612#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002613
Neal Norwitz1818ed72006-03-26 00:29:48 +00002614
2615#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002616PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002617"nice(inc) -> new_priority\n\n\
2618Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002619
Barry Warsaw53699e91996-12-10 23:23:01 +00002620static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002621posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002622{
2623 int increment, value;
2624
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002625 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002626 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002627
2628 /* There are two flavours of 'nice': one that returns the new
2629 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002630 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2631 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002632
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002633 If we are of the nice family that returns the new priority, we
2634 need to clear errno before the call, and check if errno is filled
2635 before calling posix_error() on a returnvalue of -1, because the
2636 -1 may be the actual new priority! */
2637
2638 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002639 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002640#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002641 if (value == 0)
2642 value = getpriority(PRIO_PROCESS, 0);
2643#endif
2644 if (value == -1 && errno != 0)
2645 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002646 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002647 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002648}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002649#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002650
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002651PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002652"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002653Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002654
Barry Warsaw53699e91996-12-10 23:23:01 +00002655static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002656posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002657{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002658#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002659 PyObject *o1, *o2;
2660 char *p1, *p2;
2661 BOOL result;
2662 if (unicode_file_names()) {
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002663 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2664 goto error;
2665 if (!convert_to_unicode(&o1))
2666 goto error;
2667 if (!convert_to_unicode(&o2)) {
2668 Py_DECREF(o1);
2669 goto error;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002670 }
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002671 Py_BEGIN_ALLOW_THREADS
2672 result = MoveFileW(PyUnicode_AsUnicode(o1),
2673 PyUnicode_AsUnicode(o2));
2674 Py_END_ALLOW_THREADS
2675 Py_DECREF(o1);
2676 Py_DECREF(o2);
2677 if (!result)
2678 return win32_error("rename", NULL);
2679 Py_INCREF(Py_None);
2680 return Py_None;
2681error:
2682 PyErr_Clear();
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002683 }
2684 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2685 return NULL;
2686 Py_BEGIN_ALLOW_THREADS
2687 result = MoveFileA(p1, p2);
2688 Py_END_ALLOW_THREADS
2689 if (!result)
2690 return win32_error("rename", NULL);
2691 Py_INCREF(Py_None);
2692 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002693#else
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002694 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002695#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002696}
2697
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002698
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002699PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002700"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002701Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002702
Barry Warsaw53699e91996-12-10 23:23:01 +00002703static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002704posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002705{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002706#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002707 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002708#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002709 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002710#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002711}
2712
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002713
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002714PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002715"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002716Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002717
Barry Warsaw53699e91996-12-10 23:23:01 +00002718static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002719posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002720{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002721#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002722 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002723#else
2724 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2725#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002726}
2727
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002728
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002729#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002730PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002731"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002732Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002733
Barry Warsaw53699e91996-12-10 23:23:01 +00002734static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002735posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002736{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002737 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002738 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002739 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002740 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002741 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002742 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002743 Py_END_ALLOW_THREADS
2744 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002745}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002746#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002747
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002748
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002749PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002750"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002751Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002752
Barry Warsaw53699e91996-12-10 23:23:01 +00002753static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002754posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002755{
2756 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002757 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002758 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002759 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002760 if (i < 0)
2761 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002762 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002763}
2764
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002765
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002766PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002767"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002768Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002769
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002770PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002771"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002772Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002773
Barry Warsaw53699e91996-12-10 23:23:01 +00002774static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002775posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002776{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002777#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002778 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002779#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002780 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002781#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002782}
2783
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002784
Guido van Rossumb6775db1994-08-01 11:34:53 +00002785#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002786PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002787"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002788Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002789
Barry Warsaw53699e91996-12-10 23:23:01 +00002790static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002791posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002792{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002793 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002794 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002795
Barry Warsaw53699e91996-12-10 23:23:01 +00002796 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002797 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002798 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002799 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002800 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002801 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002802 u.sysname,
2803 u.nodename,
2804 u.release,
2805 u.version,
2806 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002807}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002808#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002809
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002810static int
2811extract_time(PyObject *t, long* sec, long* usec)
2812{
2813 long intval;
2814 if (PyFloat_Check(t)) {
2815 double tval = PyFloat_AsDouble(t);
Christian Heimese93237d2007-12-19 02:37:44 +00002816 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002817 if (!intobj)
2818 return -1;
2819 intval = PyInt_AsLong(intobj);
2820 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002821 if (intval == -1 && PyErr_Occurred())
2822 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002823 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002824 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002825 if (*usec < 0)
2826 /* If rounding gave us a negative number,
2827 truncate. */
2828 *usec = 0;
2829 return 0;
2830 }
2831 intval = PyInt_AsLong(t);
2832 if (intval == -1 && PyErr_Occurred())
2833 return -1;
2834 *sec = intval;
2835 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002836 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002837}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002838
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002839PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002840"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002841utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002842Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002843second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002844
Barry Warsaw53699e91996-12-10 23:23:01 +00002845static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002846posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002847{
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002848#ifdef MS_WINDOWS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002849 PyObject *arg;
2850 PyUnicodeObject *obwpath;
2851 wchar_t *wpath = NULL;
2852 char *apath = NULL;
2853 HANDLE hFile;
2854 long atimesec, mtimesec, ausec, musec;
2855 FILETIME atime, mtime;
2856 PyObject *result = NULL;
2857
2858 if (unicode_file_names()) {
2859 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2860 wpath = PyUnicode_AS_UNICODE(obwpath);
2861 Py_BEGIN_ALLOW_THREADS
2862 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002863 NULL, OPEN_EXISTING,
2864 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002865 Py_END_ALLOW_THREADS
2866 if (hFile == INVALID_HANDLE_VALUE)
2867 return win32_error_unicode("utime", wpath);
2868 } else
2869 /* Drop the argument parsing error as narrow strings
2870 are also valid. */
2871 PyErr_Clear();
2872 }
2873 if (!wpath) {
2874 if (!PyArg_ParseTuple(args, "etO:utime",
2875 Py_FileSystemDefaultEncoding, &apath, &arg))
2876 return NULL;
2877 Py_BEGIN_ALLOW_THREADS
2878 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002879 NULL, OPEN_EXISTING,
2880 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002881 Py_END_ALLOW_THREADS
2882 if (hFile == INVALID_HANDLE_VALUE) {
2883 win32_error("utime", apath);
2884 PyMem_Free(apath);
2885 return NULL;
2886 }
2887 PyMem_Free(apath);
2888 }
2889
2890 if (arg == Py_None) {
2891 SYSTEMTIME now;
2892 GetSystemTime(&now);
2893 if (!SystemTimeToFileTime(&now, &mtime) ||
2894 !SystemTimeToFileTime(&now, &atime)) {
2895 win32_error("utime", NULL);
2896 goto done;
2897 }
2898 }
2899 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2900 PyErr_SetString(PyExc_TypeError,
2901 "utime() arg 2 must be a tuple (atime, mtime)");
2902 goto done;
2903 }
2904 else {
2905 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2906 &atimesec, &ausec) == -1)
2907 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002908 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002909 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2910 &mtimesec, &musec) == -1)
2911 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002912 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002913 }
2914 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2915 /* Avoid putting the file name into the error here,
2916 as that may confuse the user into believing that
2917 something is wrong with the file, when it also
2918 could be the time stamp that gives a problem. */
2919 win32_error("utime", NULL);
2920 }
2921 Py_INCREF(Py_None);
2922 result = Py_None;
2923done:
2924 CloseHandle(hFile);
2925 return result;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002926#else /* MS_WINDOWS */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002927
Neal Norwitz2adf2102004-06-09 01:46:02 +00002928 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002929 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002930 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002931 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002932
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002933#if defined(HAVE_UTIMES)
2934 struct timeval buf[2];
2935#define ATIME buf[0].tv_sec
2936#define MTIME buf[1].tv_sec
2937#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002938/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002939 struct utimbuf buf;
2940#define ATIME buf.actime
2941#define MTIME buf.modtime
2942#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002943#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002944 time_t buf[2];
2945#define ATIME buf[0]
2946#define MTIME buf[1]
2947#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002948#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002949
Mark Hammond817c9292003-12-03 01:22:38 +00002950
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002951 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002952 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002953 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002954 if (arg == Py_None) {
2955 /* optional time values not given */
2956 Py_BEGIN_ALLOW_THREADS
2957 res = utime(path, NULL);
2958 Py_END_ALLOW_THREADS
2959 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002960 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002961 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002962 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002963 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002964 return NULL;
2965 }
2966 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002967 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002968 &atime, &ausec) == -1) {
2969 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002970 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002971 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002972 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002973 &mtime, &musec) == -1) {
2974 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002975 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002976 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002977 ATIME = atime;
2978 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002979#ifdef HAVE_UTIMES
2980 buf[0].tv_usec = ausec;
2981 buf[1].tv_usec = musec;
2982 Py_BEGIN_ALLOW_THREADS
2983 res = utimes(path, buf);
2984 Py_END_ALLOW_THREADS
2985#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002986 Py_BEGIN_ALLOW_THREADS
2987 res = utime(path, UTIME_ARG);
2988 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002989#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002990 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002991 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002992 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002993 }
Neal Norwitz96652712004-06-06 20:40:27 +00002994 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002995 Py_INCREF(Py_None);
2996 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002997#undef UTIME_ARG
2998#undef ATIME
2999#undef MTIME
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00003000#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003001}
3002
Guido van Rossum85e3b011991-06-03 12:42:10 +00003003
Guido van Rossum3b066191991-06-04 19:40:25 +00003004/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003005
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003006PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003007"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003008Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003009
Barry Warsaw53699e91996-12-10 23:23:01 +00003010static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003011posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003012{
3013 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003014 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003015 return NULL;
3016 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00003017 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003018}
3019
Martin v. Löwis114619e2002-10-07 06:44:21 +00003020#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3021static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003022free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003023{
Martin v. Löwis725507b2006-03-07 12:08:51 +00003024 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00003025 for (i = 0; i < count; i++)
3026 PyMem_Free(array[i]);
3027 PyMem_DEL(array);
3028}
3029#endif
3030
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003031
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003032#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003033PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003034"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003035Execute an executable path with arguments, replacing current process.\n\
3036\n\
3037 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003038 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003039
Barry Warsaw53699e91996-12-10 23:23:01 +00003040static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003041posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003042{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003043 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003044 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003045 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003046 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003047 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003048
Guido van Rossum89b33251993-10-22 14:26:06 +00003049 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00003050 argv is a list or tuple of strings. */
3051
Martin v. Löwis114619e2002-10-07 06:44:21 +00003052 if (!PyArg_ParseTuple(args, "etO:execv",
3053 Py_FileSystemDefaultEncoding,
3054 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003055 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003056 if (PyList_Check(argv)) {
3057 argc = PyList_Size(argv);
3058 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003059 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003060 else if (PyTuple_Check(argv)) {
3061 argc = PyTuple_Size(argv);
3062 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003063 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003064 else {
Fred Drake661ea262000-10-24 19:57:45 +00003065 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003066 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00003067 return NULL;
3068 }
3069
Barry Warsaw53699e91996-12-10 23:23:01 +00003070 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003071 if (argvlist == NULL) {
3072 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003073 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003074 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00003075 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003076 if (!PyArg_Parse((*getitem)(argv, i), "et",
3077 Py_FileSystemDefaultEncoding,
3078 &argvlist[i])) {
3079 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00003080 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00003081 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003082 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00003083 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003084
Guido van Rossum85e3b011991-06-03 12:42:10 +00003085 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00003086 }
3087 argvlist[argc] = NULL;
3088
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003089 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003090
Guido van Rossum85e3b011991-06-03 12:42:10 +00003091 /* If we get here it's definitely an error */
3092
Martin v. Löwis114619e2002-10-07 06:44:21 +00003093 free_string_array(argvlist, argc);
3094 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003095 return posix_error();
3096}
3097
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003098
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003099PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003100"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003101Execute a path with arguments and environment, replacing current process.\n\
3102\n\
3103 path: path of executable file\n\
3104 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003105 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003106
Barry Warsaw53699e91996-12-10 23:23:01 +00003107static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003108posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003109{
3110 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003111 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003112 char **argvlist;
3113 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003114 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003115 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003116 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003117 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003118
3119 /* execve has three arguments: (path, argv, env), where
3120 argv is a list or tuple of strings and env is a dictionary
3121 like posix.environ. */
3122
Martin v. Löwis114619e2002-10-07 06:44:21 +00003123 if (!PyArg_ParseTuple(args, "etOO:execve",
3124 Py_FileSystemDefaultEncoding,
3125 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003126 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003127 if (PyList_Check(argv)) {
3128 argc = PyList_Size(argv);
3129 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003130 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003131 else if (PyTuple_Check(argv)) {
3132 argc = PyTuple_Size(argv);
3133 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003134 }
3135 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003136 PyErr_SetString(PyExc_TypeError,
3137 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003138 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003139 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003140 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003141 PyErr_SetString(PyExc_TypeError,
3142 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003143 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003144 }
3145
Barry Warsaw53699e91996-12-10 23:23:01 +00003146 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003147 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003148 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003149 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003150 }
3151 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003152 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00003153 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00003154 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00003155 &argvlist[i]))
3156 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003157 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003158 goto fail_1;
3159 }
3160 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003161 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003162 argvlist[argc] = NULL;
3163
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003164 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003165 if (i < 0)
3166 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00003167 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003168 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003169 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003170 goto fail_1;
3171 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003172 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003173 keys = PyMapping_Keys(env);
3174 vals = PyMapping_Values(env);
3175 if (!keys || !vals)
3176 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003177 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3178 PyErr_SetString(PyExc_TypeError,
3179 "execve(): env.keys() or env.values() is not a list");
3180 goto fail_2;
3181 }
Tim Peters5aa91602002-01-30 05:46:57 +00003182
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003183 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003184 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003185 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003186
3187 key = PyList_GetItem(keys, pos);
3188 val = PyList_GetItem(vals, pos);
3189 if (!key || !val)
3190 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003191
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003192 if (!PyArg_Parse(
3193 key,
3194 "s;execve() arg 3 contains a non-string key",
3195 &k) ||
3196 !PyArg_Parse(
3197 val,
3198 "s;execve() arg 3 contains a non-string value",
3199 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003200 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003201 goto fail_2;
3202 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003203
3204#if defined(PYOS_OS2)
3205 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3206 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3207#endif
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003208 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003209 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003210 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003211 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003212 goto fail_2;
3213 }
Tim Petersc8996f52001-12-03 20:41:00 +00003214 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003215 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003216#if defined(PYOS_OS2)
3217 }
3218#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003219 }
3220 envlist[envc] = 0;
3221
3222 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003223
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003224 /* If we get here it's definitely an error */
3225
3226 (void) posix_error();
3227
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003228 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003229 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003230 PyMem_DEL(envlist[envc]);
3231 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003232 fail_1:
3233 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003234 Py_XDECREF(vals);
3235 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003236 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003237 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003238 return NULL;
3239}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003240#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003241
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003242
Guido van Rossuma1065681999-01-25 23:20:23 +00003243#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003244PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003245"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003246Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003247\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003248 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003249 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003250 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003251
3252static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003253posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003254{
3255 char *path;
3256 PyObject *argv;
3257 char **argvlist;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003258 int mode, i;
3259 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003260 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003261 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003262
3263 /* spawnv has three arguments: (mode, path, argv), where
3264 argv is a list or tuple of strings. */
3265
Martin v. Löwis114619e2002-10-07 06:44:21 +00003266 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3267 Py_FileSystemDefaultEncoding,
3268 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003269 return NULL;
3270 if (PyList_Check(argv)) {
3271 argc = PyList_Size(argv);
3272 getitem = PyList_GetItem;
3273 }
3274 else if (PyTuple_Check(argv)) {
3275 argc = PyTuple_Size(argv);
3276 getitem = PyTuple_GetItem;
3277 }
3278 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003279 PyErr_SetString(PyExc_TypeError,
3280 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003281 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003282 return NULL;
3283 }
3284
3285 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003286 if (argvlist == NULL) {
3287 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003288 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003289 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003290 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003291 if (!PyArg_Parse((*getitem)(argv, i), "et",
3292 Py_FileSystemDefaultEncoding,
3293 &argvlist[i])) {
3294 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003295 PyErr_SetString(
3296 PyExc_TypeError,
3297 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003298 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00003299 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003300 }
3301 }
3302 argvlist[argc] = NULL;
3303
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003304#if defined(PYOS_OS2) && defined(PYCC_GCC)
3305 Py_BEGIN_ALLOW_THREADS
3306 spawnval = spawnv(mode, path, argvlist);
3307 Py_END_ALLOW_THREADS
3308#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003309 if (mode == _OLD_P_OVERLAY)
3310 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003311
Tim Peters25059d32001-12-07 20:35:43 +00003312 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003313 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003314 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003315#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003316
Martin v. Löwis114619e2002-10-07 06:44:21 +00003317 free_string_array(argvlist, argc);
3318 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003319
Fred Drake699f3522000-06-29 21:12:41 +00003320 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003321 return posix_error();
3322 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003323#if SIZEOF_LONG == SIZEOF_VOID_P
3324 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003325#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003326 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003327#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003328}
3329
3330
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003331PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003332"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003333Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003334\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003335 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003336 path: path of executable file\n\
3337 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003338 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003339
3340static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003341posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003342{
3343 char *path;
3344 PyObject *argv, *env;
3345 char **argvlist;
3346 char **envlist;
3347 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003348 int mode, pos, envc;
3349 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003350 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003351 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003352 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003353
3354 /* spawnve has four arguments: (mode, path, argv, env), where
3355 argv is a list or tuple of strings and env is a dictionary
3356 like posix.environ. */
3357
Martin v. Löwis114619e2002-10-07 06:44:21 +00003358 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3359 Py_FileSystemDefaultEncoding,
3360 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003361 return NULL;
3362 if (PyList_Check(argv)) {
3363 argc = PyList_Size(argv);
3364 getitem = PyList_GetItem;
3365 }
3366 else if (PyTuple_Check(argv)) {
3367 argc = PyTuple_Size(argv);
3368 getitem = PyTuple_GetItem;
3369 }
3370 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003371 PyErr_SetString(PyExc_TypeError,
3372 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003373 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003374 }
3375 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003376 PyErr_SetString(PyExc_TypeError,
3377 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003378 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003379 }
3380
3381 argvlist = PyMem_NEW(char *, argc+1);
3382 if (argvlist == NULL) {
3383 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003384 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003385 }
3386 for (i = 0; i < argc; i++) {
3387 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003388 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00003389 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00003390 &argvlist[i]))
3391 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003392 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003393 goto fail_1;
3394 }
3395 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003396 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003397 argvlist[argc] = NULL;
3398
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003399 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003400 if (i < 0)
3401 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003402 envlist = PyMem_NEW(char *, i + 1);
3403 if (envlist == NULL) {
3404 PyErr_NoMemory();
3405 goto fail_1;
3406 }
3407 envc = 0;
3408 keys = PyMapping_Keys(env);
3409 vals = PyMapping_Values(env);
3410 if (!keys || !vals)
3411 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003412 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3413 PyErr_SetString(PyExc_TypeError,
3414 "spawnve(): env.keys() or env.values() is not a list");
3415 goto fail_2;
3416 }
Tim Peters5aa91602002-01-30 05:46:57 +00003417
Guido van Rossuma1065681999-01-25 23:20:23 +00003418 for (pos = 0; pos < i; pos++) {
3419 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003420 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003421
3422 key = PyList_GetItem(keys, pos);
3423 val = PyList_GetItem(vals, pos);
3424 if (!key || !val)
3425 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003426
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003427 if (!PyArg_Parse(
3428 key,
3429 "s;spawnve() arg 3 contains a non-string key",
3430 &k) ||
3431 !PyArg_Parse(
3432 val,
3433 "s;spawnve() arg 3 contains a non-string value",
3434 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003435 {
3436 goto fail_2;
3437 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003438 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003439 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003440 if (p == NULL) {
3441 PyErr_NoMemory();
3442 goto fail_2;
3443 }
Tim Petersc8996f52001-12-03 20:41:00 +00003444 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003445 envlist[envc++] = p;
3446 }
3447 envlist[envc] = 0;
3448
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003449#if defined(PYOS_OS2) && defined(PYCC_GCC)
3450 Py_BEGIN_ALLOW_THREADS
3451 spawnval = spawnve(mode, path, argvlist, envlist);
3452 Py_END_ALLOW_THREADS
3453#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003454 if (mode == _OLD_P_OVERLAY)
3455 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003456
3457 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003458 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003459 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003460#endif
Tim Peters25059d32001-12-07 20:35:43 +00003461
Fred Drake699f3522000-06-29 21:12:41 +00003462 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003463 (void) posix_error();
3464 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003465#if SIZEOF_LONG == SIZEOF_VOID_P
3466 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003467#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003468 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003469#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003470
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003471 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003472 while (--envc >= 0)
3473 PyMem_DEL(envlist[envc]);
3474 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003475 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003476 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003477 Py_XDECREF(vals);
3478 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003479 fail_0:
3480 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003481 return res;
3482}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003483
3484/* OS/2 supports spawnvp & spawnvpe natively */
3485#if defined(PYOS_OS2)
3486PyDoc_STRVAR(posix_spawnvp__doc__,
3487"spawnvp(mode, file, args)\n\n\
3488Execute the program 'file' in a new process, using the environment\n\
3489search path to find the file.\n\
3490\n\
3491 mode: mode of process creation\n\
3492 file: executable file name\n\
3493 args: tuple or list of strings");
3494
3495static PyObject *
3496posix_spawnvp(PyObject *self, PyObject *args)
3497{
3498 char *path;
3499 PyObject *argv;
3500 char **argvlist;
3501 int mode, i, argc;
3502 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003503 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003504
3505 /* spawnvp has three arguments: (mode, path, argv), where
3506 argv is a list or tuple of strings. */
3507
3508 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3509 Py_FileSystemDefaultEncoding,
3510 &path, &argv))
3511 return NULL;
3512 if (PyList_Check(argv)) {
3513 argc = PyList_Size(argv);
3514 getitem = PyList_GetItem;
3515 }
3516 else if (PyTuple_Check(argv)) {
3517 argc = PyTuple_Size(argv);
3518 getitem = PyTuple_GetItem;
3519 }
3520 else {
3521 PyErr_SetString(PyExc_TypeError,
3522 "spawnvp() arg 2 must be a tuple or list");
3523 PyMem_Free(path);
3524 return NULL;
3525 }
3526
3527 argvlist = PyMem_NEW(char *, argc+1);
3528 if (argvlist == NULL) {
3529 PyMem_Free(path);
3530 return PyErr_NoMemory();
3531 }
3532 for (i = 0; i < argc; i++) {
3533 if (!PyArg_Parse((*getitem)(argv, i), "et",
3534 Py_FileSystemDefaultEncoding,
3535 &argvlist[i])) {
3536 free_string_array(argvlist, i);
3537 PyErr_SetString(
3538 PyExc_TypeError,
3539 "spawnvp() arg 2 must contain only strings");
3540 PyMem_Free(path);
3541 return NULL;
3542 }
3543 }
3544 argvlist[argc] = NULL;
3545
3546 Py_BEGIN_ALLOW_THREADS
3547#if defined(PYCC_GCC)
3548 spawnval = spawnvp(mode, path, argvlist);
3549#else
3550 spawnval = _spawnvp(mode, path, argvlist);
3551#endif
3552 Py_END_ALLOW_THREADS
3553
3554 free_string_array(argvlist, argc);
3555 PyMem_Free(path);
3556
3557 if (spawnval == -1)
3558 return posix_error();
3559 else
3560 return Py_BuildValue("l", (long) spawnval);
3561}
3562
3563
3564PyDoc_STRVAR(posix_spawnvpe__doc__,
3565"spawnvpe(mode, file, args, env)\n\n\
3566Execute the program 'file' in a new process, using the environment\n\
3567search path to find the file.\n\
3568\n\
3569 mode: mode of process creation\n\
3570 file: executable file name\n\
3571 args: tuple or list of arguments\n\
3572 env: dictionary of strings mapping to strings");
3573
3574static PyObject *
3575posix_spawnvpe(PyObject *self, PyObject *args)
3576{
3577 char *path;
3578 PyObject *argv, *env;
3579 char **argvlist;
3580 char **envlist;
3581 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3582 int mode, i, pos, argc, envc;
3583 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003584 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003585 int lastarg = 0;
3586
3587 /* spawnvpe has four arguments: (mode, path, argv, env), where
3588 argv is a list or tuple of strings and env is a dictionary
3589 like posix.environ. */
3590
3591 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3592 Py_FileSystemDefaultEncoding,
3593 &path, &argv, &env))
3594 return NULL;
3595 if (PyList_Check(argv)) {
3596 argc = PyList_Size(argv);
3597 getitem = PyList_GetItem;
3598 }
3599 else if (PyTuple_Check(argv)) {
3600 argc = PyTuple_Size(argv);
3601 getitem = PyTuple_GetItem;
3602 }
3603 else {
3604 PyErr_SetString(PyExc_TypeError,
3605 "spawnvpe() arg 2 must be a tuple or list");
3606 goto fail_0;
3607 }
3608 if (!PyMapping_Check(env)) {
3609 PyErr_SetString(PyExc_TypeError,
3610 "spawnvpe() arg 3 must be a mapping object");
3611 goto fail_0;
3612 }
3613
3614 argvlist = PyMem_NEW(char *, argc+1);
3615 if (argvlist == NULL) {
3616 PyErr_NoMemory();
3617 goto fail_0;
3618 }
3619 for (i = 0; i < argc; i++) {
3620 if (!PyArg_Parse((*getitem)(argv, i),
3621 "et;spawnvpe() arg 2 must contain only strings",
3622 Py_FileSystemDefaultEncoding,
3623 &argvlist[i]))
3624 {
3625 lastarg = i;
3626 goto fail_1;
3627 }
3628 }
3629 lastarg = argc;
3630 argvlist[argc] = NULL;
3631
3632 i = PyMapping_Size(env);
3633 if (i < 0)
3634 goto fail_1;
3635 envlist = PyMem_NEW(char *, i + 1);
3636 if (envlist == NULL) {
3637 PyErr_NoMemory();
3638 goto fail_1;
3639 }
3640 envc = 0;
3641 keys = PyMapping_Keys(env);
3642 vals = PyMapping_Values(env);
3643 if (!keys || !vals)
3644 goto fail_2;
3645 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3646 PyErr_SetString(PyExc_TypeError,
3647 "spawnvpe(): env.keys() or env.values() is not a list");
3648 goto fail_2;
3649 }
3650
3651 for (pos = 0; pos < i; pos++) {
3652 char *p, *k, *v;
3653 size_t len;
3654
3655 key = PyList_GetItem(keys, pos);
3656 val = PyList_GetItem(vals, pos);
3657 if (!key || !val)
3658 goto fail_2;
3659
3660 if (!PyArg_Parse(
3661 key,
3662 "s;spawnvpe() arg 3 contains a non-string key",
3663 &k) ||
3664 !PyArg_Parse(
3665 val,
3666 "s;spawnvpe() arg 3 contains a non-string value",
3667 &v))
3668 {
3669 goto fail_2;
3670 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003671 len = PyString_Size(key) + PyString_Size(val) + 2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003672 p = PyMem_NEW(char, len);
3673 if (p == NULL) {
3674 PyErr_NoMemory();
3675 goto fail_2;
3676 }
3677 PyOS_snprintf(p, len, "%s=%s", k, v);
3678 envlist[envc++] = p;
3679 }
3680 envlist[envc] = 0;
3681
3682 Py_BEGIN_ALLOW_THREADS
3683#if defined(PYCC_GCC)
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003684 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003685#else
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003686 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003687#endif
3688 Py_END_ALLOW_THREADS
3689
3690 if (spawnval == -1)
3691 (void) posix_error();
3692 else
3693 res = Py_BuildValue("l", (long) spawnval);
3694
3695 fail_2:
3696 while (--envc >= 0)
3697 PyMem_DEL(envlist[envc]);
3698 PyMem_DEL(envlist);
3699 fail_1:
3700 free_string_array(argvlist, lastarg);
3701 Py_XDECREF(vals);
3702 Py_XDECREF(keys);
3703 fail_0:
3704 PyMem_Free(path);
3705 return res;
3706}
3707#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003708#endif /* HAVE_SPAWNV */
3709
3710
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003711#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003712PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003713"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003714Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3715\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003716Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003717
3718static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003719posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003720{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003721 pid_t pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003722 if (pid == -1)
3723 return posix_error();
Gregory P. Smithfb7a50f2008-07-14 06:06:48 +00003724 if (pid == 0)
3725 PyOS_AfterFork();
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00003726 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003727}
3728#endif
3729
3730
Guido van Rossumad0ee831995-03-01 10:34:45 +00003731#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003732PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003733"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003734Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003735Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003736
Barry Warsaw53699e91996-12-10 23:23:01 +00003737static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003738posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003739{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003740 pid_t pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003741 if (pid == -1)
3742 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003743 if (pid == 0)
3744 PyOS_AfterFork();
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00003745 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003746}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003747#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003748
Neal Norwitzb59798b2003-03-21 01:43:31 +00003749/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003750/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3751#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003752#define DEV_PTY_FILE "/dev/ptc"
3753#define HAVE_DEV_PTMX
3754#else
3755#define DEV_PTY_FILE "/dev/ptmx"
3756#endif
3757
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003758#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003759#ifdef HAVE_PTY_H
3760#include <pty.h>
3761#else
3762#ifdef HAVE_LIBUTIL_H
3763#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003764#endif /* HAVE_LIBUTIL_H */
3765#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003766#ifdef HAVE_STROPTS_H
3767#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003768#endif
3769#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003770
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003771#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003772PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003773"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003774Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003775
3776static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003777posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003778{
3779 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003780#ifndef HAVE_OPENPTY
3781 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003782#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003783#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003784 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003785#ifdef sun
Neal Norwitz84a98e02006-04-10 07:44:23 +00003786 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003787#endif
3788#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003789
Thomas Wouters70c21a12000-07-14 14:28:33 +00003790#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003791 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3792 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003793#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003794 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3795 if (slave_name == NULL)
3796 return posix_error();
3797
3798 slave_fd = open(slave_name, O_RDWR);
3799 if (slave_fd < 0)
3800 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003801#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003802 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003803 if (master_fd < 0)
3804 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003805 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003806 /* change permission of slave */
3807 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003808 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003809 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003810 }
3811 /* unlock slave */
3812 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003813 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003814 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003815 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003816 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003817 slave_name = ptsname(master_fd); /* get name of slave */
3818 if (slave_name == NULL)
3819 return posix_error();
3820 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3821 if (slave_fd < 0)
3822 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003823#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003824 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3825 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003826#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003827 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003828#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003829#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003830#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003831
Fred Drake8cef4cf2000-06-28 16:40:38 +00003832 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003833
Fred Drake8cef4cf2000-06-28 16:40:38 +00003834}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003835#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003836
3837#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003838PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003839"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003840Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3841Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003842To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003843
3844static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003845posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003846{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003847 int master_fd = -1;
3848 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003849
Fred Drake8cef4cf2000-06-28 16:40:38 +00003850 pid = forkpty(&master_fd, NULL, NULL, NULL);
3851 if (pid == -1)
3852 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003853 if (pid == 0)
3854 PyOS_AfterFork();
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00003855 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003856}
3857#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003858
Guido van Rossumad0ee831995-03-01 10:34:45 +00003859#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003860PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003861"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003862Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003863
Barry Warsaw53699e91996-12-10 23:23:01 +00003864static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003865posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003866{
Barry Warsaw53699e91996-12-10 23:23:01 +00003867 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003868}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003869#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003870
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003871
Guido van Rossumad0ee831995-03-01 10:34:45 +00003872#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003873PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003874"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003875Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003876
Barry Warsaw53699e91996-12-10 23:23:01 +00003877static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003878posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003879{
Barry Warsaw53699e91996-12-10 23:23:01 +00003880 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003881}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003882#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003883
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003884
Guido van Rossumad0ee831995-03-01 10:34:45 +00003885#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003886PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003887"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003888Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003889
Barry Warsaw53699e91996-12-10 23:23:01 +00003890static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003891posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003892{
Barry Warsaw53699e91996-12-10 23:23:01 +00003893 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003894}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003895#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003896
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003897
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003898PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003899"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003900Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003901
Barry Warsaw53699e91996-12-10 23:23:01 +00003902static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003903posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003904{
Barry Warsaw53699e91996-12-10 23:23:01 +00003905 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003906}
3907
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003908
Fred Drakec9680921999-12-13 16:37:25 +00003909#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003910PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003911"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003912Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003913
3914static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003915posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003916{
3917 PyObject *result = NULL;
3918
Fred Drakec9680921999-12-13 16:37:25 +00003919#ifdef NGROUPS_MAX
3920#define MAX_GROUPS NGROUPS_MAX
3921#else
3922 /* defined to be 16 on Solaris7, so this should be a small number */
3923#define MAX_GROUPS 64
3924#endif
3925 gid_t grouplist[MAX_GROUPS];
3926 int n;
3927
3928 n = getgroups(MAX_GROUPS, grouplist);
3929 if (n < 0)
3930 posix_error();
3931 else {
3932 result = PyList_New(n);
3933 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003934 int i;
3935 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003936 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003937 if (o == NULL) {
3938 Py_DECREF(result);
3939 result = NULL;
3940 break;
3941 }
3942 PyList_SET_ITEM(result, i, o);
3943 }
3944 }
3945 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003946
Fred Drakec9680921999-12-13 16:37:25 +00003947 return result;
3948}
3949#endif
3950
Martin v. Löwis606edc12002-06-13 21:09:11 +00003951#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003952PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003953"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003954Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003955
3956static PyObject *
3957posix_getpgid(PyObject *self, PyObject *args)
3958{
3959 int pid, pgid;
3960 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3961 return NULL;
3962 pgid = getpgid(pid);
3963 if (pgid < 0)
3964 return posix_error();
3965 return PyInt_FromLong((long)pgid);
3966}
3967#endif /* HAVE_GETPGID */
3968
3969
Guido van Rossumb6775db1994-08-01 11:34:53 +00003970#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003971PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003972"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003973Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003974
Barry Warsaw53699e91996-12-10 23:23:01 +00003975static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003976posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003977{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003978#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003979 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003980#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003981 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003982#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003983}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003984#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003985
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003986
Guido van Rossumb6775db1994-08-01 11:34:53 +00003987#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003988PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003989"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003990Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003991
Barry Warsaw53699e91996-12-10 23:23:01 +00003992static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003993posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003994{
Guido van Rossum64933891994-10-20 21:56:42 +00003995#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003996 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003997#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003998 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003999#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00004000 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004001 Py_INCREF(Py_None);
4002 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004003}
4004
Guido van Rossumb6775db1994-08-01 11:34:53 +00004005#endif /* HAVE_SETPGRP */
4006
Guido van Rossumad0ee831995-03-01 10:34:45 +00004007#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004008PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004009"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004010Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004011
Barry Warsaw53699e91996-12-10 23:23:01 +00004012static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004013posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004014{
Christian Heimesd491d712008-02-01 18:49:26 +00004015 return PyInt_FromLong(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004016}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004017#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004018
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004019
Fred Drake12c6e2d1999-12-14 21:25:03 +00004020#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004021PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004022"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004023Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004024
4025static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004026posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004027{
Neal Norwitze241ce82003-02-17 18:17:05 +00004028 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00004029 char *name;
4030 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004031
Fred Drakea30680b2000-12-06 21:24:28 +00004032 errno = 0;
4033 name = getlogin();
4034 if (name == NULL) {
4035 if (errno)
4036 posix_error();
4037 else
4038 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00004039 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00004040 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00004041 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004042 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00004043 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004044
Fred Drake12c6e2d1999-12-14 21:25:03 +00004045 return result;
4046}
4047#endif
4048
Guido van Rossumad0ee831995-03-01 10:34:45 +00004049#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004050PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004051"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004052Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004053
Barry Warsaw53699e91996-12-10 23:23:01 +00004054static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004055posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004056{
Barry Warsaw53699e91996-12-10 23:23:01 +00004057 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004058}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004059#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004060
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004061
Guido van Rossumad0ee831995-03-01 10:34:45 +00004062#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004063PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004064"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004065Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004066
Barry Warsaw53699e91996-12-10 23:23:01 +00004067static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004068posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004069{
Christian Heimesd491d712008-02-01 18:49:26 +00004070 pid_t pid;
4071 int sig;
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00004072 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00004073 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004074#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004075 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4076 APIRET rc;
4077 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004078 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004079
4080 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4081 APIRET rc;
4082 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004083 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004084
4085 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004086 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004087#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00004088 if (kill(pid, sig) == -1)
4089 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004090#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004091 Py_INCREF(Py_None);
4092 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004093}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004094#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004095
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004096#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004097PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004098"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004099Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004100
4101static PyObject *
4102posix_killpg(PyObject *self, PyObject *args)
4103{
4104 int pgid, sig;
4105 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
4106 return NULL;
4107 if (killpg(pgid, sig) == -1)
4108 return posix_error();
4109 Py_INCREF(Py_None);
4110 return Py_None;
4111}
4112#endif
4113
Guido van Rossumc0125471996-06-28 18:55:32 +00004114#ifdef HAVE_PLOCK
4115
4116#ifdef HAVE_SYS_LOCK_H
4117#include <sys/lock.h>
4118#endif
4119
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004120PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004121"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004122Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004123
Barry Warsaw53699e91996-12-10 23:23:01 +00004124static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004125posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004126{
4127 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004128 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00004129 return NULL;
4130 if (plock(op) == -1)
4131 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004132 Py_INCREF(Py_None);
4133 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004134}
4135#endif
4136
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004137
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004138#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004139PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004140"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004141Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004142
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004143#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004144#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004145static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004146async_system(const char *command)
4147{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004148 char errormsg[256], args[1024];
4149 RESULTCODES rcodes;
4150 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004151
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004152 char *shell = getenv("COMSPEC");
4153 if (!shell)
4154 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004155
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004156 /* avoid overflowing the argument buffer */
4157 if (strlen(shell) + 3 + strlen(command) >= 1024)
4158 return ERROR_NOT_ENOUGH_MEMORY
4159
4160 args[0] = '\0';
4161 strcat(args, shell);
4162 strcat(args, "/c ");
4163 strcat(args, command);
4164
4165 /* execute asynchronously, inheriting the environment */
4166 rc = DosExecPgm(errormsg,
4167 sizeof(errormsg),
4168 EXEC_ASYNC,
4169 args,
4170 NULL,
4171 &rcodes,
4172 shell);
4173 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004174}
4175
Guido van Rossumd48f2521997-12-05 22:19:34 +00004176static FILE *
4177popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004178{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004179 int oldfd, tgtfd;
4180 HFILE pipeh[2];
4181 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004182
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004183 /* mode determines which of stdin or stdout is reconnected to
4184 * the pipe to the child
4185 */
4186 if (strchr(mode, 'r') != NULL) {
4187 tgt_fd = 1; /* stdout */
4188 } else if (strchr(mode, 'w')) {
4189 tgt_fd = 0; /* stdin */
4190 } else {
4191 *err = ERROR_INVALID_ACCESS;
4192 return NULL;
4193 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004194
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00004195 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004196 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4197 *err = rc;
4198 return NULL;
4199 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004200
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004201 /* prevent other threads accessing stdio */
4202 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004203
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004204 /* reconnect stdio and execute child */
4205 oldfd = dup(tgtfd);
4206 close(tgtfd);
4207 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4208 DosClose(pipeh[tgtfd]);
4209 rc = async_system(command);
4210 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004211
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004212 /* restore stdio */
4213 dup2(oldfd, tgtfd);
4214 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004215
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004216 /* allow other threads access to stdio */
4217 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004218
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004219 /* if execution of child was successful return file stream */
4220 if (rc == NO_ERROR)
4221 return fdopen(pipeh[1 - tgtfd], mode);
4222 else {
4223 DosClose(pipeh[1 - tgtfd]);
4224 *err = rc;
4225 return NULL;
4226 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004227}
4228
4229static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004230posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004231{
4232 char *name;
4233 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00004234 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004235 FILE *fp;
4236 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004237 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004238 return NULL;
4239 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00004240 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004241 Py_END_ALLOW_THREADS
4242 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004243 return os2_error(err);
4244
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004245 f = PyFile_FromFile(fp, name, mode, fclose);
4246 if (f != NULL)
4247 PyFile_SetBufSize(f, bufsize);
4248 return f;
4249}
4250
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004251#elif defined(PYCC_GCC)
4252
4253/* standard posix version of popen() support */
4254static PyObject *
4255posix_popen(PyObject *self, PyObject *args)
4256{
4257 char *name;
4258 char *mode = "r";
4259 int bufsize = -1;
4260 FILE *fp;
4261 PyObject *f;
4262 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4263 return NULL;
4264 Py_BEGIN_ALLOW_THREADS
4265 fp = popen(name, mode);
4266 Py_END_ALLOW_THREADS
4267 if (fp == NULL)
4268 return posix_error();
4269 f = PyFile_FromFile(fp, name, mode, pclose);
4270 if (f != NULL)
4271 PyFile_SetBufSize(f, bufsize);
4272 return f;
4273}
4274
4275/* fork() under OS/2 has lots'o'warts
4276 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4277 * most of this code is a ripoff of the win32 code, but using the
4278 * capabilities of EMX's C library routines
4279 */
4280
4281/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4282#define POPEN_1 1
4283#define POPEN_2 2
4284#define POPEN_3 3
4285#define POPEN_4 4
4286
4287static PyObject *_PyPopen(char *, int, int, int);
4288static int _PyPclose(FILE *file);
4289
4290/*
4291 * Internal dictionary mapping popen* file pointers to process handles,
4292 * for use when retrieving the process exit code. See _PyPclose() below
4293 * for more information on this dictionary's use.
4294 */
4295static PyObject *_PyPopenProcs = NULL;
4296
4297/* os2emx version of popen2()
4298 *
4299 * The result of this function is a pipe (file) connected to the
4300 * process's stdin, and a pipe connected to the process's stdout.
4301 */
4302
4303static PyObject *
4304os2emx_popen2(PyObject *self, PyObject *args)
4305{
4306 PyObject *f;
4307 int tm=0;
4308
4309 char *cmdstring;
4310 char *mode = "t";
4311 int bufsize = -1;
4312 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4313 return NULL;
4314
4315 if (*mode == 't')
4316 tm = O_TEXT;
4317 else if (*mode != 'b') {
4318 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4319 return NULL;
4320 } else
4321 tm = O_BINARY;
4322
4323 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
4324
4325 return f;
4326}
4327
4328/*
4329 * Variation on os2emx.popen2
4330 *
4331 * The result of this function is 3 pipes - the process's stdin,
4332 * stdout and stderr
4333 */
4334
4335static PyObject *
4336os2emx_popen3(PyObject *self, PyObject *args)
4337{
4338 PyObject *f;
4339 int tm = 0;
4340
4341 char *cmdstring;
4342 char *mode = "t";
4343 int bufsize = -1;
4344 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4345 return NULL;
4346
4347 if (*mode == 't')
4348 tm = O_TEXT;
4349 else if (*mode != 'b') {
4350 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4351 return NULL;
4352 } else
4353 tm = O_BINARY;
4354
4355 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
4356
4357 return f;
4358}
4359
4360/*
4361 * Variation on os2emx.popen2
4362 *
Tim Peters11b23062003-04-23 02:39:17 +00004363 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004364 * and stdout+stderr combined as a single pipe.
4365 */
4366
4367static PyObject *
4368os2emx_popen4(PyObject *self, PyObject *args)
4369{
4370 PyObject *f;
4371 int tm = 0;
4372
4373 char *cmdstring;
4374 char *mode = "t";
4375 int bufsize = -1;
4376 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4377 return NULL;
4378
4379 if (*mode == 't')
4380 tm = O_TEXT;
4381 else if (*mode != 'b') {
4382 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4383 return NULL;
4384 } else
4385 tm = O_BINARY;
4386
4387 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
4388
4389 return f;
4390}
4391
4392/* a couple of structures for convenient handling of multiple
4393 * file handles and pipes
4394 */
4395struct file_ref
4396{
4397 int handle;
4398 int flags;
4399};
4400
4401struct pipe_ref
4402{
4403 int rd;
4404 int wr;
4405};
4406
4407/* The following code is derived from the win32 code */
4408
4409static PyObject *
4410_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4411{
4412 struct file_ref stdio[3];
4413 struct pipe_ref p_fd[3];
4414 FILE *p_s[3];
Christian Heimesd491d712008-02-01 18:49:26 +00004415 int file_count, i, pipe_err;
4416 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004417 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4418 PyObject *f, *p_f[3];
4419
4420 /* file modes for subsequent fdopen's on pipe handles */
4421 if (mode == O_TEXT)
4422 {
4423 rd_mode = "rt";
4424 wr_mode = "wt";
4425 }
4426 else
4427 {
4428 rd_mode = "rb";
4429 wr_mode = "wb";
4430 }
4431
4432 /* prepare shell references */
4433 if ((shell = getenv("EMXSHELL")) == NULL)
4434 if ((shell = getenv("COMSPEC")) == NULL)
4435 {
4436 errno = ENOENT;
4437 return posix_error();
4438 }
4439
4440 sh_name = _getname(shell);
4441 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4442 opt = "/c";
4443 else
4444 opt = "-c";
4445
4446 /* save current stdio fds + their flags, and set not inheritable */
4447 i = pipe_err = 0;
4448 while (pipe_err >= 0 && i < 3)
4449 {
4450 pipe_err = stdio[i].handle = dup(i);
4451 stdio[i].flags = fcntl(i, F_GETFD, 0);
4452 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4453 i++;
4454 }
4455 if (pipe_err < 0)
4456 {
4457 /* didn't get them all saved - clean up and bail out */
4458 int saved_err = errno;
4459 while (i-- > 0)
4460 {
4461 close(stdio[i].handle);
4462 }
4463 errno = saved_err;
4464 return posix_error();
4465 }
4466
4467 /* create pipe ends */
4468 file_count = 2;
4469 if (n == POPEN_3)
4470 file_count = 3;
4471 i = pipe_err = 0;
4472 while ((pipe_err == 0) && (i < file_count))
4473 pipe_err = pipe((int *)&p_fd[i++]);
4474 if (pipe_err < 0)
4475 {
4476 /* didn't get them all made - clean up and bail out */
4477 while (i-- > 0)
4478 {
4479 close(p_fd[i].wr);
4480 close(p_fd[i].rd);
4481 }
4482 errno = EPIPE;
4483 return posix_error();
4484 }
4485
4486 /* change the actual standard IO streams over temporarily,
4487 * making the retained pipe ends non-inheritable
4488 */
4489 pipe_err = 0;
4490
4491 /* - stdin */
4492 if (dup2(p_fd[0].rd, 0) == 0)
4493 {
4494 close(p_fd[0].rd);
4495 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4496 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4497 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4498 {
4499 close(p_fd[0].wr);
4500 pipe_err = -1;
4501 }
4502 }
4503 else
4504 {
4505 pipe_err = -1;
4506 }
4507
4508 /* - stdout */
4509 if (pipe_err == 0)
4510 {
4511 if (dup2(p_fd[1].wr, 1) == 1)
4512 {
4513 close(p_fd[1].wr);
4514 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4515 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4516 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4517 {
4518 close(p_fd[1].rd);
4519 pipe_err = -1;
4520 }
4521 }
4522 else
4523 {
4524 pipe_err = -1;
4525 }
4526 }
4527
4528 /* - stderr, as required */
4529 if (pipe_err == 0)
4530 switch (n)
4531 {
4532 case POPEN_3:
4533 {
4534 if (dup2(p_fd[2].wr, 2) == 2)
4535 {
4536 close(p_fd[2].wr);
4537 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4538 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4539 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4540 {
4541 close(p_fd[2].rd);
4542 pipe_err = -1;
4543 }
4544 }
4545 else
4546 {
4547 pipe_err = -1;
4548 }
4549 break;
4550 }
4551
4552 case POPEN_4:
4553 {
4554 if (dup2(1, 2) != 2)
4555 {
4556 pipe_err = -1;
4557 }
4558 break;
4559 }
4560 }
4561
4562 /* spawn the child process */
4563 if (pipe_err == 0)
4564 {
4565 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4566 if (pipe_pid == -1)
4567 {
4568 pipe_err = -1;
4569 }
4570 else
4571 {
4572 /* save the PID into the FILE structure
4573 * NOTE: this implementation doesn't actually
4574 * take advantage of this, but do it for
4575 * completeness - AIM Apr01
4576 */
4577 for (i = 0; i < file_count; i++)
4578 p_s[i]->_pid = pipe_pid;
4579 }
4580 }
4581
4582 /* reset standard IO to normal */
4583 for (i = 0; i < 3; i++)
4584 {
4585 dup2(stdio[i].handle, i);
4586 fcntl(i, F_SETFD, stdio[i].flags);
4587 close(stdio[i].handle);
4588 }
4589
4590 /* if any remnant problems, clean up and bail out */
4591 if (pipe_err < 0)
4592 {
4593 for (i = 0; i < 3; i++)
4594 {
4595 close(p_fd[i].rd);
4596 close(p_fd[i].wr);
4597 }
4598 errno = EPIPE;
4599 return posix_error_with_filename(cmdstring);
4600 }
4601
4602 /* build tuple of file objects to return */
4603 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4604 PyFile_SetBufSize(p_f[0], bufsize);
4605 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4606 PyFile_SetBufSize(p_f[1], bufsize);
4607 if (n == POPEN_3)
4608 {
4609 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4610 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004611 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004612 }
4613 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004614 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004615
4616 /*
4617 * Insert the files we've created into the process dictionary
4618 * all referencing the list with the process handle and the
4619 * initial number of files (see description below in _PyPclose).
4620 * Since if _PyPclose later tried to wait on a process when all
4621 * handles weren't closed, it could create a deadlock with the
4622 * child, we spend some energy here to try to ensure that we
4623 * either insert all file handles into the dictionary or none
4624 * at all. It's a little clumsy with the various popen modes
4625 * and variable number of files involved.
4626 */
4627 if (!_PyPopenProcs)
4628 {
4629 _PyPopenProcs = PyDict_New();
4630 }
4631
4632 if (_PyPopenProcs)
4633 {
4634 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4635 int ins_rc[3];
4636
4637 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4638 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4639
4640 procObj = PyList_New(2);
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00004641 pidObj = PyLong_FromPid(pipe_pid);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004642 intObj = PyInt_FromLong((long) file_count);
4643
4644 if (procObj && pidObj && intObj)
4645 {
4646 PyList_SetItem(procObj, 0, pidObj);
4647 PyList_SetItem(procObj, 1, intObj);
4648
4649 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4650 if (fileObj[0])
4651 {
4652 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4653 fileObj[0],
4654 procObj);
4655 }
4656 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4657 if (fileObj[1])
4658 {
4659 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4660 fileObj[1],
4661 procObj);
4662 }
4663 if (file_count >= 3)
4664 {
4665 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4666 if (fileObj[2])
4667 {
4668 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4669 fileObj[2],
4670 procObj);
4671 }
4672 }
4673
4674 if (ins_rc[0] < 0 || !fileObj[0] ||
4675 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4676 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4677 {
4678 /* Something failed - remove any dictionary
4679 * entries that did make it.
4680 */
4681 if (!ins_rc[0] && fileObj[0])
4682 {
4683 PyDict_DelItem(_PyPopenProcs,
4684 fileObj[0]);
4685 }
4686 if (!ins_rc[1] && fileObj[1])
4687 {
4688 PyDict_DelItem(_PyPopenProcs,
4689 fileObj[1]);
4690 }
4691 if (!ins_rc[2] && fileObj[2])
4692 {
4693 PyDict_DelItem(_PyPopenProcs,
4694 fileObj[2]);
4695 }
4696 }
4697 }
Tim Peters11b23062003-04-23 02:39:17 +00004698
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004699 /*
4700 * Clean up our localized references for the dictionary keys
4701 * and value since PyDict_SetItem will Py_INCREF any copies
4702 * that got placed in the dictionary.
4703 */
4704 Py_XDECREF(procObj);
4705 Py_XDECREF(fileObj[0]);
4706 Py_XDECREF(fileObj[1]);
4707 Py_XDECREF(fileObj[2]);
4708 }
4709
4710 /* Child is launched. */
4711 return f;
4712}
4713
4714/*
4715 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4716 * exit code for the child process and return as a result of the close.
4717 *
4718 * This function uses the _PyPopenProcs dictionary in order to map the
4719 * input file pointer to information about the process that was
4720 * originally created by the popen* call that created the file pointer.
4721 * The dictionary uses the file pointer as a key (with one entry
4722 * inserted for each file returned by the original popen* call) and a
4723 * single list object as the value for all files from a single call.
4724 * The list object contains the Win32 process handle at [0], and a file
4725 * count at [1], which is initialized to the total number of file
4726 * handles using that list.
4727 *
4728 * This function closes whichever handle it is passed, and decrements
4729 * the file count in the dictionary for the process handle pointed to
4730 * by this file. On the last close (when the file count reaches zero),
4731 * this function will wait for the child process and then return its
4732 * exit code as the result of the close() operation. This permits the
4733 * files to be closed in any order - it is always the close() of the
4734 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004735 *
4736 * NOTE: This function is currently called with the GIL released.
4737 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004738 */
4739
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004740static int _PyPclose(FILE *file)
4741{
4742 int result;
4743 int exit_code;
Christian Heimesd491d712008-02-01 18:49:26 +00004744 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004745 PyObject *procObj, *pidObj, *intObj, *fileObj;
4746 int file_count;
4747#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004748 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004749#endif
4750
4751 /* Close the file handle first, to ensure it can't block the
4752 * child from exiting if it's the last handle.
4753 */
4754 result = fclose(file);
4755
4756#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004757 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004758#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004759 if (_PyPopenProcs)
4760 {
4761 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4762 (procObj = PyDict_GetItem(_PyPopenProcs,
4763 fileObj)) != NULL &&
4764 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4765 (intObj = PyList_GetItem(procObj,1)) != NULL)
4766 {
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00004767 pipe_pid = (pid_t) PyLong_AsPid(pidObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004768 file_count = (int) PyInt_AsLong(intObj);
4769
4770 if (file_count > 1)
4771 {
4772 /* Still other files referencing process */
4773 file_count--;
4774 PyList_SetItem(procObj,1,
4775 PyInt_FromLong((long) file_count));
4776 }
4777 else
4778 {
4779 /* Last file for this process */
4780 if (result != EOF &&
4781 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4782 {
4783 /* extract exit status */
4784 if (WIFEXITED(exit_code))
4785 {
4786 result = WEXITSTATUS(exit_code);
4787 }
4788 else
4789 {
4790 errno = EPIPE;
4791 result = -1;
4792 }
4793 }
4794 else
4795 {
4796 /* Indicate failure - this will cause the file object
4797 * to raise an I/O error and translate the last
4798 * error code from errno. We do have a problem with
4799 * last errors that overlap the normal errno table,
4800 * but that's a consistent problem with the file object.
4801 */
4802 result = -1;
4803 }
4804 }
4805
4806 /* Remove this file pointer from dictionary */
4807 PyDict_DelItem(_PyPopenProcs, fileObj);
4808
4809 if (PyDict_Size(_PyPopenProcs) == 0)
4810 {
4811 Py_DECREF(_PyPopenProcs);
4812 _PyPopenProcs = NULL;
4813 }
4814
4815 } /* if object retrieval ok */
4816
4817 Py_XDECREF(fileObj);
4818 } /* if _PyPopenProcs */
4819
4820#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004821 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004822#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004823 return result;
4824}
4825
4826#endif /* PYCC_??? */
4827
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004828#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004829
4830/*
4831 * Portable 'popen' replacement for Win32.
4832 *
4833 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4834 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004835 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004836 */
4837
4838#include <malloc.h>
4839#include <io.h>
4840#include <fcntl.h>
4841
4842/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4843#define POPEN_1 1
4844#define POPEN_2 2
4845#define POPEN_3 3
4846#define POPEN_4 4
4847
4848static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004849static int _PyPclose(FILE *file);
4850
4851/*
4852 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004853 * for use when retrieving the process exit code. See _PyPclose() below
4854 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004855 */
4856static PyObject *_PyPopenProcs = NULL;
4857
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004858
4859/* popen that works from a GUI.
4860 *
4861 * The result of this function is a pipe (file) connected to the
4862 * processes stdin or stdout, depending on the requested mode.
4863 */
4864
4865static PyObject *
4866posix_popen(PyObject *self, PyObject *args)
4867{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004868 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004869 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004870
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004871 char *cmdstring;
4872 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004873 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004874 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004875 return NULL;
4876
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004877 if (*mode == 'r')
4878 tm = _O_RDONLY;
4879 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004880 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004881 return NULL;
4882 } else
4883 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004884
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004885 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004886 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004887 return NULL;
4888 }
4889
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004890 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004891 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004892 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004893 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004894 else
4895 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4896
4897 return f;
4898}
4899
4900/* Variation on win32pipe.popen
4901 *
4902 * The result of this function is a pipe (file) connected to the
4903 * process's stdin, and a pipe connected to the process's stdout.
4904 */
4905
4906static PyObject *
4907win32_popen2(PyObject *self, PyObject *args)
4908{
4909 PyObject *f;
4910 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004911
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004912 char *cmdstring;
4913 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004914 int bufsize = -1;
4915 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004916 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004917
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004918 if (*mode == 't')
4919 tm = _O_TEXT;
4920 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004921 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004922 return NULL;
4923 } else
4924 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004925
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004926 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004927 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004928 return NULL;
4929 }
4930
4931 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004932
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004933 return f;
4934}
4935
4936/*
4937 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004938 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004939 * The result of this function is 3 pipes - the process's stdin,
4940 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004941 */
4942
4943static PyObject *
4944win32_popen3(PyObject *self, PyObject *args)
4945{
4946 PyObject *f;
4947 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004948
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004949 char *cmdstring;
4950 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004951 int bufsize = -1;
4952 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004953 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004954
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004955 if (*mode == 't')
4956 tm = _O_TEXT;
4957 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004958 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004959 return NULL;
4960 } else
4961 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004962
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004963 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004964 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004965 return NULL;
4966 }
4967
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004968 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004969
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004970 return f;
4971}
4972
4973/*
4974 * Variation on win32pipe.popen
4975 *
Tim Peters5aa91602002-01-30 05:46:57 +00004976 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004977 * and stdout+stderr combined as a single pipe.
4978 */
4979
4980static PyObject *
4981win32_popen4(PyObject *self, PyObject *args)
4982{
4983 PyObject *f;
4984 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004985
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004986 char *cmdstring;
4987 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004988 int bufsize = -1;
4989 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004990 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004991
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004992 if (*mode == 't')
4993 tm = _O_TEXT;
4994 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004995 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004996 return NULL;
4997 } else
4998 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004999
5000 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00005001 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005002 return NULL;
5003 }
5004
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00005005 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005006
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005007 return f;
5008}
5009
Mark Hammond08501372001-01-31 07:30:29 +00005010static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00005011_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005012 HANDLE hStdin,
5013 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00005014 HANDLE hStderr,
5015 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005016{
5017 PROCESS_INFORMATION piProcInfo;
5018 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005019 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005020 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00005021 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005022 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005023 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005024
5025 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00005026 char *comshell;
5027
Tim Peters92e4dd82002-10-05 01:47:34 +00005028 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005029 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00005030 /* x < i, so x fits into an integer */
5031 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00005032
5033 /* Explicitly check if we are using COMMAND.COM. If we are
5034 * then use the w9xpopen hack.
5035 */
5036 comshell = s1 + x;
5037 while (comshell >= s1 && *comshell != '\\')
5038 --comshell;
5039 ++comshell;
5040
5041 if (GetVersion() < 0x80000000 &&
5042 _stricmp(comshell, "command.com") != 0) {
5043 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005044 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00005045 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005046 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00005047 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005048 }
5049 else {
5050 /*
Tim Peters402d5982001-08-27 06:37:48 +00005051 * Oh gag, we're on Win9x or using COMMAND.COM. Use
5052 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005053 */
Mark Hammond08501372001-01-31 07:30:29 +00005054 char modulepath[_MAX_PATH];
5055 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005056 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Martin v. Löwis26fd9602006-04-22 11:15:41 +00005057 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005058 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005059 x = i+1;
5060 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00005061 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00005062 strncat(modulepath,
5063 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00005064 (sizeof(modulepath)/sizeof(modulepath[0]))
5065 -strlen(modulepath));
5066 if (stat(modulepath, &statinfo) != 0) {
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00005067 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
Tim Peters5aa91602002-01-30 05:46:57 +00005068 /* Eeek - file-not-found - possibly an embedding
5069 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00005070 */
Tim Peters5aa91602002-01-30 05:46:57 +00005071 strncpy(modulepath,
5072 Py_GetExecPrefix(),
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00005073 mplen);
5074 modulepath[mplen-1] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00005075 if (modulepath[strlen(modulepath)-1] != '\\')
5076 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00005077 strncat(modulepath,
5078 szConsoleSpawn,
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00005079 mplen-strlen(modulepath));
Mark Hammond08501372001-01-31 07:30:29 +00005080 /* No where else to look - raise an easily identifiable
5081 error, rather than leaving Windows to report
5082 "file not found" - as the user is probably blissfully
5083 unaware this shim EXE is used, and it will confuse them.
5084 (well, it confused me for a while ;-)
5085 */
5086 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00005087 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00005088 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00005089 "for popen to work with your shell "
5090 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00005091 szConsoleSpawn);
5092 return FALSE;
5093 }
5094 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005095 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00005096 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005097 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00005098
Tim Peters92e4dd82002-10-05 01:47:34 +00005099 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005100 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00005101 /* To maintain correct argument passing semantics,
5102 we pass the command-line as it stands, and allow
5103 quoting to be applied. w9xpopen.exe will then
5104 use its argv vector, and re-quote the necessary
5105 args for the ultimate child process.
5106 */
Tim Peters75cdad52001-11-28 22:07:30 +00005107 PyOS_snprintf(
5108 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00005109 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005110 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005111 s1,
5112 s3,
5113 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005114 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00005115 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005116 dialog:
5117 "Your program accessed mem currently in use at xxx"
5118 and a hopeful warning about the stability of your
5119 system.
Mark Dickinson3e4caeb2009-02-21 20:27:01 +00005120 Cost is Ctrl+C won't kill children, but anyone
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005121 who cares can have a go!
5122 */
5123 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005124 }
5125 }
5126
5127 /* Could be an else here to try cmd.exe / command.com in the path
5128 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00005129 else {
Tim Peters402d5982001-08-27 06:37:48 +00005130 PyErr_SetString(PyExc_RuntimeError,
5131 "Cannot locate a COMSPEC environment variable to "
5132 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00005133 return FALSE;
5134 }
Tim Peters5aa91602002-01-30 05:46:57 +00005135
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005136 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5137 siStartInfo.cb = sizeof(STARTUPINFO);
5138 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5139 siStartInfo.hStdInput = hStdin;
5140 siStartInfo.hStdOutput = hStdout;
5141 siStartInfo.hStdError = hStderr;
5142 siStartInfo.wShowWindow = SW_HIDE;
5143
5144 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005145 s2,
5146 NULL,
5147 NULL,
5148 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005149 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005150 NULL,
5151 NULL,
5152 &siStartInfo,
5153 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005154 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005155 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005156
Mark Hammondb37a3732000-08-14 04:47:33 +00005157 /* Return process handle */
5158 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005159 return TRUE;
5160 }
Tim Peters402d5982001-08-27 06:37:48 +00005161 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005162 return FALSE;
5163}
5164
5165/* The following code is based off of KB: Q190351 */
5166
5167static PyObject *
5168_PyPopen(char *cmdstring, int mode, int n)
5169{
5170 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5171 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00005172 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005173
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005174 SECURITY_ATTRIBUTES saAttr;
5175 BOOL fSuccess;
5176 int fd1, fd2, fd3;
5177 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00005178 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005179 PyObject *f;
5180
5181 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5182 saAttr.bInheritHandle = TRUE;
5183 saAttr.lpSecurityDescriptor = NULL;
5184
5185 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5186 return win32_error("CreatePipe", NULL);
5187
5188 /* Create new output read handle and the input write handle. Set
5189 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005190 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005191 * being created. */
5192 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005193 GetCurrentProcess(), &hChildStdinWrDup, 0,
5194 FALSE,
5195 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005196 if (!fSuccess)
5197 return win32_error("DuplicateHandle", NULL);
5198
5199 /* Close the inheritable version of ChildStdin
5200 that we're using. */
5201 CloseHandle(hChildStdinWr);
5202
5203 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5204 return win32_error("CreatePipe", NULL);
5205
5206 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005207 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5208 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005209 if (!fSuccess)
5210 return win32_error("DuplicateHandle", NULL);
5211
5212 /* Close the inheritable version of ChildStdout
5213 that we're using. */
5214 CloseHandle(hChildStdoutRd);
5215
5216 if (n != POPEN_4) {
5217 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5218 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005219 fSuccess = DuplicateHandle(GetCurrentProcess(),
5220 hChildStderrRd,
5221 GetCurrentProcess(),
5222 &hChildStderrRdDup, 0,
5223 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005224 if (!fSuccess)
5225 return win32_error("DuplicateHandle", NULL);
5226 /* Close the inheritable version of ChildStdErr that we're using. */
5227 CloseHandle(hChildStderrRd);
5228 }
Tim Peters5aa91602002-01-30 05:46:57 +00005229
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005230 switch (n) {
5231 case POPEN_1:
5232 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5233 case _O_WRONLY | _O_TEXT:
5234 /* Case for writing to child Stdin in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005235 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005236 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005237 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005238 PyFile_SetBufSize(f, 0);
5239 /* We don't care about these pipes anymore, so close them. */
5240 CloseHandle(hChildStdoutRdDup);
5241 CloseHandle(hChildStderrRdDup);
5242 break;
5243
5244 case _O_RDONLY | _O_TEXT:
5245 /* Case for reading from child Stdout in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005246 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005247 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005248 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005249 PyFile_SetBufSize(f, 0);
5250 /* We don't care about these pipes anymore, so close them. */
5251 CloseHandle(hChildStdinWrDup);
5252 CloseHandle(hChildStderrRdDup);
5253 break;
5254
5255 case _O_RDONLY | _O_BINARY:
5256 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005257 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005258 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005259 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005260 PyFile_SetBufSize(f, 0);
5261 /* We don't care about these pipes anymore, so close them. */
5262 CloseHandle(hChildStdinWrDup);
5263 CloseHandle(hChildStderrRdDup);
5264 break;
5265
5266 case _O_WRONLY | _O_BINARY:
5267 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005268 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005269 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005270 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005271 PyFile_SetBufSize(f, 0);
5272 /* We don't care about these pipes anymore, so close them. */
5273 CloseHandle(hChildStdoutRdDup);
5274 CloseHandle(hChildStderrRdDup);
5275 break;
5276 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005277 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005278 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005279
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005280 case POPEN_2:
5281 case POPEN_4:
5282 {
5283 char *m1, *m2;
5284 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005285
Tim Peters7dca21e2002-08-19 00:42:29 +00005286 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005287 m1 = "r";
5288 m2 = "w";
5289 } else {
5290 m1 = "rb";
5291 m2 = "wb";
5292 }
5293
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005294 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005295 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005296 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005297 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005298 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005299 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00005300 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005301 PyFile_SetBufSize(p2, 0);
5302
5303 if (n != 4)
5304 CloseHandle(hChildStderrRdDup);
5305
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005306 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00005307 Py_XDECREF(p1);
5308 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00005309 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005310 break;
5311 }
Tim Peters5aa91602002-01-30 05:46:57 +00005312
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005313 case POPEN_3:
5314 {
5315 char *m1, *m2;
5316 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005317
Tim Peters7dca21e2002-08-19 00:42:29 +00005318 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005319 m1 = "r";
5320 m2 = "w";
5321 } else {
5322 m1 = "rb";
5323 m2 = "wb";
5324 }
5325
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005326 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005327 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005328 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005329 f2 = _fdopen(fd2, m1);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005330 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005331 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005332 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00005333 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5334 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005335 PyFile_SetBufSize(p1, 0);
5336 PyFile_SetBufSize(p2, 0);
5337 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005338 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00005339 Py_XDECREF(p1);
5340 Py_XDECREF(p2);
5341 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00005342 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005343 break;
5344 }
5345 }
5346
5347 if (n == POPEN_4) {
5348 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005349 hChildStdinRd,
5350 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005351 hChildStdoutWr,
5352 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005353 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005354 }
5355 else {
5356 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005357 hChildStdinRd,
5358 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005359 hChildStderrWr,
5360 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005361 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005362 }
5363
Mark Hammondb37a3732000-08-14 04:47:33 +00005364 /*
5365 * Insert the files we've created into the process dictionary
5366 * all referencing the list with the process handle and the
5367 * initial number of files (see description below in _PyPclose).
5368 * Since if _PyPclose later tried to wait on a process when all
5369 * handles weren't closed, it could create a deadlock with the
5370 * child, we spend some energy here to try to ensure that we
5371 * either insert all file handles into the dictionary or none
5372 * at all. It's a little clumsy with the various popen modes
5373 * and variable number of files involved.
5374 */
5375 if (!_PyPopenProcs) {
5376 _PyPopenProcs = PyDict_New();
5377 }
5378
5379 if (_PyPopenProcs) {
5380 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5381 int ins_rc[3];
5382
5383 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5384 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
5385
5386 procObj = PyList_New(2);
5387 hProcessObj = PyLong_FromVoidPtr(hProcess);
5388 intObj = PyInt_FromLong(file_count);
5389
5390 if (procObj && hProcessObj && intObj) {
5391 PyList_SetItem(procObj,0,hProcessObj);
5392 PyList_SetItem(procObj,1,intObj);
5393
5394 fileObj[0] = PyLong_FromVoidPtr(f1);
5395 if (fileObj[0]) {
5396 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5397 fileObj[0],
5398 procObj);
5399 }
5400 if (file_count >= 2) {
5401 fileObj[1] = PyLong_FromVoidPtr(f2);
5402 if (fileObj[1]) {
5403 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5404 fileObj[1],
5405 procObj);
5406 }
5407 }
5408 if (file_count >= 3) {
5409 fileObj[2] = PyLong_FromVoidPtr(f3);
5410 if (fileObj[2]) {
5411 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5412 fileObj[2],
5413 procObj);
5414 }
5415 }
5416
5417 if (ins_rc[0] < 0 || !fileObj[0] ||
5418 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5419 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5420 /* Something failed - remove any dictionary
5421 * entries that did make it.
5422 */
5423 if (!ins_rc[0] && fileObj[0]) {
5424 PyDict_DelItem(_PyPopenProcs,
5425 fileObj[0]);
5426 }
5427 if (!ins_rc[1] && fileObj[1]) {
5428 PyDict_DelItem(_PyPopenProcs,
5429 fileObj[1]);
5430 }
5431 if (!ins_rc[2] && fileObj[2]) {
5432 PyDict_DelItem(_PyPopenProcs,
5433 fileObj[2]);
5434 }
5435 }
5436 }
Tim Peters5aa91602002-01-30 05:46:57 +00005437
Mark Hammondb37a3732000-08-14 04:47:33 +00005438 /*
5439 * Clean up our localized references for the dictionary keys
5440 * and value since PyDict_SetItem will Py_INCREF any copies
5441 * that got placed in the dictionary.
5442 */
5443 Py_XDECREF(procObj);
5444 Py_XDECREF(fileObj[0]);
5445 Py_XDECREF(fileObj[1]);
5446 Py_XDECREF(fileObj[2]);
5447 }
5448
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005449 /* Child is launched. Close the parents copy of those pipe
5450 * handles that only the child should have open. You need to
5451 * make sure that no handles to the write end of the output pipe
5452 * are maintained in this process or else the pipe will not close
5453 * when the child process exits and the ReadFile will hang. */
5454
5455 if (!CloseHandle(hChildStdinRd))
5456 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005457
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005458 if (!CloseHandle(hChildStdoutWr))
5459 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005460
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005461 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5462 return win32_error("CloseHandle", NULL);
5463
5464 return f;
5465}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005466
5467/*
5468 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5469 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005470 *
5471 * This function uses the _PyPopenProcs dictionary in order to map the
5472 * input file pointer to information about the process that was
5473 * originally created by the popen* call that created the file pointer.
5474 * The dictionary uses the file pointer as a key (with one entry
5475 * inserted for each file returned by the original popen* call) and a
5476 * single list object as the value for all files from a single call.
5477 * The list object contains the Win32 process handle at [0], and a file
5478 * count at [1], which is initialized to the total number of file
5479 * handles using that list.
5480 *
5481 * This function closes whichever handle it is passed, and decrements
5482 * the file count in the dictionary for the process handle pointed to
5483 * by this file. On the last close (when the file count reaches zero),
5484 * this function will wait for the child process and then return its
5485 * exit code as the result of the close() operation. This permits the
5486 * files to be closed in any order - it is always the close() of the
5487 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005488 *
5489 * NOTE: This function is currently called with the GIL released.
5490 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005491 */
Tim Peters736aa322000-09-01 06:51:24 +00005492
Fredrik Lundh56055a42000-07-23 19:47:12 +00005493static int _PyPclose(FILE *file)
5494{
Fredrik Lundh20318932000-07-26 17:29:12 +00005495 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005496 DWORD exit_code;
5497 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00005498 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5499 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005500#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005501 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005502#endif
5503
Fredrik Lundh20318932000-07-26 17:29:12 +00005504 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00005505 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00005506 */
5507 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005508#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005509 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005510#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005511 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005512 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5513 (procObj = PyDict_GetItem(_PyPopenProcs,
5514 fileObj)) != NULL &&
5515 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5516 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5517
5518 hProcess = PyLong_AsVoidPtr(hProcessObj);
5519 file_count = PyInt_AsLong(intObj);
5520
5521 if (file_count > 1) {
5522 /* Still other files referencing process */
5523 file_count--;
5524 PyList_SetItem(procObj,1,
5525 PyInt_FromLong(file_count));
5526 } else {
5527 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00005528 if (result != EOF &&
5529 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5530 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00005531 /* Possible truncation here in 16-bit environments, but
5532 * real exit codes are just the lower byte in any event.
5533 */
5534 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005535 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00005536 /* Indicate failure - this will cause the file object
5537 * to raise an I/O error and translate the last Win32
5538 * error code from errno. We do have a problem with
5539 * last errors that overlap the normal errno table,
5540 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005541 */
Fredrik Lundh20318932000-07-26 17:29:12 +00005542 if (result != EOF) {
5543 /* If the error wasn't from the fclose(), then
5544 * set errno for the file object error handling.
5545 */
5546 errno = GetLastError();
5547 }
5548 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005549 }
5550
5551 /* Free up the native handle at this point */
5552 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00005553 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005554
Mark Hammondb37a3732000-08-14 04:47:33 +00005555 /* Remove this file pointer from dictionary */
5556 PyDict_DelItem(_PyPopenProcs, fileObj);
5557
5558 if (PyDict_Size(_PyPopenProcs) == 0) {
5559 Py_DECREF(_PyPopenProcs);
5560 _PyPopenProcs = NULL;
5561 }
5562
5563 } /* if object retrieval ok */
5564
5565 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005566 } /* if _PyPopenProcs */
5567
Tim Peters736aa322000-09-01 06:51:24 +00005568#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005569 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005570#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005571 return result;
5572}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005573
5574#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005575static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005576posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005577{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005578 char *name;
5579 char *mode = "r";
5580 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00005581 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005582 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005583 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00005584 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00005585 /* Strip mode of binary or text modifiers */
5586 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5587 mode = "r";
5588 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5589 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00005590 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005591 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005592 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00005593 if (fp == NULL)
5594 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005595 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005596 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005597 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005598 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005599}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005600
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005601#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005602#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005603
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005604
Guido van Rossumb6775db1994-08-01 11:34:53 +00005605#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005606PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005607"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005608Set the current process's user id.");
5609
Barry Warsaw53699e91996-12-10 23:23:01 +00005610static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005611posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005612{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005613 long uid_arg;
5614 uid_t uid;
5615 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005616 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005617 uid = uid_arg;
5618 if (uid != uid_arg) {
5619 PyErr_SetString(PyExc_OverflowError, "user id too big");
5620 return NULL;
5621 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005622 if (setuid(uid) < 0)
5623 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005624 Py_INCREF(Py_None);
5625 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005626}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005627#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005628
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005629
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005630#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005631PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005632"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005633Set the current process's effective user id.");
5634
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005635static PyObject *
5636posix_seteuid (PyObject *self, PyObject *args)
5637{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005638 long euid_arg;
5639 uid_t euid;
5640 if (!PyArg_ParseTuple(args, "l", &euid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005641 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005642 euid = euid_arg;
5643 if (euid != euid_arg) {
5644 PyErr_SetString(PyExc_OverflowError, "user id too big");
5645 return NULL;
5646 }
5647 if (seteuid(euid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005648 return posix_error();
5649 } else {
5650 Py_INCREF(Py_None);
5651 return Py_None;
5652 }
5653}
5654#endif /* HAVE_SETEUID */
5655
5656#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005657PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005658"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005659Set the current process's effective group id.");
5660
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005661static PyObject *
5662posix_setegid (PyObject *self, PyObject *args)
5663{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005664 long egid_arg;
5665 gid_t egid;
5666 if (!PyArg_ParseTuple(args, "l", &egid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005667 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005668 egid = egid_arg;
5669 if (egid != egid_arg) {
5670 PyErr_SetString(PyExc_OverflowError, "group id too big");
5671 return NULL;
5672 }
5673 if (setegid(egid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005674 return posix_error();
5675 } else {
5676 Py_INCREF(Py_None);
5677 return Py_None;
5678 }
5679}
5680#endif /* HAVE_SETEGID */
5681
5682#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005683PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005684"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005685Set the current process's real and effective user ids.");
5686
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005687static PyObject *
5688posix_setreuid (PyObject *self, PyObject *args)
5689{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005690 long ruid_arg, euid_arg;
5691 uid_t ruid, euid;
5692 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005693 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005694 ruid = ruid_arg;
5695 euid = euid_arg;
5696 if (euid != euid_arg || ruid != ruid_arg) {
5697 PyErr_SetString(PyExc_OverflowError, "user id too big");
5698 return NULL;
5699 }
5700 if (setreuid(ruid, euid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005701 return posix_error();
5702 } else {
5703 Py_INCREF(Py_None);
5704 return Py_None;
5705 }
5706}
5707#endif /* HAVE_SETREUID */
5708
5709#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005710PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005711"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005712Set the current process's real and effective group ids.");
5713
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005714static PyObject *
5715posix_setregid (PyObject *self, PyObject *args)
5716{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005717 long rgid_arg, egid_arg;
5718 gid_t rgid, egid;
5719 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005720 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005721 rgid = rgid_arg;
5722 egid = egid_arg;
5723 if (egid != egid_arg || rgid != rgid_arg) {
5724 PyErr_SetString(PyExc_OverflowError, "group id too big");
5725 return NULL;
5726 }
5727 if (setregid(rgid, egid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005728 return posix_error();
5729 } else {
5730 Py_INCREF(Py_None);
5731 return Py_None;
5732 }
5733}
5734#endif /* HAVE_SETREGID */
5735
Guido van Rossumb6775db1994-08-01 11:34:53 +00005736#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005737PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005738"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005739Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005740
Barry Warsaw53699e91996-12-10 23:23:01 +00005741static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005742posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005743{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005744 long gid_arg;
5745 gid_t gid;
5746 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005747 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005748 gid = gid_arg;
5749 if (gid != gid_arg) {
5750 PyErr_SetString(PyExc_OverflowError, "group id too big");
5751 return NULL;
5752 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005753 if (setgid(gid) < 0)
5754 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005755 Py_INCREF(Py_None);
5756 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005757}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005758#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005759
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005760#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005761PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005762"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005763Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005764
5765static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005766posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005767{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005768 int i, len;
5769 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005770
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005771 if (!PySequence_Check(groups)) {
5772 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5773 return NULL;
5774 }
5775 len = PySequence_Size(groups);
5776 if (len > MAX_GROUPS) {
5777 PyErr_SetString(PyExc_ValueError, "too many groups");
5778 return NULL;
5779 }
5780 for(i = 0; i < len; i++) {
5781 PyObject *elem;
5782 elem = PySequence_GetItem(groups, i);
5783 if (!elem)
5784 return NULL;
5785 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005786 if (!PyLong_Check(elem)) {
5787 PyErr_SetString(PyExc_TypeError,
5788 "groups must be integers");
5789 Py_DECREF(elem);
5790 return NULL;
5791 } else {
5792 unsigned long x = PyLong_AsUnsignedLong(elem);
5793 if (PyErr_Occurred()) {
5794 PyErr_SetString(PyExc_TypeError,
5795 "group id too big");
5796 Py_DECREF(elem);
5797 return NULL;
5798 }
5799 grouplist[i] = x;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005800 /* read back to see if it fits in gid_t */
Georg Brandla13c2442005-11-22 19:30:31 +00005801 if (grouplist[i] != x) {
5802 PyErr_SetString(PyExc_TypeError,
5803 "group id too big");
5804 Py_DECREF(elem);
5805 return NULL;
5806 }
5807 }
5808 } else {
5809 long x = PyInt_AsLong(elem);
5810 grouplist[i] = x;
5811 if (grouplist[i] != x) {
5812 PyErr_SetString(PyExc_TypeError,
5813 "group id too big");
5814 Py_DECREF(elem);
5815 return NULL;
5816 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005817 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005818 Py_DECREF(elem);
5819 }
5820
5821 if (setgroups(len, grouplist) < 0)
5822 return posix_error();
5823 Py_INCREF(Py_None);
5824 return Py_None;
5825}
5826#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005827
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005828#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005829static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00005830wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00005831{
5832 PyObject *result;
5833 static PyObject *struct_rusage;
5834
5835 if (pid == -1)
5836 return posix_error();
5837
5838 if (struct_rusage == NULL) {
Christian Heimes000a0742008-01-03 22:16:32 +00005839 PyObject *m = PyImport_ImportModuleNoBlock("resource");
Neal Norwitz05a45592006-03-20 06:30:08 +00005840 if (m == NULL)
5841 return NULL;
5842 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5843 Py_DECREF(m);
5844 if (struct_rusage == NULL)
5845 return NULL;
5846 }
5847
5848 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5849 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5850 if (!result)
5851 return NULL;
5852
5853#ifndef doubletime
5854#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5855#endif
5856
5857 PyStructSequence_SET_ITEM(result, 0,
5858 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5859 PyStructSequence_SET_ITEM(result, 1,
5860 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5861#define SET_INT(result, index, value)\
5862 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5863 SET_INT(result, 2, ru->ru_maxrss);
5864 SET_INT(result, 3, ru->ru_ixrss);
5865 SET_INT(result, 4, ru->ru_idrss);
5866 SET_INT(result, 5, ru->ru_isrss);
5867 SET_INT(result, 6, ru->ru_minflt);
5868 SET_INT(result, 7, ru->ru_majflt);
5869 SET_INT(result, 8, ru->ru_nswap);
5870 SET_INT(result, 9, ru->ru_inblock);
5871 SET_INT(result, 10, ru->ru_oublock);
5872 SET_INT(result, 11, ru->ru_msgsnd);
5873 SET_INT(result, 12, ru->ru_msgrcv);
5874 SET_INT(result, 13, ru->ru_nsignals);
5875 SET_INT(result, 14, ru->ru_nvcsw);
5876 SET_INT(result, 15, ru->ru_nivcsw);
5877#undef SET_INT
5878
5879 if (PyErr_Occurred()) {
5880 Py_DECREF(result);
5881 return NULL;
5882 }
5883
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005884 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005885}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005886#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005887
5888#ifdef HAVE_WAIT3
5889PyDoc_STRVAR(posix_wait3__doc__,
5890"wait3(options) -> (pid, status, rusage)\n\n\
5891Wait for completion of a child process.");
5892
5893static PyObject *
5894posix_wait3(PyObject *self, PyObject *args)
5895{
Christian Heimesd491d712008-02-01 18:49:26 +00005896 pid_t pid;
5897 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005898 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005899 WAIT_TYPE status;
5900 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005901
5902 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5903 return NULL;
5904
5905 Py_BEGIN_ALLOW_THREADS
5906 pid = wait3(&status, options, &ru);
5907 Py_END_ALLOW_THREADS
5908
Neal Norwitzd5a37542006-03-20 06:48:34 +00005909 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005910}
5911#endif /* HAVE_WAIT3 */
5912
5913#ifdef HAVE_WAIT4
5914PyDoc_STRVAR(posix_wait4__doc__,
5915"wait4(pid, options) -> (pid, status, rusage)\n\n\
5916Wait for completion of a given child process.");
5917
5918static PyObject *
5919posix_wait4(PyObject *self, PyObject *args)
5920{
Christian Heimesd491d712008-02-01 18:49:26 +00005921 pid_t pid;
5922 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005923 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005924 WAIT_TYPE status;
5925 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005926
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005927 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
Neal Norwitz05a45592006-03-20 06:30:08 +00005928 return NULL;
5929
5930 Py_BEGIN_ALLOW_THREADS
5931 pid = wait4(pid, &status, options, &ru);
5932 Py_END_ALLOW_THREADS
5933
Neal Norwitzd5a37542006-03-20 06:48:34 +00005934 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005935}
5936#endif /* HAVE_WAIT4 */
5937
Guido van Rossumb6775db1994-08-01 11:34:53 +00005938#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005939PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005940"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005941Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005942
Barry Warsaw53699e91996-12-10 23:23:01 +00005943static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005944posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005945{
Christian Heimesd491d712008-02-01 18:49:26 +00005946 pid_t pid;
5947 int options;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005948 WAIT_TYPE status;
5949 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005950
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005951 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005952 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005953 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005954 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005955 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005956 if (pid == -1)
5957 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005958
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005959 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005960}
5961
Tim Petersab034fa2002-02-01 11:27:43 +00005962#elif defined(HAVE_CWAIT)
5963
5964/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005965PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005966"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005967"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005968
5969static PyObject *
5970posix_waitpid(PyObject *self, PyObject *args)
5971{
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005972 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005973 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005974
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005975 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
Tim Petersab034fa2002-02-01 11:27:43 +00005976 return NULL;
5977 Py_BEGIN_ALLOW_THREADS
5978 pid = _cwait(&status, pid, options);
5979 Py_END_ALLOW_THREADS
5980 if (pid == -1)
5981 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005982
5983 /* shift the status left a byte so this is more like the POSIX waitpid */
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005984 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005985}
5986#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005987
Guido van Rossumad0ee831995-03-01 10:34:45 +00005988#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005989PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005990"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005991Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005992
Barry Warsaw53699e91996-12-10 23:23:01 +00005993static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005994posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005995{
Christian Heimesd491d712008-02-01 18:49:26 +00005996 pid_t pid;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005997 WAIT_TYPE status;
5998 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005999
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006000 Py_BEGIN_ALLOW_THREADS
6001 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00006002 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00006003 if (pid == -1)
6004 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006005
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00006006 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006007}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006008#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006009
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006010
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006011PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006012"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006013Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006014
Barry Warsaw53699e91996-12-10 23:23:01 +00006015static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006016posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006017{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006018#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006019 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006020#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006021#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00006022 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006023#else
6024 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
6025#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006026#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006027}
6028
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006029
Guido van Rossumb6775db1994-08-01 11:34:53 +00006030#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006031PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006032"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006033Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006034
Barry Warsaw53699e91996-12-10 23:23:01 +00006035static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006036posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006037{
Ronald Oussoren10168f22006-10-22 10:45:18 +00006038 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00006039 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00006040 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006041 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006042#ifdef Py_USING_UNICODE
6043 int arg_is_unicode = 0;
6044#endif
6045
6046 if (!PyArg_ParseTuple(args, "et:readlink",
6047 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006048 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006049#ifdef Py_USING_UNICODE
6050 v = PySequence_GetItem(args, 0);
Neal Norwitz91a57212007-08-12 17:11:13 +00006051 if (v == NULL) {
6052 PyMem_Free(path);
6053 return NULL;
6054 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006055
6056 if (PyUnicode_Check(v)) {
6057 arg_is_unicode = 1;
6058 }
6059 Py_DECREF(v);
6060#endif
6061
Barry Warsaw53699e91996-12-10 23:23:01 +00006062 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00006063 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00006064 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006065 if (n < 0)
Neal Norwitz91a57212007-08-12 17:11:13 +00006066 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006067
Neal Norwitz91a57212007-08-12 17:11:13 +00006068 PyMem_Free(path);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006069 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006070#ifdef Py_USING_UNICODE
6071 if (arg_is_unicode) {
6072 PyObject *w;
6073
6074 w = PyUnicode_FromEncodedObject(v,
6075 Py_FileSystemDefaultEncoding,
6076 "strict");
6077 if (w != NULL) {
6078 Py_DECREF(v);
6079 v = w;
6080 }
6081 else {
6082 /* fall back to the original byte string, as
6083 discussed in patch #683592 */
6084 PyErr_Clear();
6085 }
6086 }
6087#endif
6088 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006089}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006090#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006091
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006092
Guido van Rossumb6775db1994-08-01 11:34:53 +00006093#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006094PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006095"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006096Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006097
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006098static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006099posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006100{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00006101 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006102}
6103#endif /* HAVE_SYMLINK */
6104
6105
6106#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006107#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6108static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006109system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006110{
6111 ULONG value = 0;
6112
6113 Py_BEGIN_ALLOW_THREADS
6114 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6115 Py_END_ALLOW_THREADS
6116
6117 return value;
6118}
6119
6120static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006121posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006122{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006123 /* Currently Only Uptime is Provided -- Others Later */
6124 return Py_BuildValue("ddddd",
6125 (double)0 /* t.tms_utime / HZ */,
6126 (double)0 /* t.tms_stime / HZ */,
6127 (double)0 /* t.tms_cutime / HZ */,
6128 (double)0 /* t.tms_cstime / HZ */,
6129 (double)system_uptime() / 1000);
6130}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006131#else /* not OS2 */
Martin v. Löwis03824e42008-12-29 18:17:34 +00006132#define NEED_TICKS_PER_SECOND
6133static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006134static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006135posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006136{
6137 struct tms t;
6138 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00006139 errno = 0;
6140 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00006141 if (c == (clock_t) -1)
6142 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006143 return Py_BuildValue("ddddd",
Martin v. Löwis03824e42008-12-29 18:17:34 +00006144 (double)t.tms_utime / ticks_per_second,
6145 (double)t.tms_stime / ticks_per_second,
6146 (double)t.tms_cutime / ticks_per_second,
6147 (double)t.tms_cstime / ticks_per_second,
6148 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006149}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006150#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006151#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006152
6153
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006154#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006155#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006156static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006157posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006158{
6159 FILETIME create, exit, kernel, user;
6160 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006161 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006162 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6163 /* The fields of a FILETIME structure are the hi and lo part
6164 of a 64-bit value expressed in 100 nanosecond units.
6165 1e7 is one second in such units; 1e-7 the inverse.
6166 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6167 */
Barry Warsaw53699e91996-12-10 23:23:01 +00006168 return Py_BuildValue(
6169 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006170 (double)(user.dwHighDateTime*429.4967296 +
6171 user.dwLowDateTime*1e-7),
Georg Brandl0a40ffb2008-02-13 07:20:22 +00006172 (double)(kernel.dwHighDateTime*429.4967296 +
6173 kernel.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00006174 (double)0,
6175 (double)0,
6176 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006177}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006178#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006179
6180#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006181PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006182"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006183Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006184#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006185
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006186
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006187#ifdef HAVE_GETSID
6188PyDoc_STRVAR(posix_getsid__doc__,
6189"getsid(pid) -> sid\n\n\
6190Call the system call getsid().");
6191
6192static PyObject *
6193posix_getsid(PyObject *self, PyObject *args)
6194{
Christian Heimesd491d712008-02-01 18:49:26 +00006195 pid_t pid;
6196 int sid;
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00006197 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006198 return NULL;
6199 sid = getsid(pid);
6200 if (sid < 0)
6201 return posix_error();
6202 return PyInt_FromLong((long)sid);
6203}
6204#endif /* HAVE_GETSID */
6205
6206
Guido van Rossumb6775db1994-08-01 11:34:53 +00006207#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006208PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006209"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006210Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006211
Barry Warsaw53699e91996-12-10 23:23:01 +00006212static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006213posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006214{
Guido van Rossum687dd131993-05-17 08:34:16 +00006215 if (setsid() < 0)
6216 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006217 Py_INCREF(Py_None);
6218 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006219}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006220#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006221
Guido van Rossumb6775db1994-08-01 11:34:53 +00006222#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006223PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006224"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006225Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006226
Barry Warsaw53699e91996-12-10 23:23:01 +00006227static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006228posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006229{
Christian Heimesd491d712008-02-01 18:49:26 +00006230 pid_t pid;
6231 int pgrp;
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00006232 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00006233 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006234 if (setpgid(pid, pgrp) < 0)
6235 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006236 Py_INCREF(Py_None);
6237 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006238}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006239#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006240
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006241
Guido van Rossumb6775db1994-08-01 11:34:53 +00006242#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006243PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006244"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006245Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006246
Barry Warsaw53699e91996-12-10 23:23:01 +00006247static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006248posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006249{
Christian Heimese6a80742008-02-03 19:51:13 +00006250 int fd;
6251 pid_t pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006252 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006253 return NULL;
6254 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006255 if (pgid < 0)
6256 return posix_error();
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00006257 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006258}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006259#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006260
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006261
Guido van Rossumb6775db1994-08-01 11:34:53 +00006262#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006263PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006264"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006265Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006266
Barry Warsaw53699e91996-12-10 23:23:01 +00006267static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006268posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006269{
6270 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006271 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006272 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006273 if (tcsetpgrp(fd, pgid) < 0)
6274 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00006275 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00006276 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006277}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006278#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006279
Guido van Rossum687dd131993-05-17 08:34:16 +00006280/* Functions acting on file descriptors */
6281
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006282PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006283"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006284Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006285
Barry Warsaw53699e91996-12-10 23:23:01 +00006286static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006287posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006288{
Mark Hammondef8b6542001-05-13 08:04:26 +00006289 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006290 int flag;
6291 int mode = 0777;
6292 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006293
6294#ifdef MS_WINDOWS
6295 if (unicode_file_names()) {
6296 PyUnicodeObject *po;
6297 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6298 Py_BEGIN_ALLOW_THREADS
6299 /* PyUnicode_AS_UNICODE OK without thread
6300 lock as it is a simple dereference. */
6301 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6302 Py_END_ALLOW_THREADS
6303 if (fd < 0)
6304 return posix_error();
6305 return PyInt_FromLong((long)fd);
6306 }
6307 /* Drop the argument parsing error as narrow strings
6308 are also valid. */
6309 PyErr_Clear();
6310 }
6311#endif
6312
Tim Peters5aa91602002-01-30 05:46:57 +00006313 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00006314 Py_FileSystemDefaultEncoding, &file,
6315 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00006316 return NULL;
6317
Barry Warsaw53699e91996-12-10 23:23:01 +00006318 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006319 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00006320 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006321 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00006322 return posix_error_with_allocated_filename(file);
6323 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00006324 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006325}
6326
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006327
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006328PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006329"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006330Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006331
Barry Warsaw53699e91996-12-10 23:23:01 +00006332static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006333posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006334{
6335 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006336 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006337 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006338 if (!_PyVerify_fd(fd))
6339 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006340 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006341 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006342 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006343 if (res < 0)
6344 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006345 Py_INCREF(Py_None);
6346 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006347}
6348
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006349
Georg Brandl309501a2008-01-19 20:22:13 +00006350PyDoc_STRVAR(posix_closerange__doc__,
6351"closerange(fd_low, fd_high)\n\n\
6352Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6353
6354static PyObject *
6355posix_closerange(PyObject *self, PyObject *args)
6356{
6357 int fd_from, fd_to, i;
6358 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6359 return NULL;
6360 Py_BEGIN_ALLOW_THREADS
6361 for (i = fd_from; i < fd_to; i++)
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006362 if (_PyVerify_fd(i))
6363 close(i);
Georg Brandl309501a2008-01-19 20:22:13 +00006364 Py_END_ALLOW_THREADS
6365 Py_RETURN_NONE;
6366}
6367
6368
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006369PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006370"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006371Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006372
Barry Warsaw53699e91996-12-10 23:23:01 +00006373static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006374posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006375{
6376 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006377 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006378 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006379 if (!_PyVerify_fd(fd))
6380 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006381 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006382 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006383 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006384 if (fd < 0)
6385 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006386 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006387}
6388
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006389
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006390PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006391"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006392Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006393
Barry Warsaw53699e91996-12-10 23:23:01 +00006394static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006395posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006396{
6397 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006398 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00006399 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006400 if (!_PyVerify_fd_dup2(fd, fd2))
6401 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006402 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006403 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00006404 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006405 if (res < 0)
6406 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006407 Py_INCREF(Py_None);
6408 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006409}
6410
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006411
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006412PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006413"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006414Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006415
Barry Warsaw53699e91996-12-10 23:23:01 +00006416static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006417posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006418{
6419 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006420#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006421 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006422#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00006423 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006424#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006425 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006426 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00006427 return NULL;
6428#ifdef SEEK_SET
6429 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6430 switch (how) {
6431 case 0: how = SEEK_SET; break;
6432 case 1: how = SEEK_CUR; break;
6433 case 2: how = SEEK_END; break;
6434 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006435#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006436
6437#if !defined(HAVE_LARGEFILE_SUPPORT)
6438 pos = PyInt_AsLong(posobj);
6439#else
6440 pos = PyLong_Check(posobj) ?
6441 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
6442#endif
6443 if (PyErr_Occurred())
6444 return NULL;
6445
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006446 if (!_PyVerify_fd(fd))
6447 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006448 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006449#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00006450 res = _lseeki64(fd, pos, how);
6451#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006452 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006453#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006454 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006455 if (res < 0)
6456 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006457
6458#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00006459 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006460#else
6461 return PyLong_FromLongLong(res);
6462#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006463}
6464
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006465
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006466PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006467"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006468Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006469
Barry Warsaw53699e91996-12-10 23:23:01 +00006470static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006471posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006472{
Guido van Rossum8bac5461996-06-11 18:38:48 +00006473 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00006474 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006475 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00006476 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00006477 if (size < 0) {
6478 errno = EINVAL;
6479 return posix_error();
6480 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006481 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006482 if (buffer == NULL)
6483 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006484 if (!_PyVerify_fd(fd))
6485 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006486 Py_BEGIN_ALLOW_THREADS
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006487 n = read(fd, PyString_AsString(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00006488 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00006489 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006490 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00006491 return posix_error();
6492 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00006493 if (n != size)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006494 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00006495 return buffer;
6496}
6497
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006498
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006499PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006500"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006501Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006502
Barry Warsaw53699e91996-12-10 23:23:01 +00006503static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006504posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006505{
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006506 Py_buffer pbuf;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006507 int fd;
6508 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006509
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006510 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
Guido van Rossum687dd131993-05-17 08:34:16 +00006511 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006512 if (!_PyVerify_fd(fd))
6513 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006514 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006515 size = write(fd, pbuf.buf, (size_t)pbuf.len);
Barry Warsaw53699e91996-12-10 23:23:01 +00006516 Py_END_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006517 PyBuffer_Release(&pbuf);
Guido van Rossum687dd131993-05-17 08:34:16 +00006518 if (size < 0)
6519 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006520 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006521}
6522
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006523
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006524PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006525"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006526Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006527
Barry Warsaw53699e91996-12-10 23:23:01 +00006528static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006529posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006530{
6531 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00006532 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00006533 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006534 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006535 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006536#ifdef __VMS
6537 /* on OpenVMS we must ensure that all bytes are written to the file */
6538 fsync(fd);
6539#endif
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006540 if (!_PyVerify_fd(fd))
6541 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006542 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00006543 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00006544 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00006545 if (res != 0) {
6546#ifdef MS_WINDOWS
6547 return win32_error("fstat", NULL);
6548#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006549 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006550#endif
6551 }
Tim Peters5aa91602002-01-30 05:46:57 +00006552
Martin v. Löwis14694662006-02-03 12:54:16 +00006553 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006554}
6555
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006556
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006557PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006558"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006559Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006560
Barry Warsaw53699e91996-12-10 23:23:01 +00006561static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006562posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006563{
Guido van Rossum687dd131993-05-17 08:34:16 +00006564 int fd;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006565 char *orgmode = "r";
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006566 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00006567 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00006568 PyObject *f;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006569 char *mode;
6570 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00006571 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006572
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006573 /* Sanitize mode. See fileobject.c */
6574 mode = PyMem_MALLOC(strlen(orgmode)+3);
6575 if (!mode) {
6576 PyErr_NoMemory();
6577 return NULL;
6578 }
6579 strcpy(mode, orgmode);
6580 if (_PyFile_SanitizeMode(mode)) {
6581 PyMem_FREE(mode);
Thomas Heller1f043e22002-11-07 16:00:59 +00006582 return NULL;
6583 }
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006584 if (!_PyVerify_fd(fd))
6585 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006586 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006587#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Georg Brandl54a188a2006-03-31 20:00:11 +00006588 if (mode[0] == 'a') {
6589 /* try to make sure the O_APPEND flag is set */
6590 int flags;
6591 flags = fcntl(fd, F_GETFL);
6592 if (flags != -1)
6593 fcntl(fd, F_SETFL, flags | O_APPEND);
6594 fp = fdopen(fd, mode);
Thomas Wouters2a9a6b02006-03-31 22:38:19 +00006595 if (fp == NULL && flags != -1)
Georg Brandl54a188a2006-03-31 20:00:11 +00006596 /* restore old mode if fdopen failed */
6597 fcntl(fd, F_SETFL, flags);
6598 } else {
6599 fp = fdopen(fd, mode);
6600 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006601#else
6602 fp = fdopen(fd, mode);
6603#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006604 Py_END_ALLOW_THREADS
Neal Norwitzd83eb312007-05-02 04:47:55 +00006605 PyMem_FREE(mode);
Guido van Rossum687dd131993-05-17 08:34:16 +00006606 if (fp == NULL)
6607 return posix_error();
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006608 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006609 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00006610 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006611 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006612}
6613
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006614PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006615"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006616Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006617connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006618
6619static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006620posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006621{
6622 int fd;
6623 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6624 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006625 if (!_PyVerify_fd(fd))
6626 return PyBool_FromLong(0);
Fred Drake106c1a02002-04-23 15:58:02 +00006627 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006628}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006629
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006630#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006631PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006632"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006633Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006634
Barry Warsaw53699e91996-12-10 23:23:01 +00006635static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006636posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006637{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006638#if defined(PYOS_OS2)
6639 HFILE read, write;
6640 APIRET rc;
6641
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006642 Py_BEGIN_ALLOW_THREADS
6643 rc = DosCreatePipe( &read, &write, 4096);
6644 Py_END_ALLOW_THREADS
6645 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006646 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006647
6648 return Py_BuildValue("(ii)", read, write);
6649#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006650#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00006651 int fds[2];
6652 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00006653 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006654 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00006655 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006656 if (res != 0)
6657 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006658 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006659#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00006660 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006661 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00006662 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00006663 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006664 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00006665 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00006666 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006667 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00006668 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6669 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006670 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006671#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006672#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006673}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006674#endif /* HAVE_PIPE */
6675
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006676
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006677#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006678PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006679"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006680Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006681
Barry Warsaw53699e91996-12-10 23:23:01 +00006682static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006683posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006684{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006685 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006686 int mode = 0666;
6687 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006688 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006689 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006690 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006691 res = mkfifo(filename, mode);
6692 Py_END_ALLOW_THREADS
6693 if (res < 0)
6694 return posix_error();
6695 Py_INCREF(Py_None);
6696 return Py_None;
6697}
6698#endif
6699
6700
Neal Norwitz11690112002-07-30 01:08:28 +00006701#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006702PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006703"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006704Create a filesystem node (file, device special file or named pipe)\n\
6705named filename. mode specifies both the permissions to use and the\n\
6706type of node to be created, being combined (bitwise OR) with one of\n\
6707S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006708device defines the newly created device special file (probably using\n\
6709os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006710
6711
6712static PyObject *
6713posix_mknod(PyObject *self, PyObject *args)
6714{
6715 char *filename;
6716 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006717 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006718 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00006719 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006720 return NULL;
6721 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006722 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00006723 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006724 if (res < 0)
6725 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006726 Py_INCREF(Py_None);
6727 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006728}
6729#endif
6730
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006731#ifdef HAVE_DEVICE_MACROS
6732PyDoc_STRVAR(posix_major__doc__,
6733"major(device) -> major number\n\
6734Extracts a device major number from a raw device number.");
6735
6736static PyObject *
6737posix_major(PyObject *self, PyObject *args)
6738{
6739 int device;
6740 if (!PyArg_ParseTuple(args, "i:major", &device))
6741 return NULL;
6742 return PyInt_FromLong((long)major(device));
6743}
6744
6745PyDoc_STRVAR(posix_minor__doc__,
6746"minor(device) -> minor number\n\
6747Extracts a device minor number from a raw device number.");
6748
6749static PyObject *
6750posix_minor(PyObject *self, PyObject *args)
6751{
6752 int device;
6753 if (!PyArg_ParseTuple(args, "i:minor", &device))
6754 return NULL;
6755 return PyInt_FromLong((long)minor(device));
6756}
6757
6758PyDoc_STRVAR(posix_makedev__doc__,
6759"makedev(major, minor) -> device number\n\
6760Composes a raw device number from the major and minor device numbers.");
6761
6762static PyObject *
6763posix_makedev(PyObject *self, PyObject *args)
6764{
6765 int major, minor;
6766 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6767 return NULL;
6768 return PyInt_FromLong((long)makedev(major, minor));
6769}
6770#endif /* device macros */
6771
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006772
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006773#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006774PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006775"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006776Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006777
Barry Warsaw53699e91996-12-10 23:23:01 +00006778static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006779posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006780{
6781 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006782 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006783 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006784 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006785
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006786 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006787 return NULL;
6788
6789#if !defined(HAVE_LARGEFILE_SUPPORT)
6790 length = PyInt_AsLong(lenobj);
6791#else
6792 length = PyLong_Check(lenobj) ?
6793 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6794#endif
6795 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006796 return NULL;
6797
Barry Warsaw53699e91996-12-10 23:23:01 +00006798 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006799 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006800 Py_END_ALLOW_THREADS
Benjamin Peterson943a6dd2009-01-19 15:51:27 +00006801 if (res < 0)
6802 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006803 Py_INCREF(Py_None);
6804 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006805}
6806#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006807
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006808#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006809PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006810"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006811Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006812
Fred Drake762e2061999-08-26 17:23:54 +00006813/* Save putenv() parameters as values here, so we can collect them when they
6814 * get re-set with another call for the same key. */
6815static PyObject *posix_putenv_garbage;
6816
Tim Peters5aa91602002-01-30 05:46:57 +00006817static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006818posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006819{
6820 char *s1, *s2;
Anthony Baxter64182fe2006-04-11 12:14:09 +00006821 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006822 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006823 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006824
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006825 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006826 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006827
6828#if defined(PYOS_OS2)
6829 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6830 APIRET rc;
6831
Guido van Rossumd48f2521997-12-05 22:19:34 +00006832 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6833 if (rc != NO_ERROR)
6834 return os2_error(rc);
6835
6836 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6837 APIRET rc;
6838
Guido van Rossumd48f2521997-12-05 22:19:34 +00006839 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6840 if (rc != NO_ERROR)
6841 return os2_error(rc);
6842 } else {
6843#endif
6844
Fred Drake762e2061999-08-26 17:23:54 +00006845 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006846 len = strlen(s1) + strlen(s2) + 2;
6847 /* len includes space for a trailing \0; the size arg to
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006848 PyString_FromStringAndSize does not count that */
6849 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006850 if (newstr == NULL)
6851 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006852 newenv = PyString_AS_STRING(newstr);
Anthony Baxter64182fe2006-04-11 12:14:09 +00006853 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6854 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006855 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006856 posix_error();
6857 return NULL;
6858 }
Fred Drake762e2061999-08-26 17:23:54 +00006859 /* Install the first arg and newstr in posix_putenv_garbage;
6860 * this will cause previous value to be collected. This has to
6861 * happen after the real putenv() call because the old value
6862 * was still accessible until then. */
6863 if (PyDict_SetItem(posix_putenv_garbage,
6864 PyTuple_GET_ITEM(args, 0), newstr)) {
6865 /* really not much we can do; just leak */
6866 PyErr_Clear();
6867 }
6868 else {
6869 Py_DECREF(newstr);
6870 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006871
6872#if defined(PYOS_OS2)
6873 }
6874#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006875 Py_INCREF(Py_None);
6876 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006877}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006878#endif /* putenv */
6879
Guido van Rossumc524d952001-10-19 01:31:59 +00006880#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006881PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006882"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006883Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006884
6885static PyObject *
6886posix_unsetenv(PyObject *self, PyObject *args)
6887{
6888 char *s1;
6889
6890 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6891 return NULL;
6892
6893 unsetenv(s1);
6894
6895 /* Remove the key from posix_putenv_garbage;
6896 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006897 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006898 * old value was still accessible until then.
6899 */
6900 if (PyDict_DelItem(posix_putenv_garbage,
6901 PyTuple_GET_ITEM(args, 0))) {
6902 /* really not much we can do; just leak */
6903 PyErr_Clear();
6904 }
6905
6906 Py_INCREF(Py_None);
6907 return Py_None;
6908}
6909#endif /* unsetenv */
6910
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006911PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006912"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006913Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006914
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006915static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006916posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006917{
6918 int code;
6919 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006920 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006921 return NULL;
6922 message = strerror(code);
6923 if (message == NULL) {
6924 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006925 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006926 return NULL;
6927 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006928 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006929}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006930
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006931
Guido van Rossumc9641791998-08-04 15:26:23 +00006932#ifdef HAVE_SYS_WAIT_H
6933
Fred Drake106c1a02002-04-23 15:58:02 +00006934#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006935PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006936"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006937Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006938
6939static PyObject *
6940posix_WCOREDUMP(PyObject *self, PyObject *args)
6941{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006942 WAIT_TYPE status;
6943 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006944
Neal Norwitzd5a37542006-03-20 06:48:34 +00006945 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006946 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006947
6948 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006949}
6950#endif /* WCOREDUMP */
6951
6952#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006953PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006954"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006955Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006956job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006957
6958static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006959posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006960{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006961 WAIT_TYPE status;
6962 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006963
Neal Norwitzd5a37542006-03-20 06:48:34 +00006964 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006965 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006966
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006967 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006968}
6969#endif /* WIFCONTINUED */
6970
Guido van Rossumc9641791998-08-04 15:26:23 +00006971#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006972PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006973"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006974Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006975
6976static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006977posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006978{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006979 WAIT_TYPE status;
6980 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006981
Neal Norwitzd5a37542006-03-20 06:48:34 +00006982 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006983 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006984
Fred Drake106c1a02002-04-23 15:58:02 +00006985 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006986}
6987#endif /* WIFSTOPPED */
6988
6989#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006990PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006991"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006992Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006993
6994static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006995posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006996{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006997 WAIT_TYPE status;
6998 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006999
Neal Norwitzd5a37542006-03-20 06:48:34 +00007000 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007001 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007002
Fred Drake106c1a02002-04-23 15:58:02 +00007003 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007004}
7005#endif /* WIFSIGNALED */
7006
7007#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007008PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007009"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007010Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007011system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007012
7013static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007014posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007015{
Neal Norwitzd5a37542006-03-20 06:48:34 +00007016 WAIT_TYPE status;
7017 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007018
Neal Norwitzd5a37542006-03-20 06:48:34 +00007019 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007020 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007021
Fred Drake106c1a02002-04-23 15:58:02 +00007022 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007023}
7024#endif /* WIFEXITED */
7025
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007026#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007027PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007028"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007029Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007030
7031static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007032posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007033{
Neal Norwitzd5a37542006-03-20 06:48:34 +00007034 WAIT_TYPE status;
7035 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007036
Neal Norwitzd5a37542006-03-20 06:48:34 +00007037 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007038 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007039
Guido van Rossumc9641791998-08-04 15:26:23 +00007040 return Py_BuildValue("i", WEXITSTATUS(status));
7041}
7042#endif /* WEXITSTATUS */
7043
7044#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007045PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007046"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007047Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007048value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007049
7050static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007051posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007052{
Neal Norwitzd5a37542006-03-20 06:48:34 +00007053 WAIT_TYPE status;
7054 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007055
Neal Norwitzd5a37542006-03-20 06:48:34 +00007056 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007057 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007058
Guido van Rossumc9641791998-08-04 15:26:23 +00007059 return Py_BuildValue("i", WTERMSIG(status));
7060}
7061#endif /* WTERMSIG */
7062
7063#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007064PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007065"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007066Return the signal that stopped the process that provided\n\
7067the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007068
7069static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007070posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007071{
Neal Norwitzd5a37542006-03-20 06:48:34 +00007072 WAIT_TYPE status;
7073 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007074
Neal Norwitzd5a37542006-03-20 06:48:34 +00007075 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007076 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007077
Guido van Rossumc9641791998-08-04 15:26:23 +00007078 return Py_BuildValue("i", WSTOPSIG(status));
7079}
7080#endif /* WSTOPSIG */
7081
7082#endif /* HAVE_SYS_WAIT_H */
7083
7084
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007085#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00007086#ifdef _SCO_DS
7087/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7088 needed definitions in sys/statvfs.h */
7089#define _SVID3
7090#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007091#include <sys/statvfs.h>
7092
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007093static PyObject*
7094_pystatvfs_fromstructstatvfs(struct statvfs st) {
7095 PyObject *v = PyStructSequence_New(&StatVFSResultType);
7096 if (v == NULL)
7097 return NULL;
7098
7099#if !defined(HAVE_LARGEFILE_SUPPORT)
7100 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7101 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7102 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7103 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7104 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7105 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7106 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7107 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
7108 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7109 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
7110#else
7111 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7112 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00007113 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007114 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00007115 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007116 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007117 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007118 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00007119 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007120 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00007121 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007122 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00007123 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007124 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007125 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7126 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
7127#endif
7128
7129 return v;
7130}
7131
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007132PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007133"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007134Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007135
7136static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007137posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007138{
7139 int fd, res;
7140 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007141
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007142 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00007143 return NULL;
7144 Py_BEGIN_ALLOW_THREADS
7145 res = fstatvfs(fd, &st);
7146 Py_END_ALLOW_THREADS
7147 if (res != 0)
7148 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007149
7150 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007151}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007152#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007153
7154
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007155#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007156#include <sys/statvfs.h>
7157
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007158PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007159"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007160Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007161
7162static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007163posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007164{
7165 char *path;
7166 int res;
7167 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007168 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00007169 return NULL;
7170 Py_BEGIN_ALLOW_THREADS
7171 res = statvfs(path, &st);
7172 Py_END_ALLOW_THREADS
7173 if (res != 0)
7174 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007175
7176 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007177}
7178#endif /* HAVE_STATVFS */
7179
7180
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007181#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007182PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007183"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007184Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007185The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007186or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007187
7188static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007189posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007190{
7191 PyObject *result = NULL;
7192 char *dir = NULL;
7193 char *pfx = NULL;
7194 char *name;
7195
7196 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
7197 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007198
7199 if (PyErr_Warn(PyExc_RuntimeWarning,
7200 "tempnam is a potential security risk to your program") < 0)
7201 return NULL;
7202
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007203#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007204 name = _tempnam(dir, pfx);
7205#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007206 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007207#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007208 if (name == NULL)
7209 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007210 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007211 free(name);
7212 return result;
7213}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007214#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007215
7216
7217#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007218PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007219"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007220Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007221
7222static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007223posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007224{
7225 FILE *fp;
7226
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007227 fp = tmpfile();
7228 if (fp == NULL)
7229 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007230 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007231}
7232#endif
7233
7234
7235#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007236PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007237"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007238Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007239
7240static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007241posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007242{
7243 char buffer[L_tmpnam];
7244 char *name;
7245
Skip Montanaro95618b52001-08-18 18:52:10 +00007246 if (PyErr_Warn(PyExc_RuntimeWarning,
7247 "tmpnam is a potential security risk to your program") < 0)
7248 return NULL;
7249
Greg Wardb48bc172000-03-01 21:51:56 +00007250#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007251 name = tmpnam_r(buffer);
7252#else
7253 name = tmpnam(buffer);
7254#endif
7255 if (name == NULL) {
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007256 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007257#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007258 "unexpected NULL from tmpnam_r"
7259#else
7260 "unexpected NULL from tmpnam"
7261#endif
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007262 );
7263 PyErr_SetObject(PyExc_OSError, err);
7264 Py_XDECREF(err);
7265 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007266 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007267 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007268}
7269#endif
7270
7271
Fred Drakec9680921999-12-13 16:37:25 +00007272/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7273 * It maps strings representing configuration variable names to
7274 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007275 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007276 * rarely-used constants. There are three separate tables that use
7277 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007278 *
7279 * This code is always included, even if none of the interfaces that
7280 * need it are included. The #if hackery needed to avoid it would be
7281 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007282 */
7283struct constdef {
7284 char *name;
7285 long value;
7286};
7287
Fred Drake12c6e2d1999-12-14 21:25:03 +00007288static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007289conv_confname(PyObject *arg, int *valuep, struct constdef *table,
7290 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007291{
7292 if (PyInt_Check(arg)) {
7293 *valuep = PyInt_AS_LONG(arg);
7294 return 1;
7295 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007296 if (PyString_Check(arg)) {
Fred Drake12c6e2d1999-12-14 21:25:03 +00007297 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00007298 size_t lo = 0;
7299 size_t mid;
7300 size_t hi = tablesize;
7301 int cmp;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007302 char *confname = PyString_AS_STRING(arg);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007303 while (lo < hi) {
7304 mid = (lo + hi) / 2;
7305 cmp = strcmp(confname, table[mid].name);
7306 if (cmp < 0)
7307 hi = mid;
7308 else if (cmp > 0)
7309 lo = mid + 1;
7310 else {
7311 *valuep = table[mid].value;
7312 return 1;
7313 }
7314 }
7315 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
7316 }
7317 else
7318 PyErr_SetString(PyExc_TypeError,
7319 "configuration names must be strings or integers");
7320 return 0;
7321}
7322
7323
7324#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7325static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007326#ifdef _PC_ABI_AIO_XFER_MAX
7327 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
7328#endif
7329#ifdef _PC_ABI_ASYNC_IO
7330 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
7331#endif
Fred Drakec9680921999-12-13 16:37:25 +00007332#ifdef _PC_ASYNC_IO
7333 {"PC_ASYNC_IO", _PC_ASYNC_IO},
7334#endif
7335#ifdef _PC_CHOWN_RESTRICTED
7336 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
7337#endif
7338#ifdef _PC_FILESIZEBITS
7339 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
7340#endif
7341#ifdef _PC_LAST
7342 {"PC_LAST", _PC_LAST},
7343#endif
7344#ifdef _PC_LINK_MAX
7345 {"PC_LINK_MAX", _PC_LINK_MAX},
7346#endif
7347#ifdef _PC_MAX_CANON
7348 {"PC_MAX_CANON", _PC_MAX_CANON},
7349#endif
7350#ifdef _PC_MAX_INPUT
7351 {"PC_MAX_INPUT", _PC_MAX_INPUT},
7352#endif
7353#ifdef _PC_NAME_MAX
7354 {"PC_NAME_MAX", _PC_NAME_MAX},
7355#endif
7356#ifdef _PC_NO_TRUNC
7357 {"PC_NO_TRUNC", _PC_NO_TRUNC},
7358#endif
7359#ifdef _PC_PATH_MAX
7360 {"PC_PATH_MAX", _PC_PATH_MAX},
7361#endif
7362#ifdef _PC_PIPE_BUF
7363 {"PC_PIPE_BUF", _PC_PIPE_BUF},
7364#endif
7365#ifdef _PC_PRIO_IO
7366 {"PC_PRIO_IO", _PC_PRIO_IO},
7367#endif
7368#ifdef _PC_SOCK_MAXBUF
7369 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
7370#endif
7371#ifdef _PC_SYNC_IO
7372 {"PC_SYNC_IO", _PC_SYNC_IO},
7373#endif
7374#ifdef _PC_VDISABLE
7375 {"PC_VDISABLE", _PC_VDISABLE},
7376#endif
7377};
7378
Fred Drakec9680921999-12-13 16:37:25 +00007379static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007380conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007381{
7382 return conv_confname(arg, valuep, posix_constants_pathconf,
7383 sizeof(posix_constants_pathconf)
7384 / sizeof(struct constdef));
7385}
7386#endif
7387
7388#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007389PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007390"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007391Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007392If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007393
7394static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007395posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007396{
7397 PyObject *result = NULL;
7398 int name, fd;
7399
Fred Drake12c6e2d1999-12-14 21:25:03 +00007400 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7401 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00007402 long limit;
7403
7404 errno = 0;
7405 limit = fpathconf(fd, name);
7406 if (limit == -1 && errno != 0)
7407 posix_error();
7408 else
7409 result = PyInt_FromLong(limit);
7410 }
7411 return result;
7412}
7413#endif
7414
7415
7416#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007417PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007418"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007419Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007420If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007421
7422static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007423posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007424{
7425 PyObject *result = NULL;
7426 int name;
7427 char *path;
7428
7429 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7430 conv_path_confname, &name)) {
7431 long limit;
7432
7433 errno = 0;
7434 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007435 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00007436 if (errno == EINVAL)
7437 /* could be a path or name problem */
7438 posix_error();
7439 else
7440 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007441 }
Fred Drakec9680921999-12-13 16:37:25 +00007442 else
7443 result = PyInt_FromLong(limit);
7444 }
7445 return result;
7446}
7447#endif
7448
7449#ifdef HAVE_CONFSTR
7450static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007451#ifdef _CS_ARCHITECTURE
7452 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
7453#endif
7454#ifdef _CS_HOSTNAME
7455 {"CS_HOSTNAME", _CS_HOSTNAME},
7456#endif
7457#ifdef _CS_HW_PROVIDER
7458 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
7459#endif
7460#ifdef _CS_HW_SERIAL
7461 {"CS_HW_SERIAL", _CS_HW_SERIAL},
7462#endif
7463#ifdef _CS_INITTAB_NAME
7464 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
7465#endif
Fred Drakec9680921999-12-13 16:37:25 +00007466#ifdef _CS_LFS64_CFLAGS
7467 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
7468#endif
7469#ifdef _CS_LFS64_LDFLAGS
7470 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
7471#endif
7472#ifdef _CS_LFS64_LIBS
7473 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
7474#endif
7475#ifdef _CS_LFS64_LINTFLAGS
7476 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
7477#endif
7478#ifdef _CS_LFS_CFLAGS
7479 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
7480#endif
7481#ifdef _CS_LFS_LDFLAGS
7482 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
7483#endif
7484#ifdef _CS_LFS_LIBS
7485 {"CS_LFS_LIBS", _CS_LFS_LIBS},
7486#endif
7487#ifdef _CS_LFS_LINTFLAGS
7488 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
7489#endif
Fred Draked86ed291999-12-15 15:34:33 +00007490#ifdef _CS_MACHINE
7491 {"CS_MACHINE", _CS_MACHINE},
7492#endif
Fred Drakec9680921999-12-13 16:37:25 +00007493#ifdef _CS_PATH
7494 {"CS_PATH", _CS_PATH},
7495#endif
Fred Draked86ed291999-12-15 15:34:33 +00007496#ifdef _CS_RELEASE
7497 {"CS_RELEASE", _CS_RELEASE},
7498#endif
7499#ifdef _CS_SRPC_DOMAIN
7500 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
7501#endif
7502#ifdef _CS_SYSNAME
7503 {"CS_SYSNAME", _CS_SYSNAME},
7504#endif
7505#ifdef _CS_VERSION
7506 {"CS_VERSION", _CS_VERSION},
7507#endif
Fred Drakec9680921999-12-13 16:37:25 +00007508#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
7509 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
7510#endif
7511#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
7512 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
7513#endif
7514#ifdef _CS_XBS5_ILP32_OFF32_LIBS
7515 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
7516#endif
7517#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
7518 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
7519#endif
7520#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
7521 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
7522#endif
7523#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
7524 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
7525#endif
7526#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
7527 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
7528#endif
7529#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
7530 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
7531#endif
7532#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7533 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
7534#endif
7535#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7536 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7537#endif
7538#ifdef _CS_XBS5_LP64_OFF64_LIBS
7539 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7540#endif
7541#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7542 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7543#endif
7544#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7545 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7546#endif
7547#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7548 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7549#endif
7550#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7551 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7552#endif
7553#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7554 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7555#endif
Fred Draked86ed291999-12-15 15:34:33 +00007556#ifdef _MIPS_CS_AVAIL_PROCESSORS
7557 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7558#endif
7559#ifdef _MIPS_CS_BASE
7560 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7561#endif
7562#ifdef _MIPS_CS_HOSTID
7563 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7564#endif
7565#ifdef _MIPS_CS_HW_NAME
7566 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7567#endif
7568#ifdef _MIPS_CS_NUM_PROCESSORS
7569 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7570#endif
7571#ifdef _MIPS_CS_OSREL_MAJ
7572 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7573#endif
7574#ifdef _MIPS_CS_OSREL_MIN
7575 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7576#endif
7577#ifdef _MIPS_CS_OSREL_PATCH
7578 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7579#endif
7580#ifdef _MIPS_CS_OS_NAME
7581 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7582#endif
7583#ifdef _MIPS_CS_OS_PROVIDER
7584 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7585#endif
7586#ifdef _MIPS_CS_PROCESSORS
7587 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7588#endif
7589#ifdef _MIPS_CS_SERIAL
7590 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7591#endif
7592#ifdef _MIPS_CS_VENDOR
7593 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7594#endif
Fred Drakec9680921999-12-13 16:37:25 +00007595};
7596
7597static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007598conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007599{
7600 return conv_confname(arg, valuep, posix_constants_confstr,
7601 sizeof(posix_constants_confstr)
7602 / sizeof(struct constdef));
7603}
7604
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007605PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007606"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007607Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007608
7609static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007610posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007611{
7612 PyObject *result = NULL;
7613 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007614 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007615
7616 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Skip Montanarodd527fc2006-04-18 00:49:49 +00007617 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007618
Fred Drakec9680921999-12-13 16:37:25 +00007619 errno = 0;
Skip Montanarodd527fc2006-04-18 00:49:49 +00007620 len = confstr(name, buffer, sizeof(buffer));
Skip Montanaro94785ef2006-04-20 01:29:48 +00007621 if (len == 0) {
7622 if (errno) {
7623 posix_error();
7624 }
7625 else {
7626 result = Py_None;
7627 Py_INCREF(Py_None);
7628 }
Fred Drakec9680921999-12-13 16:37:25 +00007629 }
7630 else {
Neal Norwitz0d21b1e2006-04-20 06:44:42 +00007631 if ((unsigned int)len >= sizeof(buffer)) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007632 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007633 if (result != NULL)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007634 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00007635 }
7636 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007637 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007638 }
7639 }
7640 return result;
7641}
7642#endif
7643
7644
7645#ifdef HAVE_SYSCONF
7646static struct constdef posix_constants_sysconf[] = {
7647#ifdef _SC_2_CHAR_TERM
7648 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7649#endif
7650#ifdef _SC_2_C_BIND
7651 {"SC_2_C_BIND", _SC_2_C_BIND},
7652#endif
7653#ifdef _SC_2_C_DEV
7654 {"SC_2_C_DEV", _SC_2_C_DEV},
7655#endif
7656#ifdef _SC_2_C_VERSION
7657 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7658#endif
7659#ifdef _SC_2_FORT_DEV
7660 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7661#endif
7662#ifdef _SC_2_FORT_RUN
7663 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7664#endif
7665#ifdef _SC_2_LOCALEDEF
7666 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7667#endif
7668#ifdef _SC_2_SW_DEV
7669 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7670#endif
7671#ifdef _SC_2_UPE
7672 {"SC_2_UPE", _SC_2_UPE},
7673#endif
7674#ifdef _SC_2_VERSION
7675 {"SC_2_VERSION", _SC_2_VERSION},
7676#endif
Fred Draked86ed291999-12-15 15:34:33 +00007677#ifdef _SC_ABI_ASYNCHRONOUS_IO
7678 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7679#endif
7680#ifdef _SC_ACL
7681 {"SC_ACL", _SC_ACL},
7682#endif
Fred Drakec9680921999-12-13 16:37:25 +00007683#ifdef _SC_AIO_LISTIO_MAX
7684 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7685#endif
Fred Drakec9680921999-12-13 16:37:25 +00007686#ifdef _SC_AIO_MAX
7687 {"SC_AIO_MAX", _SC_AIO_MAX},
7688#endif
7689#ifdef _SC_AIO_PRIO_DELTA_MAX
7690 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7691#endif
7692#ifdef _SC_ARG_MAX
7693 {"SC_ARG_MAX", _SC_ARG_MAX},
7694#endif
7695#ifdef _SC_ASYNCHRONOUS_IO
7696 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7697#endif
7698#ifdef _SC_ATEXIT_MAX
7699 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7700#endif
Fred Draked86ed291999-12-15 15:34:33 +00007701#ifdef _SC_AUDIT
7702 {"SC_AUDIT", _SC_AUDIT},
7703#endif
Fred Drakec9680921999-12-13 16:37:25 +00007704#ifdef _SC_AVPHYS_PAGES
7705 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7706#endif
7707#ifdef _SC_BC_BASE_MAX
7708 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7709#endif
7710#ifdef _SC_BC_DIM_MAX
7711 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7712#endif
7713#ifdef _SC_BC_SCALE_MAX
7714 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7715#endif
7716#ifdef _SC_BC_STRING_MAX
7717 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7718#endif
Fred Draked86ed291999-12-15 15:34:33 +00007719#ifdef _SC_CAP
7720 {"SC_CAP", _SC_CAP},
7721#endif
Fred Drakec9680921999-12-13 16:37:25 +00007722#ifdef _SC_CHARCLASS_NAME_MAX
7723 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7724#endif
7725#ifdef _SC_CHAR_BIT
7726 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7727#endif
7728#ifdef _SC_CHAR_MAX
7729 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7730#endif
7731#ifdef _SC_CHAR_MIN
7732 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7733#endif
7734#ifdef _SC_CHILD_MAX
7735 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7736#endif
7737#ifdef _SC_CLK_TCK
7738 {"SC_CLK_TCK", _SC_CLK_TCK},
7739#endif
7740#ifdef _SC_COHER_BLKSZ
7741 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7742#endif
7743#ifdef _SC_COLL_WEIGHTS_MAX
7744 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7745#endif
7746#ifdef _SC_DCACHE_ASSOC
7747 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7748#endif
7749#ifdef _SC_DCACHE_BLKSZ
7750 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7751#endif
7752#ifdef _SC_DCACHE_LINESZ
7753 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7754#endif
7755#ifdef _SC_DCACHE_SZ
7756 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7757#endif
7758#ifdef _SC_DCACHE_TBLKSZ
7759 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7760#endif
7761#ifdef _SC_DELAYTIMER_MAX
7762 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7763#endif
7764#ifdef _SC_EQUIV_CLASS_MAX
7765 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7766#endif
7767#ifdef _SC_EXPR_NEST_MAX
7768 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7769#endif
7770#ifdef _SC_FSYNC
7771 {"SC_FSYNC", _SC_FSYNC},
7772#endif
7773#ifdef _SC_GETGR_R_SIZE_MAX
7774 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7775#endif
7776#ifdef _SC_GETPW_R_SIZE_MAX
7777 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7778#endif
7779#ifdef _SC_ICACHE_ASSOC
7780 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7781#endif
7782#ifdef _SC_ICACHE_BLKSZ
7783 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7784#endif
7785#ifdef _SC_ICACHE_LINESZ
7786 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7787#endif
7788#ifdef _SC_ICACHE_SZ
7789 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7790#endif
Fred Draked86ed291999-12-15 15:34:33 +00007791#ifdef _SC_INF
7792 {"SC_INF", _SC_INF},
7793#endif
Fred Drakec9680921999-12-13 16:37:25 +00007794#ifdef _SC_INT_MAX
7795 {"SC_INT_MAX", _SC_INT_MAX},
7796#endif
7797#ifdef _SC_INT_MIN
7798 {"SC_INT_MIN", _SC_INT_MIN},
7799#endif
7800#ifdef _SC_IOV_MAX
7801 {"SC_IOV_MAX", _SC_IOV_MAX},
7802#endif
Fred Draked86ed291999-12-15 15:34:33 +00007803#ifdef _SC_IP_SECOPTS
7804 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7805#endif
Fred Drakec9680921999-12-13 16:37:25 +00007806#ifdef _SC_JOB_CONTROL
7807 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7808#endif
Fred Draked86ed291999-12-15 15:34:33 +00007809#ifdef _SC_KERN_POINTERS
7810 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7811#endif
7812#ifdef _SC_KERN_SIM
7813 {"SC_KERN_SIM", _SC_KERN_SIM},
7814#endif
Fred Drakec9680921999-12-13 16:37:25 +00007815#ifdef _SC_LINE_MAX
7816 {"SC_LINE_MAX", _SC_LINE_MAX},
7817#endif
7818#ifdef _SC_LOGIN_NAME_MAX
7819 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7820#endif
7821#ifdef _SC_LOGNAME_MAX
7822 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7823#endif
7824#ifdef _SC_LONG_BIT
7825 {"SC_LONG_BIT", _SC_LONG_BIT},
7826#endif
Fred Draked86ed291999-12-15 15:34:33 +00007827#ifdef _SC_MAC
7828 {"SC_MAC", _SC_MAC},
7829#endif
Fred Drakec9680921999-12-13 16:37:25 +00007830#ifdef _SC_MAPPED_FILES
7831 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7832#endif
7833#ifdef _SC_MAXPID
7834 {"SC_MAXPID", _SC_MAXPID},
7835#endif
7836#ifdef _SC_MB_LEN_MAX
7837 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7838#endif
7839#ifdef _SC_MEMLOCK
7840 {"SC_MEMLOCK", _SC_MEMLOCK},
7841#endif
7842#ifdef _SC_MEMLOCK_RANGE
7843 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7844#endif
7845#ifdef _SC_MEMORY_PROTECTION
7846 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7847#endif
7848#ifdef _SC_MESSAGE_PASSING
7849 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7850#endif
Fred Draked86ed291999-12-15 15:34:33 +00007851#ifdef _SC_MMAP_FIXED_ALIGNMENT
7852 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7853#endif
Fred Drakec9680921999-12-13 16:37:25 +00007854#ifdef _SC_MQ_OPEN_MAX
7855 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7856#endif
7857#ifdef _SC_MQ_PRIO_MAX
7858 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7859#endif
Fred Draked86ed291999-12-15 15:34:33 +00007860#ifdef _SC_NACLS_MAX
7861 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7862#endif
Fred Drakec9680921999-12-13 16:37:25 +00007863#ifdef _SC_NGROUPS_MAX
7864 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7865#endif
7866#ifdef _SC_NL_ARGMAX
7867 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7868#endif
7869#ifdef _SC_NL_LANGMAX
7870 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7871#endif
7872#ifdef _SC_NL_MSGMAX
7873 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7874#endif
7875#ifdef _SC_NL_NMAX
7876 {"SC_NL_NMAX", _SC_NL_NMAX},
7877#endif
7878#ifdef _SC_NL_SETMAX
7879 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7880#endif
7881#ifdef _SC_NL_TEXTMAX
7882 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7883#endif
7884#ifdef _SC_NPROCESSORS_CONF
7885 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7886#endif
7887#ifdef _SC_NPROCESSORS_ONLN
7888 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7889#endif
Fred Draked86ed291999-12-15 15:34:33 +00007890#ifdef _SC_NPROC_CONF
7891 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7892#endif
7893#ifdef _SC_NPROC_ONLN
7894 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7895#endif
Fred Drakec9680921999-12-13 16:37:25 +00007896#ifdef _SC_NZERO
7897 {"SC_NZERO", _SC_NZERO},
7898#endif
7899#ifdef _SC_OPEN_MAX
7900 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7901#endif
7902#ifdef _SC_PAGESIZE
7903 {"SC_PAGESIZE", _SC_PAGESIZE},
7904#endif
7905#ifdef _SC_PAGE_SIZE
7906 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7907#endif
7908#ifdef _SC_PASS_MAX
7909 {"SC_PASS_MAX", _SC_PASS_MAX},
7910#endif
7911#ifdef _SC_PHYS_PAGES
7912 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7913#endif
7914#ifdef _SC_PII
7915 {"SC_PII", _SC_PII},
7916#endif
7917#ifdef _SC_PII_INTERNET
7918 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7919#endif
7920#ifdef _SC_PII_INTERNET_DGRAM
7921 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7922#endif
7923#ifdef _SC_PII_INTERNET_STREAM
7924 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7925#endif
7926#ifdef _SC_PII_OSI
7927 {"SC_PII_OSI", _SC_PII_OSI},
7928#endif
7929#ifdef _SC_PII_OSI_CLTS
7930 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7931#endif
7932#ifdef _SC_PII_OSI_COTS
7933 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7934#endif
7935#ifdef _SC_PII_OSI_M
7936 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7937#endif
7938#ifdef _SC_PII_SOCKET
7939 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7940#endif
7941#ifdef _SC_PII_XTI
7942 {"SC_PII_XTI", _SC_PII_XTI},
7943#endif
7944#ifdef _SC_POLL
7945 {"SC_POLL", _SC_POLL},
7946#endif
7947#ifdef _SC_PRIORITIZED_IO
7948 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7949#endif
7950#ifdef _SC_PRIORITY_SCHEDULING
7951 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7952#endif
7953#ifdef _SC_REALTIME_SIGNALS
7954 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7955#endif
7956#ifdef _SC_RE_DUP_MAX
7957 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7958#endif
7959#ifdef _SC_RTSIG_MAX
7960 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7961#endif
7962#ifdef _SC_SAVED_IDS
7963 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7964#endif
7965#ifdef _SC_SCHAR_MAX
7966 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7967#endif
7968#ifdef _SC_SCHAR_MIN
7969 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7970#endif
7971#ifdef _SC_SELECT
7972 {"SC_SELECT", _SC_SELECT},
7973#endif
7974#ifdef _SC_SEMAPHORES
7975 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7976#endif
7977#ifdef _SC_SEM_NSEMS_MAX
7978 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7979#endif
7980#ifdef _SC_SEM_VALUE_MAX
7981 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7982#endif
7983#ifdef _SC_SHARED_MEMORY_OBJECTS
7984 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7985#endif
7986#ifdef _SC_SHRT_MAX
7987 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7988#endif
7989#ifdef _SC_SHRT_MIN
7990 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7991#endif
7992#ifdef _SC_SIGQUEUE_MAX
7993 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7994#endif
7995#ifdef _SC_SIGRT_MAX
7996 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7997#endif
7998#ifdef _SC_SIGRT_MIN
7999 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
8000#endif
Fred Draked86ed291999-12-15 15:34:33 +00008001#ifdef _SC_SOFTPOWER
8002 {"SC_SOFTPOWER", _SC_SOFTPOWER},
8003#endif
Fred Drakec9680921999-12-13 16:37:25 +00008004#ifdef _SC_SPLIT_CACHE
8005 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
8006#endif
8007#ifdef _SC_SSIZE_MAX
8008 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
8009#endif
8010#ifdef _SC_STACK_PROT
8011 {"SC_STACK_PROT", _SC_STACK_PROT},
8012#endif
8013#ifdef _SC_STREAM_MAX
8014 {"SC_STREAM_MAX", _SC_STREAM_MAX},
8015#endif
8016#ifdef _SC_SYNCHRONIZED_IO
8017 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
8018#endif
8019#ifdef _SC_THREADS
8020 {"SC_THREADS", _SC_THREADS},
8021#endif
8022#ifdef _SC_THREAD_ATTR_STACKADDR
8023 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
8024#endif
8025#ifdef _SC_THREAD_ATTR_STACKSIZE
8026 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
8027#endif
8028#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
8029 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
8030#endif
8031#ifdef _SC_THREAD_KEYS_MAX
8032 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
8033#endif
8034#ifdef _SC_THREAD_PRIORITY_SCHEDULING
8035 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
8036#endif
8037#ifdef _SC_THREAD_PRIO_INHERIT
8038 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
8039#endif
8040#ifdef _SC_THREAD_PRIO_PROTECT
8041 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
8042#endif
8043#ifdef _SC_THREAD_PROCESS_SHARED
8044 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
8045#endif
8046#ifdef _SC_THREAD_SAFE_FUNCTIONS
8047 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
8048#endif
8049#ifdef _SC_THREAD_STACK_MIN
8050 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
8051#endif
8052#ifdef _SC_THREAD_THREADS_MAX
8053 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
8054#endif
8055#ifdef _SC_TIMERS
8056 {"SC_TIMERS", _SC_TIMERS},
8057#endif
8058#ifdef _SC_TIMER_MAX
8059 {"SC_TIMER_MAX", _SC_TIMER_MAX},
8060#endif
8061#ifdef _SC_TTY_NAME_MAX
8062 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
8063#endif
8064#ifdef _SC_TZNAME_MAX
8065 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
8066#endif
8067#ifdef _SC_T_IOV_MAX
8068 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
8069#endif
8070#ifdef _SC_UCHAR_MAX
8071 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
8072#endif
8073#ifdef _SC_UINT_MAX
8074 {"SC_UINT_MAX", _SC_UINT_MAX},
8075#endif
8076#ifdef _SC_UIO_MAXIOV
8077 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
8078#endif
8079#ifdef _SC_ULONG_MAX
8080 {"SC_ULONG_MAX", _SC_ULONG_MAX},
8081#endif
8082#ifdef _SC_USHRT_MAX
8083 {"SC_USHRT_MAX", _SC_USHRT_MAX},
8084#endif
8085#ifdef _SC_VERSION
8086 {"SC_VERSION", _SC_VERSION},
8087#endif
8088#ifdef _SC_WORD_BIT
8089 {"SC_WORD_BIT", _SC_WORD_BIT},
8090#endif
8091#ifdef _SC_XBS5_ILP32_OFF32
8092 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
8093#endif
8094#ifdef _SC_XBS5_ILP32_OFFBIG
8095 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
8096#endif
8097#ifdef _SC_XBS5_LP64_OFF64
8098 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
8099#endif
8100#ifdef _SC_XBS5_LPBIG_OFFBIG
8101 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
8102#endif
8103#ifdef _SC_XOPEN_CRYPT
8104 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
8105#endif
8106#ifdef _SC_XOPEN_ENH_I18N
8107 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
8108#endif
8109#ifdef _SC_XOPEN_LEGACY
8110 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
8111#endif
8112#ifdef _SC_XOPEN_REALTIME
8113 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
8114#endif
8115#ifdef _SC_XOPEN_REALTIME_THREADS
8116 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
8117#endif
8118#ifdef _SC_XOPEN_SHM
8119 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
8120#endif
8121#ifdef _SC_XOPEN_UNIX
8122 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
8123#endif
8124#ifdef _SC_XOPEN_VERSION
8125 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
8126#endif
8127#ifdef _SC_XOPEN_XCU_VERSION
8128 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
8129#endif
8130#ifdef _SC_XOPEN_XPG2
8131 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
8132#endif
8133#ifdef _SC_XOPEN_XPG3
8134 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
8135#endif
8136#ifdef _SC_XOPEN_XPG4
8137 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
8138#endif
8139};
8140
8141static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008142conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008143{
8144 return conv_confname(arg, valuep, posix_constants_sysconf,
8145 sizeof(posix_constants_sysconf)
8146 / sizeof(struct constdef));
8147}
8148
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008149PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008150"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008151Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008152
8153static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008154posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008155{
8156 PyObject *result = NULL;
8157 int name;
8158
8159 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
8160 int value;
8161
8162 errno = 0;
8163 value = sysconf(name);
8164 if (value == -1 && errno != 0)
8165 posix_error();
8166 else
8167 result = PyInt_FromLong(value);
8168 }
8169 return result;
8170}
8171#endif
8172
8173
Fred Drakebec628d1999-12-15 18:31:10 +00008174/* This code is used to ensure that the tables of configuration value names
8175 * are in sorted order as required by conv_confname(), and also to build the
8176 * the exported dictionaries that are used to publish information about the
8177 * names available on the host platform.
8178 *
8179 * Sorting the table at runtime ensures that the table is properly ordered
8180 * when used, even for platforms we're not able to test on. It also makes
8181 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008182 */
Fred Drakebec628d1999-12-15 18:31:10 +00008183
8184static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008185cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008186{
8187 const struct constdef *c1 =
8188 (const struct constdef *) v1;
8189 const struct constdef *c2 =
8190 (const struct constdef *) v2;
8191
8192 return strcmp(c1->name, c2->name);
8193}
8194
8195static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008196setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008197 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008198{
Fred Drakebec628d1999-12-15 18:31:10 +00008199 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008200 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008201
8202 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8203 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008204 if (d == NULL)
8205 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008206
Barry Warsaw3155db32000-04-13 15:20:40 +00008207 for (i=0; i < tablesize; ++i) {
8208 PyObject *o = PyInt_FromLong(table[i].value);
8209 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8210 Py_XDECREF(o);
8211 Py_DECREF(d);
8212 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008213 }
Barry Warsaw3155db32000-04-13 15:20:40 +00008214 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008215 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008216 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008217}
8218
Fred Drakebec628d1999-12-15 18:31:10 +00008219/* Return -1 on failure, 0 on success. */
8220static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008221setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008222{
8223#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008224 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008225 sizeof(posix_constants_pathconf)
8226 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008227 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008228 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008229#endif
8230#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008231 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008232 sizeof(posix_constants_confstr)
8233 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008234 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008235 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008236#endif
8237#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008238 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008239 sizeof(posix_constants_sysconf)
8240 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008241 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008242 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008243#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008244 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008245}
Fred Draked86ed291999-12-15 15:34:33 +00008246
8247
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008248PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008249"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008250Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008251in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008252
8253static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008254posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008255{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008256 abort();
8257 /*NOTREACHED*/
8258 Py_FatalError("abort() called from Python code didn't abort!");
8259 return NULL;
8260}
Fred Drakebec628d1999-12-15 18:31:10 +00008261
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008262#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008263PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008264"startfile(filepath [, operation]) - Start a file with its associated\n\
8265application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008266\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008267When \"operation\" is not specified or \"open\", this acts like\n\
8268double-clicking the file in Explorer, or giving the file name as an\n\
8269argument to the DOS \"start\" command: the file is opened with whatever\n\
8270application (if any) its extension is associated.\n\
8271When another \"operation\" is given, it specifies what should be done with\n\
8272the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008273\n\
8274startfile returns as soon as the associated application is launched.\n\
8275There is no option to wait for the application to close, and no way\n\
8276to retrieve the application's exit status.\n\
8277\n\
8278The filepath is relative to the current directory. If you want to use\n\
8279an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008280the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008281
8282static PyObject *
8283win32_startfile(PyObject *self, PyObject *args)
8284{
8285 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00008286 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008287 HINSTANCE rc;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008288
Georg Brandlad89dc82006-04-03 12:26:26 +00008289 if (unicode_file_names()) {
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008290 PyObject *unipath, *woperation = NULL;
Georg Brandlad89dc82006-04-03 12:26:26 +00008291 if (!PyArg_ParseTuple(args, "U|s:startfile",
8292 &unipath, &operation)) {
8293 PyErr_Clear();
8294 goto normal;
8295 }
8296
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008297
8298 if (operation) {
8299 woperation = PyUnicode_DecodeASCII(operation,
8300 strlen(operation), NULL);
8301 if (!woperation) {
8302 PyErr_Clear();
8303 operation = NULL;
8304 goto normal;
8305 }
Georg Brandlad89dc82006-04-03 12:26:26 +00008306 }
8307
8308 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008309 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Georg Brandlad89dc82006-04-03 12:26:26 +00008310 PyUnicode_AS_UNICODE(unipath),
Georg Brandlad89dc82006-04-03 12:26:26 +00008311 NULL, NULL, SW_SHOWNORMAL);
8312 Py_END_ALLOW_THREADS
8313
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008314 Py_XDECREF(woperation);
Georg Brandlad89dc82006-04-03 12:26:26 +00008315 if (rc <= (HINSTANCE)32) {
8316 PyObject *errval = win32_error_unicode("startfile",
8317 PyUnicode_AS_UNICODE(unipath));
8318 return errval;
8319 }
8320 Py_INCREF(Py_None);
8321 return Py_None;
8322 }
Georg Brandlad89dc82006-04-03 12:26:26 +00008323
8324normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00008325 if (!PyArg_ParseTuple(args, "et|s:startfile",
8326 Py_FileSystemDefaultEncoding, &filepath,
8327 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00008328 return NULL;
8329 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00008330 rc = ShellExecute((HWND)0, operation, filepath,
8331 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008332 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00008333 if (rc <= (HINSTANCE)32) {
8334 PyObject *errval = win32_error("startfile", filepath);
8335 PyMem_Free(filepath);
8336 return errval;
8337 }
8338 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008339 Py_INCREF(Py_None);
8340 return Py_None;
8341}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008342#endif /* MS_WINDOWS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008343
Martin v. Löwis438b5342002-12-27 10:16:42 +00008344#ifdef HAVE_GETLOADAVG
8345PyDoc_STRVAR(posix_getloadavg__doc__,
8346"getloadavg() -> (float, float, float)\n\n\
8347Return the number of processes in the system run queue averaged over\n\
8348the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8349was unobtainable");
8350
8351static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008352posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008353{
8354 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008355 if (getloadavg(loadavg, 3)!=3) {
8356 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8357 return NULL;
8358 } else
8359 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
8360}
8361#endif
8362
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008363#ifdef MS_WINDOWS
8364
8365PyDoc_STRVAR(win32_urandom__doc__,
8366"urandom(n) -> str\n\n\
8367Return a string of n random bytes suitable for cryptographic use.");
8368
8369typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8370 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8371 DWORD dwFlags );
8372typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8373 BYTE *pbBuffer );
8374
8375static CRYPTGENRANDOM pCryptGenRandom = NULL;
Martin v. Löwisaf699dd2007-09-04 09:51:57 +00008376/* This handle is never explicitly released. Instead, the operating
8377 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008378static HCRYPTPROV hCryptProv = 0;
8379
Tim Peters4ad82172004-08-30 17:02:04 +00008380static PyObject*
8381win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008382{
Tim Petersd3115382004-08-30 17:36:46 +00008383 int howMany;
8384 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008385
Tim Peters4ad82172004-08-30 17:02:04 +00008386 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00008387 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00008388 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00008389 if (howMany < 0)
8390 return PyErr_Format(PyExc_ValueError,
8391 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008392
Tim Peters4ad82172004-08-30 17:02:04 +00008393 if (hCryptProv == 0) {
8394 HINSTANCE hAdvAPI32 = NULL;
8395 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008396
Tim Peters4ad82172004-08-30 17:02:04 +00008397 /* Obtain handle to the DLL containing CryptoAPI
8398 This should not fail */
8399 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8400 if(hAdvAPI32 == NULL)
8401 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008402
Tim Peters4ad82172004-08-30 17:02:04 +00008403 /* Obtain pointers to the CryptoAPI functions
8404 This will fail on some early versions of Win95 */
8405 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8406 hAdvAPI32,
8407 "CryptAcquireContextA");
8408 if (pCryptAcquireContext == NULL)
8409 return PyErr_Format(PyExc_NotImplementedError,
8410 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008411
Tim Peters4ad82172004-08-30 17:02:04 +00008412 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8413 hAdvAPI32, "CryptGenRandom");
Georg Brandl74bb7832006-09-06 06:03:59 +00008414 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00008415 return PyErr_Format(PyExc_NotImplementedError,
8416 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008417
Tim Peters4ad82172004-08-30 17:02:04 +00008418 /* Acquire context */
8419 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8420 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8421 return win32_error("CryptAcquireContext", NULL);
8422 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008423
Tim Peters4ad82172004-08-30 17:02:04 +00008424 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008425 result = PyString_FromStringAndSize(NULL, howMany);
Tim Petersd3115382004-08-30 17:36:46 +00008426 if (result != NULL) {
8427 /* Get random data */
Amaury Forgeot d'Arc74bd40d2008-07-21 21:06:46 +00008428 memset(PyString_AS_STRING(result), 0, howMany); /* zero seed */
Tim Petersd3115382004-08-30 17:36:46 +00008429 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008430 PyString_AS_STRING(result))) {
Tim Petersd3115382004-08-30 17:36:46 +00008431 Py_DECREF(result);
8432 return win32_error("CryptGenRandom", NULL);
8433 }
Tim Peters4ad82172004-08-30 17:02:04 +00008434 }
Tim Petersd3115382004-08-30 17:36:46 +00008435 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008436}
8437#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008438
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008439#ifdef __VMS
8440/* Use openssl random routine */
8441#include <openssl/rand.h>
8442PyDoc_STRVAR(vms_urandom__doc__,
8443"urandom(n) -> str\n\n\
8444Return a string of n random bytes suitable for cryptographic use.");
8445
8446static PyObject*
8447vms_urandom(PyObject *self, PyObject *args)
8448{
8449 int howMany;
8450 PyObject* result;
8451
8452 /* Read arguments */
8453 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8454 return NULL;
8455 if (howMany < 0)
8456 return PyErr_Format(PyExc_ValueError,
8457 "negative argument not allowed");
8458
8459 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008460 result = PyString_FromStringAndSize(NULL, howMany);
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008461 if (result != NULL) {
8462 /* Get random data */
8463 if (RAND_pseudo_bytes((unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008464 PyString_AS_STRING(result),
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008465 howMany) < 0) {
8466 Py_DECREF(result);
8467 return PyErr_Format(PyExc_ValueError,
8468 "RAND_pseudo_bytes");
8469 }
8470 }
8471 return result;
8472}
8473#endif
8474
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008475static PyMethodDef posix_methods[] = {
8476 {"access", posix_access, METH_VARARGS, posix_access__doc__},
8477#ifdef HAVE_TTYNAME
8478 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
8479#endif
8480 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008481#ifdef HAVE_CHFLAGS
8482 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
8483#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008484 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008485#ifdef HAVE_FCHMOD
8486 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
8487#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008488#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008489 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008490#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008491#ifdef HAVE_LCHMOD
8492 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
8493#endif /* HAVE_LCHMOD */
8494#ifdef HAVE_FCHOWN
8495 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
8496#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008497#ifdef HAVE_LCHFLAGS
8498 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
8499#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008500#ifdef HAVE_LCHOWN
8501 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
8502#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008503#ifdef HAVE_CHROOT
8504 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
8505#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008506#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00008507 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008508#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008509#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00008510 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008511#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00008512 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008513#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008514#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008515#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008516 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008517#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008518 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8519 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8520 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008521#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008522 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008523#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008524#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008525 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008526#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008527 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8528 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8529 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008530 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008531#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008532 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008533#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008534#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008535 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008536#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008537 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008538#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00008539 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008540#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008541 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8542 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8543 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008544#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00008545 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008546#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008547 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008548#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008549 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8550 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008551#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008552#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008553 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8554 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008555#if defined(PYOS_OS2)
8556 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8557 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8558#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008559#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008560#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00008561 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008562#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008563#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00008564 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008565#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008566#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00008567 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008568#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008569#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00008570 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008571#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008572#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008573 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008574#endif /* HAVE_GETEGID */
8575#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008576 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008577#endif /* HAVE_GETEUID */
8578#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008579 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008580#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008581#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00008582 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008583#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008584 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008585#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008586 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008587#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008588#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00008589 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008590#endif /* HAVE_GETPPID */
8591#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008592 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008593#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008594#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00008595 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008596#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008597#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008598 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008599#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008600#ifdef HAVE_KILLPG
8601 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8602#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008603#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008604 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008605#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008606#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008607 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008608#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008609 {"popen2", win32_popen2, METH_VARARGS},
8610 {"popen3", win32_popen3, METH_VARARGS},
8611 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00008612 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008613#else
8614#if defined(PYOS_OS2) && defined(PYCC_GCC)
8615 {"popen2", os2emx_popen2, METH_VARARGS},
8616 {"popen3", os2emx_popen3, METH_VARARGS},
8617 {"popen4", os2emx_popen4, METH_VARARGS},
8618#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008619#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008620#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008621#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008622 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008623#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008624#ifdef HAVE_SETEUID
8625 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8626#endif /* HAVE_SETEUID */
8627#ifdef HAVE_SETEGID
8628 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8629#endif /* HAVE_SETEGID */
8630#ifdef HAVE_SETREUID
8631 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8632#endif /* HAVE_SETREUID */
8633#ifdef HAVE_SETREGID
8634 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8635#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008636#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008637 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008638#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008639#ifdef HAVE_SETGROUPS
Georg Brandl96a8c392006-05-29 21:04:52 +00008640 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008641#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008642#ifdef HAVE_GETPGID
8643 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8644#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008645#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008646 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008647#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008648#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00008649 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008650#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008651#ifdef HAVE_WAIT3
8652 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8653#endif /* HAVE_WAIT3 */
8654#ifdef HAVE_WAIT4
8655 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8656#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008657#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008658 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008659#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008660#ifdef HAVE_GETSID
8661 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8662#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008663#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00008664 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008665#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008666#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008667 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008668#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008669#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008670 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008671#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008672#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008673 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008674#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008675 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8676 {"close", posix_close, METH_VARARGS, posix_close__doc__},
Georg Brandl309501a2008-01-19 20:22:13 +00008677 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008678 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8679 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8680 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8681 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8682 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8683 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8684 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00008685 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008686#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00008687 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008688#endif
8689#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008690 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008691#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008692#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008693 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8694#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008695#ifdef HAVE_DEVICE_MACROS
8696 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8697 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8698 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8699#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008700#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008701 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008702#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008703#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008704 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008705#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008706#ifdef HAVE_UNSETENV
8707 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8708#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008709 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008710#ifdef HAVE_FCHDIR
8711 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8712#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008713#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008714 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008715#endif
8716#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008717 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008718#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008719#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008720#ifdef WCOREDUMP
8721 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8722#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008723#ifdef WIFCONTINUED
8724 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8725#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008726#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008727 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008728#endif /* WIFSTOPPED */
8729#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008730 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008731#endif /* WIFSIGNALED */
8732#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008733 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008734#endif /* WIFEXITED */
8735#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008736 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008737#endif /* WEXITSTATUS */
8738#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008739 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008740#endif /* WTERMSIG */
8741#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008742 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008743#endif /* WSTOPSIG */
8744#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008745#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008746 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008747#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008748#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008749 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008750#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008751#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00008752 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008753#endif
8754#ifdef HAVE_TEMPNAM
8755 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8756#endif
8757#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00008758 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008759#endif
Fred Drakec9680921999-12-13 16:37:25 +00008760#ifdef HAVE_CONFSTR
8761 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8762#endif
8763#ifdef HAVE_SYSCONF
8764 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8765#endif
8766#ifdef HAVE_FPATHCONF
8767 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8768#endif
8769#ifdef HAVE_PATHCONF
8770 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8771#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008772 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008773#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00008774 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8775#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008776#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00008777 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008778#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008779 #ifdef MS_WINDOWS
8780 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8781 #endif
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008782 #ifdef __VMS
8783 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8784 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008785 {NULL, NULL} /* Sentinel */
8786};
8787
8788
Barry Warsaw4a342091996-12-19 23:50:02 +00008789static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008790ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008791{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008792 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008793}
8794
Guido van Rossumd48f2521997-12-05 22:19:34 +00008795#if defined(PYOS_OS2)
8796/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008797static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008798{
8799 APIRET rc;
8800 ULONG values[QSV_MAX+1];
8801 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008802 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008803
8804 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008805 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008806 Py_END_ALLOW_THREADS
8807
8808 if (rc != NO_ERROR) {
8809 os2_error(rc);
8810 return -1;
8811 }
8812
Fred Drake4d1e64b2002-04-15 19:40:07 +00008813 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8814 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8815 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8816 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8817 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8818 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8819 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008820
8821 switch (values[QSV_VERSION_MINOR]) {
8822 case 0: ver = "2.00"; break;
8823 case 10: ver = "2.10"; break;
8824 case 11: ver = "2.11"; break;
8825 case 30: ver = "3.00"; break;
8826 case 40: ver = "4.00"; break;
8827 case 50: ver = "5.00"; break;
8828 default:
Tim Peters885d4572001-11-28 20:27:42 +00008829 PyOS_snprintf(tmp, sizeof(tmp),
8830 "%d-%d", values[QSV_VERSION_MAJOR],
8831 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008832 ver = &tmp[0];
8833 }
8834
8835 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008836 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008837 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008838
8839 /* Add Indicator of Which Drive was Used to Boot the System */
8840 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8841 tmp[1] = ':';
8842 tmp[2] = '\0';
8843
Fred Drake4d1e64b2002-04-15 19:40:07 +00008844 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008845}
8846#endif
8847
Barry Warsaw4a342091996-12-19 23:50:02 +00008848static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008849all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008850{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008851#ifdef F_OK
8852 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008853#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008854#ifdef R_OK
8855 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008856#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008857#ifdef W_OK
8858 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008859#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008860#ifdef X_OK
8861 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008862#endif
Fred Drakec9680921999-12-13 16:37:25 +00008863#ifdef NGROUPS_MAX
8864 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8865#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008866#ifdef TMP_MAX
8867 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8868#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008869#ifdef WCONTINUED
8870 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8871#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008872#ifdef WNOHANG
8873 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008874#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008875#ifdef WUNTRACED
8876 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8877#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008878#ifdef O_RDONLY
8879 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8880#endif
8881#ifdef O_WRONLY
8882 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8883#endif
8884#ifdef O_RDWR
8885 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8886#endif
8887#ifdef O_NDELAY
8888 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8889#endif
8890#ifdef O_NONBLOCK
8891 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8892#endif
8893#ifdef O_APPEND
8894 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8895#endif
8896#ifdef O_DSYNC
8897 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8898#endif
8899#ifdef O_RSYNC
8900 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8901#endif
8902#ifdef O_SYNC
8903 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8904#endif
8905#ifdef O_NOCTTY
8906 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8907#endif
8908#ifdef O_CREAT
8909 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8910#endif
8911#ifdef O_EXCL
8912 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8913#endif
8914#ifdef O_TRUNC
8915 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8916#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008917#ifdef O_BINARY
8918 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8919#endif
8920#ifdef O_TEXT
8921 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8922#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008923#ifdef O_LARGEFILE
8924 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8925#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008926#ifdef O_SHLOCK
8927 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8928#endif
8929#ifdef O_EXLOCK
8930 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8931#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008932
Tim Peters5aa91602002-01-30 05:46:57 +00008933/* MS Windows */
8934#ifdef O_NOINHERIT
8935 /* Don't inherit in child processes. */
8936 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8937#endif
8938#ifdef _O_SHORT_LIVED
8939 /* Optimize for short life (keep in memory). */
8940 /* MS forgot to define this one with a non-underscore form too. */
8941 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8942#endif
8943#ifdef O_TEMPORARY
8944 /* Automatically delete when last handle is closed. */
8945 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8946#endif
8947#ifdef O_RANDOM
8948 /* Optimize for random access. */
8949 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8950#endif
8951#ifdef O_SEQUENTIAL
8952 /* Optimize for sequential access. */
8953 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8954#endif
8955
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008956/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00008957#ifdef O_ASYNC
8958 /* Send a SIGIO signal whenever input or output
8959 becomes available on file descriptor */
8960 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
8961#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008962#ifdef O_DIRECT
8963 /* Direct disk access. */
8964 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8965#endif
8966#ifdef O_DIRECTORY
8967 /* Must be a directory. */
8968 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8969#endif
8970#ifdef O_NOFOLLOW
8971 /* Do not follow links. */
8972 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8973#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00008974#ifdef O_NOATIME
8975 /* Do not update the access time. */
8976 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
8977#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008978
Barry Warsaw5676bd12003-01-07 20:57:09 +00008979 /* These come from sysexits.h */
8980#ifdef EX_OK
8981 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008982#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008983#ifdef EX_USAGE
8984 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008985#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008986#ifdef EX_DATAERR
8987 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008988#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008989#ifdef EX_NOINPUT
8990 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008991#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008992#ifdef EX_NOUSER
8993 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008994#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008995#ifdef EX_NOHOST
8996 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008997#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008998#ifdef EX_UNAVAILABLE
8999 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009000#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009001#ifdef EX_SOFTWARE
9002 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009003#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009004#ifdef EX_OSERR
9005 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009006#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009007#ifdef EX_OSFILE
9008 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009009#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009010#ifdef EX_CANTCREAT
9011 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009012#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009013#ifdef EX_IOERR
9014 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009015#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009016#ifdef EX_TEMPFAIL
9017 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009018#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009019#ifdef EX_PROTOCOL
9020 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009021#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009022#ifdef EX_NOPERM
9023 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009024#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009025#ifdef EX_CONFIG
9026 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009027#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009028#ifdef EX_NOTFOUND
9029 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009030#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009031
Guido van Rossum246bc171999-02-01 23:54:31 +00009032#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009033#if defined(PYOS_OS2) && defined(PYCC_GCC)
9034 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
9035 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
9036 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
9037 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
9038 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
9039 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
9040 if (ins(d, "P_PM", (long)P_PM)) return -1;
9041 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
9042 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
9043 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
9044 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
9045 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
9046 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
9047 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
9048 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
9049 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
9050 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
9051 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
9052 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
9053 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
9054#else
Guido van Rossum7d385291999-02-16 19:38:04 +00009055 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
9056 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
9057 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
9058 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
9059 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00009060#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009061#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00009062
Guido van Rossumd48f2521997-12-05 22:19:34 +00009063#if defined(PYOS_OS2)
9064 if (insertvalues(d)) return -1;
9065#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009066 return 0;
9067}
9068
9069
Tim Peters5aa91602002-01-30 05:46:57 +00009070#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009071#define INITFUNC initnt
9072#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009073
9074#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009075#define INITFUNC initos2
9076#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009077
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009078#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009079#define INITFUNC initposix
9080#define MODNAME "posix"
9081#endif
9082
Mark Hammondfe51c6d2002-08-02 02:27:13 +00009083PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009084INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00009085{
Fred Drake4d1e64b2002-04-15 19:40:07 +00009086 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00009087
Fred Drake4d1e64b2002-04-15 19:40:07 +00009088 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009089 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00009090 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00009091 if (m == NULL)
9092 return;
Tim Peters5aa91602002-01-30 05:46:57 +00009093
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009094 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009095 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00009096 Py_XINCREF(v);
9097 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009098 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00009099 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00009100
Fred Drake4d1e64b2002-04-15 19:40:07 +00009101 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00009102 return;
9103
Fred Drake4d1e64b2002-04-15 19:40:07 +00009104 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00009105 return;
9106
Fred Drake4d1e64b2002-04-15 19:40:07 +00009107 Py_INCREF(PyExc_OSError);
9108 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00009109
Guido van Rossumb3d39562000-01-31 18:41:26 +00009110#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00009111 if (posix_putenv_garbage == NULL)
9112 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00009113#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009114
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009115 if (!initialized) {
9116 stat_result_desc.name = MODNAME ".stat_result";
9117 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9118 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9119 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9120 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9121 structseq_new = StatResultType.tp_new;
9122 StatResultType.tp_new = statresult_new;
9123
9124 statvfs_result_desc.name = MODNAME ".statvfs_result";
9125 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009126#ifdef NEED_TICKS_PER_SECOND
9127# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
9128 ticks_per_second = sysconf(_SC_CLK_TCK);
9129# elif defined(HZ)
9130 ticks_per_second = HZ;
9131# else
9132 ticks_per_second = 60; /* magic fallback value; may be bogus */
9133# endif
9134#endif
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009135 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009136 Py_INCREF((PyObject*) &StatResultType);
9137 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00009138 Py_INCREF((PyObject*) &StatVFSResultType);
9139 PyModule_AddObject(m, "statvfs_result",
9140 (PyObject*) &StatVFSResultType);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009141 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009142
9143#ifdef __APPLE__
9144 /*
9145 * Step 2 of weak-linking support on Mac OS X.
9146 *
9147 * The code below removes functions that are not available on the
9148 * currently active platform.
9149 *
9150 * This block allow one to use a python binary that was build on
9151 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9152 * OSX 10.4.
9153 */
9154#ifdef HAVE_FSTATVFS
9155 if (fstatvfs == NULL) {
9156 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9157 return;
9158 }
9159 }
9160#endif /* HAVE_FSTATVFS */
9161
9162#ifdef HAVE_STATVFS
9163 if (statvfs == NULL) {
9164 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9165 return;
9166 }
9167 }
9168#endif /* HAVE_STATVFS */
9169
9170# ifdef HAVE_LCHOWN
9171 if (lchown == NULL) {
9172 if (PyObject_DelAttrString(m, "lchown") == -1) {
9173 return;
9174 }
9175 }
9176#endif /* HAVE_LCHOWN */
9177
9178
9179#endif /* __APPLE__ */
9180
Guido van Rossumb6775db1994-08-01 11:34:53 +00009181}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009182
9183#ifdef __cplusplus
9184}
9185#endif
9186
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009187