blob: 3d476b0c4f1a6aeb814a5378421e277649e04a7f [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{
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00003905 return PyLong_FromPid(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{
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00003959 pid_t pid, pgid;
3960 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
Martin v. Löwis606edc12002-06-13 21:09:11 +00003961 return NULL;
3962 pgid = getpgid(pid);
3963 if (pgid < 0)
3964 return posix_error();
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00003965 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00003966}
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
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00003979 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003980#else /* GETPGRP_HAVE_ARG */
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00003981 return PyLong_FromPid(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{
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00004015 return PyLong_FromPid(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{
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00004104 int sig;
4105 pid_t pgid;
4106 /* XXX some man pages make the `pgid` parameter an int, others
4107 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4108 take the same type. Moreover, pid_t is always at least as wide as
4109 int (else compilation of this module fails), which is safe. */
4110 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004111 return NULL;
4112 if (killpg(pgid, sig) == -1)
4113 return posix_error();
4114 Py_INCREF(Py_None);
4115 return Py_None;
4116}
4117#endif
4118
Guido van Rossumc0125471996-06-28 18:55:32 +00004119#ifdef HAVE_PLOCK
4120
4121#ifdef HAVE_SYS_LOCK_H
4122#include <sys/lock.h>
4123#endif
4124
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004125PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004126"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004127Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004128
Barry Warsaw53699e91996-12-10 23:23:01 +00004129static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004130posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004131{
4132 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004133 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00004134 return NULL;
4135 if (plock(op) == -1)
4136 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004137 Py_INCREF(Py_None);
4138 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004139}
4140#endif
4141
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004142
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004143#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004144PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004145"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004146Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004147
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004148#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004149#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004150static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004151async_system(const char *command)
4152{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004153 char errormsg[256], args[1024];
4154 RESULTCODES rcodes;
4155 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004156
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004157 char *shell = getenv("COMSPEC");
4158 if (!shell)
4159 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004160
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004161 /* avoid overflowing the argument buffer */
4162 if (strlen(shell) + 3 + strlen(command) >= 1024)
4163 return ERROR_NOT_ENOUGH_MEMORY
4164
4165 args[0] = '\0';
4166 strcat(args, shell);
4167 strcat(args, "/c ");
4168 strcat(args, command);
4169
4170 /* execute asynchronously, inheriting the environment */
4171 rc = DosExecPgm(errormsg,
4172 sizeof(errormsg),
4173 EXEC_ASYNC,
4174 args,
4175 NULL,
4176 &rcodes,
4177 shell);
4178 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004179}
4180
Guido van Rossumd48f2521997-12-05 22:19:34 +00004181static FILE *
4182popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004183{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004184 int oldfd, tgtfd;
4185 HFILE pipeh[2];
4186 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004187
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004188 /* mode determines which of stdin or stdout is reconnected to
4189 * the pipe to the child
4190 */
4191 if (strchr(mode, 'r') != NULL) {
4192 tgt_fd = 1; /* stdout */
4193 } else if (strchr(mode, 'w')) {
4194 tgt_fd = 0; /* stdin */
4195 } else {
4196 *err = ERROR_INVALID_ACCESS;
4197 return NULL;
4198 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004199
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00004200 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004201 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4202 *err = rc;
4203 return NULL;
4204 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004205
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004206 /* prevent other threads accessing stdio */
4207 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004208
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004209 /* reconnect stdio and execute child */
4210 oldfd = dup(tgtfd);
4211 close(tgtfd);
4212 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4213 DosClose(pipeh[tgtfd]);
4214 rc = async_system(command);
4215 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004216
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004217 /* restore stdio */
4218 dup2(oldfd, tgtfd);
4219 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004220
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004221 /* allow other threads access to stdio */
4222 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004223
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004224 /* if execution of child was successful return file stream */
4225 if (rc == NO_ERROR)
4226 return fdopen(pipeh[1 - tgtfd], mode);
4227 else {
4228 DosClose(pipeh[1 - tgtfd]);
4229 *err = rc;
4230 return NULL;
4231 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004232}
4233
4234static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004235posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004236{
4237 char *name;
4238 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00004239 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004240 FILE *fp;
4241 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004242 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004243 return NULL;
4244 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00004245 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004246 Py_END_ALLOW_THREADS
4247 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004248 return os2_error(err);
4249
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004250 f = PyFile_FromFile(fp, name, mode, fclose);
4251 if (f != NULL)
4252 PyFile_SetBufSize(f, bufsize);
4253 return f;
4254}
4255
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004256#elif defined(PYCC_GCC)
4257
4258/* standard posix version of popen() support */
4259static PyObject *
4260posix_popen(PyObject *self, PyObject *args)
4261{
4262 char *name;
4263 char *mode = "r";
4264 int bufsize = -1;
4265 FILE *fp;
4266 PyObject *f;
4267 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4268 return NULL;
4269 Py_BEGIN_ALLOW_THREADS
4270 fp = popen(name, mode);
4271 Py_END_ALLOW_THREADS
4272 if (fp == NULL)
4273 return posix_error();
4274 f = PyFile_FromFile(fp, name, mode, pclose);
4275 if (f != NULL)
4276 PyFile_SetBufSize(f, bufsize);
4277 return f;
4278}
4279
4280/* fork() under OS/2 has lots'o'warts
4281 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4282 * most of this code is a ripoff of the win32 code, but using the
4283 * capabilities of EMX's C library routines
4284 */
4285
4286/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4287#define POPEN_1 1
4288#define POPEN_2 2
4289#define POPEN_3 3
4290#define POPEN_4 4
4291
4292static PyObject *_PyPopen(char *, int, int, int);
4293static int _PyPclose(FILE *file);
4294
4295/*
4296 * Internal dictionary mapping popen* file pointers to process handles,
4297 * for use when retrieving the process exit code. See _PyPclose() below
4298 * for more information on this dictionary's use.
4299 */
4300static PyObject *_PyPopenProcs = NULL;
4301
4302/* os2emx version of popen2()
4303 *
4304 * The result of this function is a pipe (file) connected to the
4305 * process's stdin, and a pipe connected to the process's stdout.
4306 */
4307
4308static PyObject *
4309os2emx_popen2(PyObject *self, PyObject *args)
4310{
4311 PyObject *f;
4312 int tm=0;
4313
4314 char *cmdstring;
4315 char *mode = "t";
4316 int bufsize = -1;
4317 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4318 return NULL;
4319
4320 if (*mode == 't')
4321 tm = O_TEXT;
4322 else if (*mode != 'b') {
4323 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4324 return NULL;
4325 } else
4326 tm = O_BINARY;
4327
4328 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
4329
4330 return f;
4331}
4332
4333/*
4334 * Variation on os2emx.popen2
4335 *
4336 * The result of this function is 3 pipes - the process's stdin,
4337 * stdout and stderr
4338 */
4339
4340static PyObject *
4341os2emx_popen3(PyObject *self, PyObject *args)
4342{
4343 PyObject *f;
4344 int tm = 0;
4345
4346 char *cmdstring;
4347 char *mode = "t";
4348 int bufsize = -1;
4349 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4350 return NULL;
4351
4352 if (*mode == 't')
4353 tm = O_TEXT;
4354 else if (*mode != 'b') {
4355 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4356 return NULL;
4357 } else
4358 tm = O_BINARY;
4359
4360 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
4361
4362 return f;
4363}
4364
4365/*
4366 * Variation on os2emx.popen2
4367 *
Tim Peters11b23062003-04-23 02:39:17 +00004368 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004369 * and stdout+stderr combined as a single pipe.
4370 */
4371
4372static PyObject *
4373os2emx_popen4(PyObject *self, PyObject *args)
4374{
4375 PyObject *f;
4376 int tm = 0;
4377
4378 char *cmdstring;
4379 char *mode = "t";
4380 int bufsize = -1;
4381 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4382 return NULL;
4383
4384 if (*mode == 't')
4385 tm = O_TEXT;
4386 else if (*mode != 'b') {
4387 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4388 return NULL;
4389 } else
4390 tm = O_BINARY;
4391
4392 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
4393
4394 return f;
4395}
4396
4397/* a couple of structures for convenient handling of multiple
4398 * file handles and pipes
4399 */
4400struct file_ref
4401{
4402 int handle;
4403 int flags;
4404};
4405
4406struct pipe_ref
4407{
4408 int rd;
4409 int wr;
4410};
4411
4412/* The following code is derived from the win32 code */
4413
4414static PyObject *
4415_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4416{
4417 struct file_ref stdio[3];
4418 struct pipe_ref p_fd[3];
4419 FILE *p_s[3];
Christian Heimesd491d712008-02-01 18:49:26 +00004420 int file_count, i, pipe_err;
4421 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004422 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4423 PyObject *f, *p_f[3];
4424
4425 /* file modes for subsequent fdopen's on pipe handles */
4426 if (mode == O_TEXT)
4427 {
4428 rd_mode = "rt";
4429 wr_mode = "wt";
4430 }
4431 else
4432 {
4433 rd_mode = "rb";
4434 wr_mode = "wb";
4435 }
4436
4437 /* prepare shell references */
4438 if ((shell = getenv("EMXSHELL")) == NULL)
4439 if ((shell = getenv("COMSPEC")) == NULL)
4440 {
4441 errno = ENOENT;
4442 return posix_error();
4443 }
4444
4445 sh_name = _getname(shell);
4446 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4447 opt = "/c";
4448 else
4449 opt = "-c";
4450
4451 /* save current stdio fds + their flags, and set not inheritable */
4452 i = pipe_err = 0;
4453 while (pipe_err >= 0 && i < 3)
4454 {
4455 pipe_err = stdio[i].handle = dup(i);
4456 stdio[i].flags = fcntl(i, F_GETFD, 0);
4457 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4458 i++;
4459 }
4460 if (pipe_err < 0)
4461 {
4462 /* didn't get them all saved - clean up and bail out */
4463 int saved_err = errno;
4464 while (i-- > 0)
4465 {
4466 close(stdio[i].handle);
4467 }
4468 errno = saved_err;
4469 return posix_error();
4470 }
4471
4472 /* create pipe ends */
4473 file_count = 2;
4474 if (n == POPEN_3)
4475 file_count = 3;
4476 i = pipe_err = 0;
4477 while ((pipe_err == 0) && (i < file_count))
4478 pipe_err = pipe((int *)&p_fd[i++]);
4479 if (pipe_err < 0)
4480 {
4481 /* didn't get them all made - clean up and bail out */
4482 while (i-- > 0)
4483 {
4484 close(p_fd[i].wr);
4485 close(p_fd[i].rd);
4486 }
4487 errno = EPIPE;
4488 return posix_error();
4489 }
4490
4491 /* change the actual standard IO streams over temporarily,
4492 * making the retained pipe ends non-inheritable
4493 */
4494 pipe_err = 0;
4495
4496 /* - stdin */
4497 if (dup2(p_fd[0].rd, 0) == 0)
4498 {
4499 close(p_fd[0].rd);
4500 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4501 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4502 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4503 {
4504 close(p_fd[0].wr);
4505 pipe_err = -1;
4506 }
4507 }
4508 else
4509 {
4510 pipe_err = -1;
4511 }
4512
4513 /* - stdout */
4514 if (pipe_err == 0)
4515 {
4516 if (dup2(p_fd[1].wr, 1) == 1)
4517 {
4518 close(p_fd[1].wr);
4519 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4520 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4521 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4522 {
4523 close(p_fd[1].rd);
4524 pipe_err = -1;
4525 }
4526 }
4527 else
4528 {
4529 pipe_err = -1;
4530 }
4531 }
4532
4533 /* - stderr, as required */
4534 if (pipe_err == 0)
4535 switch (n)
4536 {
4537 case POPEN_3:
4538 {
4539 if (dup2(p_fd[2].wr, 2) == 2)
4540 {
4541 close(p_fd[2].wr);
4542 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4543 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4544 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4545 {
4546 close(p_fd[2].rd);
4547 pipe_err = -1;
4548 }
4549 }
4550 else
4551 {
4552 pipe_err = -1;
4553 }
4554 break;
4555 }
4556
4557 case POPEN_4:
4558 {
4559 if (dup2(1, 2) != 2)
4560 {
4561 pipe_err = -1;
4562 }
4563 break;
4564 }
4565 }
4566
4567 /* spawn the child process */
4568 if (pipe_err == 0)
4569 {
4570 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4571 if (pipe_pid == -1)
4572 {
4573 pipe_err = -1;
4574 }
4575 else
4576 {
4577 /* save the PID into the FILE structure
4578 * NOTE: this implementation doesn't actually
4579 * take advantage of this, but do it for
4580 * completeness - AIM Apr01
4581 */
4582 for (i = 0; i < file_count; i++)
4583 p_s[i]->_pid = pipe_pid;
4584 }
4585 }
4586
4587 /* reset standard IO to normal */
4588 for (i = 0; i < 3; i++)
4589 {
4590 dup2(stdio[i].handle, i);
4591 fcntl(i, F_SETFD, stdio[i].flags);
4592 close(stdio[i].handle);
4593 }
4594
4595 /* if any remnant problems, clean up and bail out */
4596 if (pipe_err < 0)
4597 {
4598 for (i = 0; i < 3; i++)
4599 {
4600 close(p_fd[i].rd);
4601 close(p_fd[i].wr);
4602 }
4603 errno = EPIPE;
4604 return posix_error_with_filename(cmdstring);
4605 }
4606
4607 /* build tuple of file objects to return */
4608 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4609 PyFile_SetBufSize(p_f[0], bufsize);
4610 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4611 PyFile_SetBufSize(p_f[1], bufsize);
4612 if (n == POPEN_3)
4613 {
4614 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4615 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004616 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004617 }
4618 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004619 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004620
4621 /*
4622 * Insert the files we've created into the process dictionary
4623 * all referencing the list with the process handle and the
4624 * initial number of files (see description below in _PyPclose).
4625 * Since if _PyPclose later tried to wait on a process when all
4626 * handles weren't closed, it could create a deadlock with the
4627 * child, we spend some energy here to try to ensure that we
4628 * either insert all file handles into the dictionary or none
4629 * at all. It's a little clumsy with the various popen modes
4630 * and variable number of files involved.
4631 */
4632 if (!_PyPopenProcs)
4633 {
4634 _PyPopenProcs = PyDict_New();
4635 }
4636
4637 if (_PyPopenProcs)
4638 {
4639 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4640 int ins_rc[3];
4641
4642 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4643 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4644
4645 procObj = PyList_New(2);
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00004646 pidObj = PyLong_FromPid(pipe_pid);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004647 intObj = PyInt_FromLong((long) file_count);
4648
4649 if (procObj && pidObj && intObj)
4650 {
4651 PyList_SetItem(procObj, 0, pidObj);
4652 PyList_SetItem(procObj, 1, intObj);
4653
4654 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4655 if (fileObj[0])
4656 {
4657 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4658 fileObj[0],
4659 procObj);
4660 }
4661 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4662 if (fileObj[1])
4663 {
4664 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4665 fileObj[1],
4666 procObj);
4667 }
4668 if (file_count >= 3)
4669 {
4670 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4671 if (fileObj[2])
4672 {
4673 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4674 fileObj[2],
4675 procObj);
4676 }
4677 }
4678
4679 if (ins_rc[0] < 0 || !fileObj[0] ||
4680 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4681 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4682 {
4683 /* Something failed - remove any dictionary
4684 * entries that did make it.
4685 */
4686 if (!ins_rc[0] && fileObj[0])
4687 {
4688 PyDict_DelItem(_PyPopenProcs,
4689 fileObj[0]);
4690 }
4691 if (!ins_rc[1] && fileObj[1])
4692 {
4693 PyDict_DelItem(_PyPopenProcs,
4694 fileObj[1]);
4695 }
4696 if (!ins_rc[2] && fileObj[2])
4697 {
4698 PyDict_DelItem(_PyPopenProcs,
4699 fileObj[2]);
4700 }
4701 }
4702 }
Tim Peters11b23062003-04-23 02:39:17 +00004703
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004704 /*
4705 * Clean up our localized references for the dictionary keys
4706 * and value since PyDict_SetItem will Py_INCREF any copies
4707 * that got placed in the dictionary.
4708 */
4709 Py_XDECREF(procObj);
4710 Py_XDECREF(fileObj[0]);
4711 Py_XDECREF(fileObj[1]);
4712 Py_XDECREF(fileObj[2]);
4713 }
4714
4715 /* Child is launched. */
4716 return f;
4717}
4718
4719/*
4720 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4721 * exit code for the child process and return as a result of the close.
4722 *
4723 * This function uses the _PyPopenProcs dictionary in order to map the
4724 * input file pointer to information about the process that was
4725 * originally created by the popen* call that created the file pointer.
4726 * The dictionary uses the file pointer as a key (with one entry
4727 * inserted for each file returned by the original popen* call) and a
4728 * single list object as the value for all files from a single call.
4729 * The list object contains the Win32 process handle at [0], and a file
4730 * count at [1], which is initialized to the total number of file
4731 * handles using that list.
4732 *
4733 * This function closes whichever handle it is passed, and decrements
4734 * the file count in the dictionary for the process handle pointed to
4735 * by this file. On the last close (when the file count reaches zero),
4736 * this function will wait for the child process and then return its
4737 * exit code as the result of the close() operation. This permits the
4738 * files to be closed in any order - it is always the close() of the
4739 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004740 *
4741 * NOTE: This function is currently called with the GIL released.
4742 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004743 */
4744
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004745static int _PyPclose(FILE *file)
4746{
4747 int result;
4748 int exit_code;
Christian Heimesd491d712008-02-01 18:49:26 +00004749 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004750 PyObject *procObj, *pidObj, *intObj, *fileObj;
4751 int file_count;
4752#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004753 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004754#endif
4755
4756 /* Close the file handle first, to ensure it can't block the
4757 * child from exiting if it's the last handle.
4758 */
4759 result = fclose(file);
4760
4761#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004762 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004763#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004764 if (_PyPopenProcs)
4765 {
4766 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4767 (procObj = PyDict_GetItem(_PyPopenProcs,
4768 fileObj)) != NULL &&
4769 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4770 (intObj = PyList_GetItem(procObj,1)) != NULL)
4771 {
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00004772 pipe_pid = (pid_t) PyLong_AsPid(pidObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004773 file_count = (int) PyInt_AsLong(intObj);
4774
4775 if (file_count > 1)
4776 {
4777 /* Still other files referencing process */
4778 file_count--;
4779 PyList_SetItem(procObj,1,
4780 PyInt_FromLong((long) file_count));
4781 }
4782 else
4783 {
4784 /* Last file for this process */
4785 if (result != EOF &&
4786 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4787 {
4788 /* extract exit status */
4789 if (WIFEXITED(exit_code))
4790 {
4791 result = WEXITSTATUS(exit_code);
4792 }
4793 else
4794 {
4795 errno = EPIPE;
4796 result = -1;
4797 }
4798 }
4799 else
4800 {
4801 /* Indicate failure - this will cause the file object
4802 * to raise an I/O error and translate the last
4803 * error code from errno. We do have a problem with
4804 * last errors that overlap the normal errno table,
4805 * but that's a consistent problem with the file object.
4806 */
4807 result = -1;
4808 }
4809 }
4810
4811 /* Remove this file pointer from dictionary */
4812 PyDict_DelItem(_PyPopenProcs, fileObj);
4813
4814 if (PyDict_Size(_PyPopenProcs) == 0)
4815 {
4816 Py_DECREF(_PyPopenProcs);
4817 _PyPopenProcs = NULL;
4818 }
4819
4820 } /* if object retrieval ok */
4821
4822 Py_XDECREF(fileObj);
4823 } /* if _PyPopenProcs */
4824
4825#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004826 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004827#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004828 return result;
4829}
4830
4831#endif /* PYCC_??? */
4832
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004833#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004834
4835/*
4836 * Portable 'popen' replacement for Win32.
4837 *
4838 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4839 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004840 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004841 */
4842
4843#include <malloc.h>
4844#include <io.h>
4845#include <fcntl.h>
4846
4847/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4848#define POPEN_1 1
4849#define POPEN_2 2
4850#define POPEN_3 3
4851#define POPEN_4 4
4852
4853static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004854static int _PyPclose(FILE *file);
4855
4856/*
4857 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004858 * for use when retrieving the process exit code. See _PyPclose() below
4859 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004860 */
4861static PyObject *_PyPopenProcs = NULL;
4862
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004863
4864/* popen that works from a GUI.
4865 *
4866 * The result of this function is a pipe (file) connected to the
4867 * processes stdin or stdout, depending on the requested mode.
4868 */
4869
4870static PyObject *
4871posix_popen(PyObject *self, PyObject *args)
4872{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004873 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004874 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004875
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004876 char *cmdstring;
4877 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004878 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004879 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004880 return NULL;
4881
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004882 if (*mode == 'r')
4883 tm = _O_RDONLY;
4884 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004885 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004886 return NULL;
4887 } else
4888 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004889
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004890 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004891 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004892 return NULL;
4893 }
4894
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004895 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004896 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004897 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004898 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004899 else
4900 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4901
4902 return f;
4903}
4904
4905/* Variation on win32pipe.popen
4906 *
4907 * The result of this function is a pipe (file) connected to the
4908 * process's stdin, and a pipe connected to the process's stdout.
4909 */
4910
4911static PyObject *
4912win32_popen2(PyObject *self, PyObject *args)
4913{
4914 PyObject *f;
4915 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004916
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004917 char *cmdstring;
4918 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004919 int bufsize = -1;
4920 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004921 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004922
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004923 if (*mode == 't')
4924 tm = _O_TEXT;
4925 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004926 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004927 return NULL;
4928 } else
4929 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004930
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004931 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004932 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004933 return NULL;
4934 }
4935
4936 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004937
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004938 return f;
4939}
4940
4941/*
4942 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004943 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004944 * The result of this function is 3 pipes - the process's stdin,
4945 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004946 */
4947
4948static PyObject *
4949win32_popen3(PyObject *self, PyObject *args)
4950{
4951 PyObject *f;
4952 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004953
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004954 char *cmdstring;
4955 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004956 int bufsize = -1;
4957 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004958 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004959
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004960 if (*mode == 't')
4961 tm = _O_TEXT;
4962 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004963 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004964 return NULL;
4965 } else
4966 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004967
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004968 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004969 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004970 return NULL;
4971 }
4972
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004973 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004974
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004975 return f;
4976}
4977
4978/*
4979 * Variation on win32pipe.popen
4980 *
Tim Peters5aa91602002-01-30 05:46:57 +00004981 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004982 * and stdout+stderr combined as a single pipe.
4983 */
4984
4985static PyObject *
4986win32_popen4(PyObject *self, PyObject *args)
4987{
4988 PyObject *f;
4989 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004990
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004991 char *cmdstring;
4992 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004993 int bufsize = -1;
4994 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004995 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004996
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004997 if (*mode == 't')
4998 tm = _O_TEXT;
4999 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00005000 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005001 return NULL;
5002 } else
5003 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005004
5005 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00005006 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005007 return NULL;
5008 }
5009
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00005010 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005011
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005012 return f;
5013}
5014
Mark Hammond08501372001-01-31 07:30:29 +00005015static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00005016_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005017 HANDLE hStdin,
5018 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00005019 HANDLE hStderr,
5020 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005021{
5022 PROCESS_INFORMATION piProcInfo;
5023 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005024 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005025 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00005026 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005027 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005028 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005029
5030 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00005031 char *comshell;
5032
Tim Peters92e4dd82002-10-05 01:47:34 +00005033 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005034 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00005035 /* x < i, so x fits into an integer */
5036 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00005037
5038 /* Explicitly check if we are using COMMAND.COM. If we are
5039 * then use the w9xpopen hack.
5040 */
5041 comshell = s1 + x;
5042 while (comshell >= s1 && *comshell != '\\')
5043 --comshell;
5044 ++comshell;
5045
5046 if (GetVersion() < 0x80000000 &&
5047 _stricmp(comshell, "command.com") != 0) {
5048 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005049 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00005050 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005051 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00005052 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005053 }
5054 else {
5055 /*
Tim Peters402d5982001-08-27 06:37:48 +00005056 * Oh gag, we're on Win9x or using COMMAND.COM. Use
5057 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005058 */
Mark Hammond08501372001-01-31 07:30:29 +00005059 char modulepath[_MAX_PATH];
5060 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005061 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Martin v. Löwis26fd9602006-04-22 11:15:41 +00005062 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005063 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005064 x = i+1;
5065 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00005066 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00005067 strncat(modulepath,
5068 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00005069 (sizeof(modulepath)/sizeof(modulepath[0]))
5070 -strlen(modulepath));
5071 if (stat(modulepath, &statinfo) != 0) {
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00005072 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
Tim Peters5aa91602002-01-30 05:46:57 +00005073 /* Eeek - file-not-found - possibly an embedding
5074 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00005075 */
Tim Peters5aa91602002-01-30 05:46:57 +00005076 strncpy(modulepath,
5077 Py_GetExecPrefix(),
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00005078 mplen);
5079 modulepath[mplen-1] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00005080 if (modulepath[strlen(modulepath)-1] != '\\')
5081 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00005082 strncat(modulepath,
5083 szConsoleSpawn,
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00005084 mplen-strlen(modulepath));
Mark Hammond08501372001-01-31 07:30:29 +00005085 /* No where else to look - raise an easily identifiable
5086 error, rather than leaving Windows to report
5087 "file not found" - as the user is probably blissfully
5088 unaware this shim EXE is used, and it will confuse them.
5089 (well, it confused me for a while ;-)
5090 */
5091 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00005092 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00005093 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00005094 "for popen to work with your shell "
5095 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00005096 szConsoleSpawn);
5097 return FALSE;
5098 }
5099 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005100 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00005101 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005102 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00005103
Tim Peters92e4dd82002-10-05 01:47:34 +00005104 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005105 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00005106 /* To maintain correct argument passing semantics,
5107 we pass the command-line as it stands, and allow
5108 quoting to be applied. w9xpopen.exe will then
5109 use its argv vector, and re-quote the necessary
5110 args for the ultimate child process.
5111 */
Tim Peters75cdad52001-11-28 22:07:30 +00005112 PyOS_snprintf(
5113 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00005114 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005115 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005116 s1,
5117 s3,
5118 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005119 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00005120 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005121 dialog:
5122 "Your program accessed mem currently in use at xxx"
5123 and a hopeful warning about the stability of your
5124 system.
Mark Dickinson3e4caeb2009-02-21 20:27:01 +00005125 Cost is Ctrl+C won't kill children, but anyone
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005126 who cares can have a go!
5127 */
5128 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005129 }
5130 }
5131
5132 /* Could be an else here to try cmd.exe / command.com in the path
5133 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00005134 else {
Tim Peters402d5982001-08-27 06:37:48 +00005135 PyErr_SetString(PyExc_RuntimeError,
5136 "Cannot locate a COMSPEC environment variable to "
5137 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00005138 return FALSE;
5139 }
Tim Peters5aa91602002-01-30 05:46:57 +00005140
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005141 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5142 siStartInfo.cb = sizeof(STARTUPINFO);
5143 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5144 siStartInfo.hStdInput = hStdin;
5145 siStartInfo.hStdOutput = hStdout;
5146 siStartInfo.hStdError = hStderr;
5147 siStartInfo.wShowWindow = SW_HIDE;
5148
5149 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005150 s2,
5151 NULL,
5152 NULL,
5153 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005154 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005155 NULL,
5156 NULL,
5157 &siStartInfo,
5158 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005159 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005160 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005161
Mark Hammondb37a3732000-08-14 04:47:33 +00005162 /* Return process handle */
5163 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005164 return TRUE;
5165 }
Tim Peters402d5982001-08-27 06:37:48 +00005166 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005167 return FALSE;
5168}
5169
5170/* The following code is based off of KB: Q190351 */
5171
5172static PyObject *
5173_PyPopen(char *cmdstring, int mode, int n)
5174{
5175 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5176 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00005177 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005178
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005179 SECURITY_ATTRIBUTES saAttr;
5180 BOOL fSuccess;
5181 int fd1, fd2, fd3;
5182 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00005183 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005184 PyObject *f;
5185
5186 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5187 saAttr.bInheritHandle = TRUE;
5188 saAttr.lpSecurityDescriptor = NULL;
5189
5190 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5191 return win32_error("CreatePipe", NULL);
5192
5193 /* Create new output read handle and the input write handle. Set
5194 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005195 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005196 * being created. */
5197 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005198 GetCurrentProcess(), &hChildStdinWrDup, 0,
5199 FALSE,
5200 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005201 if (!fSuccess)
5202 return win32_error("DuplicateHandle", NULL);
5203
5204 /* Close the inheritable version of ChildStdin
5205 that we're using. */
5206 CloseHandle(hChildStdinWr);
5207
5208 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5209 return win32_error("CreatePipe", NULL);
5210
5211 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005212 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5213 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005214 if (!fSuccess)
5215 return win32_error("DuplicateHandle", NULL);
5216
5217 /* Close the inheritable version of ChildStdout
5218 that we're using. */
5219 CloseHandle(hChildStdoutRd);
5220
5221 if (n != POPEN_4) {
5222 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5223 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005224 fSuccess = DuplicateHandle(GetCurrentProcess(),
5225 hChildStderrRd,
5226 GetCurrentProcess(),
5227 &hChildStderrRdDup, 0,
5228 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005229 if (!fSuccess)
5230 return win32_error("DuplicateHandle", NULL);
5231 /* Close the inheritable version of ChildStdErr that we're using. */
5232 CloseHandle(hChildStderrRd);
5233 }
Tim Peters5aa91602002-01-30 05:46:57 +00005234
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005235 switch (n) {
5236 case POPEN_1:
5237 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5238 case _O_WRONLY | _O_TEXT:
5239 /* Case for writing to child Stdin in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005240 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005241 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005242 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005243 PyFile_SetBufSize(f, 0);
5244 /* We don't care about these pipes anymore, so close them. */
5245 CloseHandle(hChildStdoutRdDup);
5246 CloseHandle(hChildStderrRdDup);
5247 break;
5248
5249 case _O_RDONLY | _O_TEXT:
5250 /* Case for reading from child Stdout in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005251 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005252 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005253 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005254 PyFile_SetBufSize(f, 0);
5255 /* We don't care about these pipes anymore, so close them. */
5256 CloseHandle(hChildStdinWrDup);
5257 CloseHandle(hChildStderrRdDup);
5258 break;
5259
5260 case _O_RDONLY | _O_BINARY:
5261 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005262 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005263 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005264 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005265 PyFile_SetBufSize(f, 0);
5266 /* We don't care about these pipes anymore, so close them. */
5267 CloseHandle(hChildStdinWrDup);
5268 CloseHandle(hChildStderrRdDup);
5269 break;
5270
5271 case _O_WRONLY | _O_BINARY:
5272 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005273 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005274 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005275 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005276 PyFile_SetBufSize(f, 0);
5277 /* We don't care about these pipes anymore, so close them. */
5278 CloseHandle(hChildStdoutRdDup);
5279 CloseHandle(hChildStderrRdDup);
5280 break;
5281 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005282 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005283 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005284
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005285 case POPEN_2:
5286 case POPEN_4:
5287 {
5288 char *m1, *m2;
5289 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005290
Tim Peters7dca21e2002-08-19 00:42:29 +00005291 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005292 m1 = "r";
5293 m2 = "w";
5294 } else {
5295 m1 = "rb";
5296 m2 = "wb";
5297 }
5298
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005299 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005300 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005301 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005302 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005303 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005304 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00005305 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005306 PyFile_SetBufSize(p2, 0);
5307
5308 if (n != 4)
5309 CloseHandle(hChildStderrRdDup);
5310
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005311 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00005312 Py_XDECREF(p1);
5313 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00005314 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005315 break;
5316 }
Tim Peters5aa91602002-01-30 05:46:57 +00005317
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005318 case POPEN_3:
5319 {
5320 char *m1, *m2;
5321 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005322
Tim Peters7dca21e2002-08-19 00:42:29 +00005323 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005324 m1 = "r";
5325 m2 = "w";
5326 } else {
5327 m1 = "rb";
5328 m2 = "wb";
5329 }
5330
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005331 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005332 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005333 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005334 f2 = _fdopen(fd2, m1);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005335 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005336 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005337 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00005338 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5339 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005340 PyFile_SetBufSize(p1, 0);
5341 PyFile_SetBufSize(p2, 0);
5342 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005343 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00005344 Py_XDECREF(p1);
5345 Py_XDECREF(p2);
5346 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00005347 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005348 break;
5349 }
5350 }
5351
5352 if (n == POPEN_4) {
5353 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005354 hChildStdinRd,
5355 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005356 hChildStdoutWr,
5357 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005358 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005359 }
5360 else {
5361 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005362 hChildStdinRd,
5363 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005364 hChildStderrWr,
5365 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005366 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005367 }
5368
Mark Hammondb37a3732000-08-14 04:47:33 +00005369 /*
5370 * Insert the files we've created into the process dictionary
5371 * all referencing the list with the process handle and the
5372 * initial number of files (see description below in _PyPclose).
5373 * Since if _PyPclose later tried to wait on a process when all
5374 * handles weren't closed, it could create a deadlock with the
5375 * child, we spend some energy here to try to ensure that we
5376 * either insert all file handles into the dictionary or none
5377 * at all. It's a little clumsy with the various popen modes
5378 * and variable number of files involved.
5379 */
5380 if (!_PyPopenProcs) {
5381 _PyPopenProcs = PyDict_New();
5382 }
5383
5384 if (_PyPopenProcs) {
5385 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5386 int ins_rc[3];
5387
5388 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5389 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
5390
5391 procObj = PyList_New(2);
5392 hProcessObj = PyLong_FromVoidPtr(hProcess);
5393 intObj = PyInt_FromLong(file_count);
5394
5395 if (procObj && hProcessObj && intObj) {
5396 PyList_SetItem(procObj,0,hProcessObj);
5397 PyList_SetItem(procObj,1,intObj);
5398
5399 fileObj[0] = PyLong_FromVoidPtr(f1);
5400 if (fileObj[0]) {
5401 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5402 fileObj[0],
5403 procObj);
5404 }
5405 if (file_count >= 2) {
5406 fileObj[1] = PyLong_FromVoidPtr(f2);
5407 if (fileObj[1]) {
5408 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5409 fileObj[1],
5410 procObj);
5411 }
5412 }
5413 if (file_count >= 3) {
5414 fileObj[2] = PyLong_FromVoidPtr(f3);
5415 if (fileObj[2]) {
5416 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5417 fileObj[2],
5418 procObj);
5419 }
5420 }
5421
5422 if (ins_rc[0] < 0 || !fileObj[0] ||
5423 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5424 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5425 /* Something failed - remove any dictionary
5426 * entries that did make it.
5427 */
5428 if (!ins_rc[0] && fileObj[0]) {
5429 PyDict_DelItem(_PyPopenProcs,
5430 fileObj[0]);
5431 }
5432 if (!ins_rc[1] && fileObj[1]) {
5433 PyDict_DelItem(_PyPopenProcs,
5434 fileObj[1]);
5435 }
5436 if (!ins_rc[2] && fileObj[2]) {
5437 PyDict_DelItem(_PyPopenProcs,
5438 fileObj[2]);
5439 }
5440 }
5441 }
Tim Peters5aa91602002-01-30 05:46:57 +00005442
Mark Hammondb37a3732000-08-14 04:47:33 +00005443 /*
5444 * Clean up our localized references for the dictionary keys
5445 * and value since PyDict_SetItem will Py_INCREF any copies
5446 * that got placed in the dictionary.
5447 */
5448 Py_XDECREF(procObj);
5449 Py_XDECREF(fileObj[0]);
5450 Py_XDECREF(fileObj[1]);
5451 Py_XDECREF(fileObj[2]);
5452 }
5453
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005454 /* Child is launched. Close the parents copy of those pipe
5455 * handles that only the child should have open. You need to
5456 * make sure that no handles to the write end of the output pipe
5457 * are maintained in this process or else the pipe will not close
5458 * when the child process exits and the ReadFile will hang. */
5459
5460 if (!CloseHandle(hChildStdinRd))
5461 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005462
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005463 if (!CloseHandle(hChildStdoutWr))
5464 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005465
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005466 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5467 return win32_error("CloseHandle", NULL);
5468
5469 return f;
5470}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005471
5472/*
5473 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5474 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005475 *
5476 * This function uses the _PyPopenProcs dictionary in order to map the
5477 * input file pointer to information about the process that was
5478 * originally created by the popen* call that created the file pointer.
5479 * The dictionary uses the file pointer as a key (with one entry
5480 * inserted for each file returned by the original popen* call) and a
5481 * single list object as the value for all files from a single call.
5482 * The list object contains the Win32 process handle at [0], and a file
5483 * count at [1], which is initialized to the total number of file
5484 * handles using that list.
5485 *
5486 * This function closes whichever handle it is passed, and decrements
5487 * the file count in the dictionary for the process handle pointed to
5488 * by this file. On the last close (when the file count reaches zero),
5489 * this function will wait for the child process and then return its
5490 * exit code as the result of the close() operation. This permits the
5491 * files to be closed in any order - it is always the close() of the
5492 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005493 *
5494 * NOTE: This function is currently called with the GIL released.
5495 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005496 */
Tim Peters736aa322000-09-01 06:51:24 +00005497
Fredrik Lundh56055a42000-07-23 19:47:12 +00005498static int _PyPclose(FILE *file)
5499{
Fredrik Lundh20318932000-07-26 17:29:12 +00005500 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005501 DWORD exit_code;
5502 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00005503 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5504 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005505#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005506 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005507#endif
5508
Fredrik Lundh20318932000-07-26 17:29:12 +00005509 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00005510 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00005511 */
5512 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005513#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005514 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005515#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005516 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005517 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5518 (procObj = PyDict_GetItem(_PyPopenProcs,
5519 fileObj)) != NULL &&
5520 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5521 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5522
5523 hProcess = PyLong_AsVoidPtr(hProcessObj);
5524 file_count = PyInt_AsLong(intObj);
5525
5526 if (file_count > 1) {
5527 /* Still other files referencing process */
5528 file_count--;
5529 PyList_SetItem(procObj,1,
5530 PyInt_FromLong(file_count));
5531 } else {
5532 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00005533 if (result != EOF &&
5534 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5535 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00005536 /* Possible truncation here in 16-bit environments, but
5537 * real exit codes are just the lower byte in any event.
5538 */
5539 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005540 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00005541 /* Indicate failure - this will cause the file object
5542 * to raise an I/O error and translate the last Win32
5543 * error code from errno. We do have a problem with
5544 * last errors that overlap the normal errno table,
5545 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005546 */
Fredrik Lundh20318932000-07-26 17:29:12 +00005547 if (result != EOF) {
5548 /* If the error wasn't from the fclose(), then
5549 * set errno for the file object error handling.
5550 */
5551 errno = GetLastError();
5552 }
5553 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005554 }
5555
5556 /* Free up the native handle at this point */
5557 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00005558 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005559
Mark Hammondb37a3732000-08-14 04:47:33 +00005560 /* Remove this file pointer from dictionary */
5561 PyDict_DelItem(_PyPopenProcs, fileObj);
5562
5563 if (PyDict_Size(_PyPopenProcs) == 0) {
5564 Py_DECREF(_PyPopenProcs);
5565 _PyPopenProcs = NULL;
5566 }
5567
5568 } /* if object retrieval ok */
5569
5570 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005571 } /* if _PyPopenProcs */
5572
Tim Peters736aa322000-09-01 06:51:24 +00005573#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005574 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005575#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005576 return result;
5577}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005578
5579#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005580static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005581posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005582{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005583 char *name;
5584 char *mode = "r";
5585 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00005586 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005587 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005588 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00005589 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00005590 /* Strip mode of binary or text modifiers */
5591 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5592 mode = "r";
5593 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5594 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00005595 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005596 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005597 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00005598 if (fp == NULL)
5599 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005600 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005601 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005602 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005603 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005604}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005605
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005606#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005607#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005608
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005609
Guido van Rossumb6775db1994-08-01 11:34:53 +00005610#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005611PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005612"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005613Set the current process's user id.");
5614
Barry Warsaw53699e91996-12-10 23:23:01 +00005615static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005616posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005617{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005618 long uid_arg;
5619 uid_t uid;
5620 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005621 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005622 uid = uid_arg;
5623 if (uid != uid_arg) {
5624 PyErr_SetString(PyExc_OverflowError, "user id too big");
5625 return NULL;
5626 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005627 if (setuid(uid) < 0)
5628 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005629 Py_INCREF(Py_None);
5630 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005631}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005632#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005633
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005634
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005635#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005636PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005637"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005638Set the current process's effective user id.");
5639
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005640static PyObject *
5641posix_seteuid (PyObject *self, PyObject *args)
5642{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005643 long euid_arg;
5644 uid_t euid;
5645 if (!PyArg_ParseTuple(args, "l", &euid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005646 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005647 euid = euid_arg;
5648 if (euid != euid_arg) {
5649 PyErr_SetString(PyExc_OverflowError, "user id too big");
5650 return NULL;
5651 }
5652 if (seteuid(euid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005653 return posix_error();
5654 } else {
5655 Py_INCREF(Py_None);
5656 return Py_None;
5657 }
5658}
5659#endif /* HAVE_SETEUID */
5660
5661#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005662PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005663"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005664Set the current process's effective group id.");
5665
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005666static PyObject *
5667posix_setegid (PyObject *self, PyObject *args)
5668{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005669 long egid_arg;
5670 gid_t egid;
5671 if (!PyArg_ParseTuple(args, "l", &egid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005672 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005673 egid = egid_arg;
5674 if (egid != egid_arg) {
5675 PyErr_SetString(PyExc_OverflowError, "group id too big");
5676 return NULL;
5677 }
5678 if (setegid(egid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005679 return posix_error();
5680 } else {
5681 Py_INCREF(Py_None);
5682 return Py_None;
5683 }
5684}
5685#endif /* HAVE_SETEGID */
5686
5687#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005688PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005689"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005690Set the current process's real and effective user ids.");
5691
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005692static PyObject *
5693posix_setreuid (PyObject *self, PyObject *args)
5694{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005695 long ruid_arg, euid_arg;
5696 uid_t ruid, euid;
5697 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005698 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005699 ruid = ruid_arg;
5700 euid = euid_arg;
5701 if (euid != euid_arg || ruid != ruid_arg) {
5702 PyErr_SetString(PyExc_OverflowError, "user id too big");
5703 return NULL;
5704 }
5705 if (setreuid(ruid, euid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005706 return posix_error();
5707 } else {
5708 Py_INCREF(Py_None);
5709 return Py_None;
5710 }
5711}
5712#endif /* HAVE_SETREUID */
5713
5714#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005715PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005716"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005717Set the current process's real and effective group ids.");
5718
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005719static PyObject *
5720posix_setregid (PyObject *self, PyObject *args)
5721{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005722 long rgid_arg, egid_arg;
5723 gid_t rgid, egid;
5724 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005725 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005726 rgid = rgid_arg;
5727 egid = egid_arg;
5728 if (egid != egid_arg || rgid != rgid_arg) {
5729 PyErr_SetString(PyExc_OverflowError, "group id too big");
5730 return NULL;
5731 }
5732 if (setregid(rgid, egid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005733 return posix_error();
5734 } else {
5735 Py_INCREF(Py_None);
5736 return Py_None;
5737 }
5738}
5739#endif /* HAVE_SETREGID */
5740
Guido van Rossumb6775db1994-08-01 11:34:53 +00005741#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005742PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005743"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005744Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005745
Barry Warsaw53699e91996-12-10 23:23:01 +00005746static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005747posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005748{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005749 long gid_arg;
5750 gid_t gid;
5751 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005752 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005753 gid = gid_arg;
5754 if (gid != gid_arg) {
5755 PyErr_SetString(PyExc_OverflowError, "group id too big");
5756 return NULL;
5757 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005758 if (setgid(gid) < 0)
5759 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005760 Py_INCREF(Py_None);
5761 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005762}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005763#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005764
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005765#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005766PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005767"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005768Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005769
5770static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005771posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005772{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005773 int i, len;
5774 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005775
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005776 if (!PySequence_Check(groups)) {
5777 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5778 return NULL;
5779 }
5780 len = PySequence_Size(groups);
5781 if (len > MAX_GROUPS) {
5782 PyErr_SetString(PyExc_ValueError, "too many groups");
5783 return NULL;
5784 }
5785 for(i = 0; i < len; i++) {
5786 PyObject *elem;
5787 elem = PySequence_GetItem(groups, i);
5788 if (!elem)
5789 return NULL;
5790 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005791 if (!PyLong_Check(elem)) {
5792 PyErr_SetString(PyExc_TypeError,
5793 "groups must be integers");
5794 Py_DECREF(elem);
5795 return NULL;
5796 } else {
5797 unsigned long x = PyLong_AsUnsignedLong(elem);
5798 if (PyErr_Occurred()) {
5799 PyErr_SetString(PyExc_TypeError,
5800 "group id too big");
5801 Py_DECREF(elem);
5802 return NULL;
5803 }
5804 grouplist[i] = x;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005805 /* read back to see if it fits in gid_t */
Georg Brandla13c2442005-11-22 19:30:31 +00005806 if (grouplist[i] != x) {
5807 PyErr_SetString(PyExc_TypeError,
5808 "group id too big");
5809 Py_DECREF(elem);
5810 return NULL;
5811 }
5812 }
5813 } else {
5814 long x = PyInt_AsLong(elem);
5815 grouplist[i] = x;
5816 if (grouplist[i] != x) {
5817 PyErr_SetString(PyExc_TypeError,
5818 "group id too big");
5819 Py_DECREF(elem);
5820 return NULL;
5821 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005822 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005823 Py_DECREF(elem);
5824 }
5825
5826 if (setgroups(len, grouplist) < 0)
5827 return posix_error();
5828 Py_INCREF(Py_None);
5829 return Py_None;
5830}
5831#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005832
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005833#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005834static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00005835wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00005836{
5837 PyObject *result;
5838 static PyObject *struct_rusage;
5839
5840 if (pid == -1)
5841 return posix_error();
5842
5843 if (struct_rusage == NULL) {
Christian Heimes000a0742008-01-03 22:16:32 +00005844 PyObject *m = PyImport_ImportModuleNoBlock("resource");
Neal Norwitz05a45592006-03-20 06:30:08 +00005845 if (m == NULL)
5846 return NULL;
5847 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5848 Py_DECREF(m);
5849 if (struct_rusage == NULL)
5850 return NULL;
5851 }
5852
5853 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5854 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5855 if (!result)
5856 return NULL;
5857
5858#ifndef doubletime
5859#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5860#endif
5861
5862 PyStructSequence_SET_ITEM(result, 0,
5863 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5864 PyStructSequence_SET_ITEM(result, 1,
5865 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5866#define SET_INT(result, index, value)\
5867 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5868 SET_INT(result, 2, ru->ru_maxrss);
5869 SET_INT(result, 3, ru->ru_ixrss);
5870 SET_INT(result, 4, ru->ru_idrss);
5871 SET_INT(result, 5, ru->ru_isrss);
5872 SET_INT(result, 6, ru->ru_minflt);
5873 SET_INT(result, 7, ru->ru_majflt);
5874 SET_INT(result, 8, ru->ru_nswap);
5875 SET_INT(result, 9, ru->ru_inblock);
5876 SET_INT(result, 10, ru->ru_oublock);
5877 SET_INT(result, 11, ru->ru_msgsnd);
5878 SET_INT(result, 12, ru->ru_msgrcv);
5879 SET_INT(result, 13, ru->ru_nsignals);
5880 SET_INT(result, 14, ru->ru_nvcsw);
5881 SET_INT(result, 15, ru->ru_nivcsw);
5882#undef SET_INT
5883
5884 if (PyErr_Occurred()) {
5885 Py_DECREF(result);
5886 return NULL;
5887 }
5888
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005889 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005890}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005891#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005892
5893#ifdef HAVE_WAIT3
5894PyDoc_STRVAR(posix_wait3__doc__,
5895"wait3(options) -> (pid, status, rusage)\n\n\
5896Wait for completion of a child process.");
5897
5898static PyObject *
5899posix_wait3(PyObject *self, PyObject *args)
5900{
Christian Heimesd491d712008-02-01 18:49:26 +00005901 pid_t pid;
5902 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005903 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005904 WAIT_TYPE status;
5905 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005906
5907 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5908 return NULL;
5909
5910 Py_BEGIN_ALLOW_THREADS
5911 pid = wait3(&status, options, &ru);
5912 Py_END_ALLOW_THREADS
5913
Neal Norwitzd5a37542006-03-20 06:48:34 +00005914 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005915}
5916#endif /* HAVE_WAIT3 */
5917
5918#ifdef HAVE_WAIT4
5919PyDoc_STRVAR(posix_wait4__doc__,
5920"wait4(pid, options) -> (pid, status, rusage)\n\n\
5921Wait for completion of a given child process.");
5922
5923static PyObject *
5924posix_wait4(PyObject *self, PyObject *args)
5925{
Christian Heimesd491d712008-02-01 18:49:26 +00005926 pid_t pid;
5927 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005928 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005929 WAIT_TYPE status;
5930 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005931
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005932 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
Neal Norwitz05a45592006-03-20 06:30:08 +00005933 return NULL;
5934
5935 Py_BEGIN_ALLOW_THREADS
5936 pid = wait4(pid, &status, options, &ru);
5937 Py_END_ALLOW_THREADS
5938
Neal Norwitzd5a37542006-03-20 06:48:34 +00005939 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005940}
5941#endif /* HAVE_WAIT4 */
5942
Guido van Rossumb6775db1994-08-01 11:34:53 +00005943#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005944PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005945"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005946Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005947
Barry Warsaw53699e91996-12-10 23:23:01 +00005948static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005949posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005950{
Christian Heimesd491d712008-02-01 18:49:26 +00005951 pid_t pid;
5952 int options;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005953 WAIT_TYPE status;
5954 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005955
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005956 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005957 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005958 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005959 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005960 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005961 if (pid == -1)
5962 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005963
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005964 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005965}
5966
Tim Petersab034fa2002-02-01 11:27:43 +00005967#elif defined(HAVE_CWAIT)
5968
5969/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005970PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005971"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005972"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005973
5974static PyObject *
5975posix_waitpid(PyObject *self, PyObject *args)
5976{
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005977 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005978 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005979
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005980 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
Tim Petersab034fa2002-02-01 11:27:43 +00005981 return NULL;
5982 Py_BEGIN_ALLOW_THREADS
5983 pid = _cwait(&status, pid, options);
5984 Py_END_ALLOW_THREADS
5985 if (pid == -1)
5986 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005987
5988 /* shift the status left a byte so this is more like the POSIX waitpid */
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005989 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005990}
5991#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005992
Guido van Rossumad0ee831995-03-01 10:34:45 +00005993#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005994PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005995"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005996Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005997
Barry Warsaw53699e91996-12-10 23:23:01 +00005998static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005999posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006000{
Christian Heimesd491d712008-02-01 18:49:26 +00006001 pid_t pid;
Neal Norwitzd5a37542006-03-20 06:48:34 +00006002 WAIT_TYPE status;
6003 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006004
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006005 Py_BEGIN_ALLOW_THREADS
6006 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00006007 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00006008 if (pid == -1)
6009 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006010
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00006011 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006012}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006013#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006014
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006015
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006016PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006017"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006018Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006019
Barry Warsaw53699e91996-12-10 23:23:01 +00006020static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006021posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006022{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006023#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006024 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006025#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006026#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00006027 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006028#else
6029 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
6030#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006031#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006032}
6033
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006034
Guido van Rossumb6775db1994-08-01 11:34:53 +00006035#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006036PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006037"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006038Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006039
Barry Warsaw53699e91996-12-10 23:23:01 +00006040static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006041posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006042{
Ronald Oussoren10168f22006-10-22 10:45:18 +00006043 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00006044 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00006045 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006046 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006047#ifdef Py_USING_UNICODE
6048 int arg_is_unicode = 0;
6049#endif
6050
6051 if (!PyArg_ParseTuple(args, "et:readlink",
6052 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006053 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006054#ifdef Py_USING_UNICODE
6055 v = PySequence_GetItem(args, 0);
Neal Norwitz91a57212007-08-12 17:11:13 +00006056 if (v == NULL) {
6057 PyMem_Free(path);
6058 return NULL;
6059 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006060
6061 if (PyUnicode_Check(v)) {
6062 arg_is_unicode = 1;
6063 }
6064 Py_DECREF(v);
6065#endif
6066
Barry Warsaw53699e91996-12-10 23:23:01 +00006067 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00006068 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00006069 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006070 if (n < 0)
Neal Norwitz91a57212007-08-12 17:11:13 +00006071 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006072
Neal Norwitz91a57212007-08-12 17:11:13 +00006073 PyMem_Free(path);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006074 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006075#ifdef Py_USING_UNICODE
6076 if (arg_is_unicode) {
6077 PyObject *w;
6078
6079 w = PyUnicode_FromEncodedObject(v,
6080 Py_FileSystemDefaultEncoding,
6081 "strict");
6082 if (w != NULL) {
6083 Py_DECREF(v);
6084 v = w;
6085 }
6086 else {
6087 /* fall back to the original byte string, as
6088 discussed in patch #683592 */
6089 PyErr_Clear();
6090 }
6091 }
6092#endif
6093 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006094}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006095#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006096
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006097
Guido van Rossumb6775db1994-08-01 11:34:53 +00006098#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006099PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006100"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006101Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006102
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006103static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006104posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006105{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00006106 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006107}
6108#endif /* HAVE_SYMLINK */
6109
6110
6111#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006112#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6113static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006114system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006115{
6116 ULONG value = 0;
6117
6118 Py_BEGIN_ALLOW_THREADS
6119 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6120 Py_END_ALLOW_THREADS
6121
6122 return value;
6123}
6124
6125static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006126posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006127{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006128 /* Currently Only Uptime is Provided -- Others Later */
6129 return Py_BuildValue("ddddd",
6130 (double)0 /* t.tms_utime / HZ */,
6131 (double)0 /* t.tms_stime / HZ */,
6132 (double)0 /* t.tms_cutime / HZ */,
6133 (double)0 /* t.tms_cstime / HZ */,
6134 (double)system_uptime() / 1000);
6135}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006136#else /* not OS2 */
Martin v. Löwis03824e42008-12-29 18:17:34 +00006137#define NEED_TICKS_PER_SECOND
6138static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006139static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006140posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006141{
6142 struct tms t;
6143 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00006144 errno = 0;
6145 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00006146 if (c == (clock_t) -1)
6147 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006148 return Py_BuildValue("ddddd",
Martin v. Löwis03824e42008-12-29 18:17:34 +00006149 (double)t.tms_utime / ticks_per_second,
6150 (double)t.tms_stime / ticks_per_second,
6151 (double)t.tms_cutime / ticks_per_second,
6152 (double)t.tms_cstime / ticks_per_second,
6153 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006154}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006155#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006156#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006157
6158
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006159#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006160#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006161static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006162posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006163{
6164 FILETIME create, exit, kernel, user;
6165 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006166 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006167 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6168 /* The fields of a FILETIME structure are the hi and lo part
6169 of a 64-bit value expressed in 100 nanosecond units.
6170 1e7 is one second in such units; 1e-7 the inverse.
6171 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6172 */
Barry Warsaw53699e91996-12-10 23:23:01 +00006173 return Py_BuildValue(
6174 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006175 (double)(user.dwHighDateTime*429.4967296 +
6176 user.dwLowDateTime*1e-7),
Georg Brandl0a40ffb2008-02-13 07:20:22 +00006177 (double)(kernel.dwHighDateTime*429.4967296 +
6178 kernel.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00006179 (double)0,
6180 (double)0,
6181 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006182}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006183#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006184
6185#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006186PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006187"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006188Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006189#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006190
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006191
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006192#ifdef HAVE_GETSID
6193PyDoc_STRVAR(posix_getsid__doc__,
6194"getsid(pid) -> sid\n\n\
6195Call the system call getsid().");
6196
6197static PyObject *
6198posix_getsid(PyObject *self, PyObject *args)
6199{
Christian Heimesd491d712008-02-01 18:49:26 +00006200 pid_t pid;
6201 int sid;
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00006202 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006203 return NULL;
6204 sid = getsid(pid);
6205 if (sid < 0)
6206 return posix_error();
6207 return PyInt_FromLong((long)sid);
6208}
6209#endif /* HAVE_GETSID */
6210
6211
Guido van Rossumb6775db1994-08-01 11:34:53 +00006212#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006213PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006214"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006215Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006216
Barry Warsaw53699e91996-12-10 23:23:01 +00006217static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006218posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006219{
Guido van Rossum687dd131993-05-17 08:34:16 +00006220 if (setsid() < 0)
6221 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006222 Py_INCREF(Py_None);
6223 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006224}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006225#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006226
Guido van Rossumb6775db1994-08-01 11:34:53 +00006227#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006228PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006229"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006230Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006231
Barry Warsaw53699e91996-12-10 23:23:01 +00006232static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006233posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006234{
Christian Heimesd491d712008-02-01 18:49:26 +00006235 pid_t pid;
6236 int pgrp;
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00006237 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00006238 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006239 if (setpgid(pid, pgrp) < 0)
6240 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006241 Py_INCREF(Py_None);
6242 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006243}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006244#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006245
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006246
Guido van Rossumb6775db1994-08-01 11:34:53 +00006247#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006248PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006249"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006250Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006251
Barry Warsaw53699e91996-12-10 23:23:01 +00006252static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006253posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006254{
Christian Heimese6a80742008-02-03 19:51:13 +00006255 int fd;
6256 pid_t pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006257 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006258 return NULL;
6259 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006260 if (pgid < 0)
6261 return posix_error();
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00006262 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006263}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006264#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006265
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006266
Guido van Rossumb6775db1994-08-01 11:34:53 +00006267#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006268PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006269"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006270Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006271
Barry Warsaw53699e91996-12-10 23:23:01 +00006272static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006273posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006274{
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00006275 int fd;
6276 pid_t pgid;
6277 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006278 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006279 if (tcsetpgrp(fd, pgid) < 0)
6280 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00006281 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00006282 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006283}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006284#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006285
Guido van Rossum687dd131993-05-17 08:34:16 +00006286/* Functions acting on file descriptors */
6287
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006288PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006289"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006290Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006291
Barry Warsaw53699e91996-12-10 23:23:01 +00006292static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006293posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006294{
Mark Hammondef8b6542001-05-13 08:04:26 +00006295 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006296 int flag;
6297 int mode = 0777;
6298 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006299
6300#ifdef MS_WINDOWS
6301 if (unicode_file_names()) {
6302 PyUnicodeObject *po;
6303 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6304 Py_BEGIN_ALLOW_THREADS
6305 /* PyUnicode_AS_UNICODE OK without thread
6306 lock as it is a simple dereference. */
6307 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6308 Py_END_ALLOW_THREADS
6309 if (fd < 0)
6310 return posix_error();
6311 return PyInt_FromLong((long)fd);
6312 }
6313 /* Drop the argument parsing error as narrow strings
6314 are also valid. */
6315 PyErr_Clear();
6316 }
6317#endif
6318
Tim Peters5aa91602002-01-30 05:46:57 +00006319 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00006320 Py_FileSystemDefaultEncoding, &file,
6321 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00006322 return NULL;
6323
Barry Warsaw53699e91996-12-10 23:23:01 +00006324 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006325 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00006326 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006327 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00006328 return posix_error_with_allocated_filename(file);
6329 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00006330 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006331}
6332
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006333
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006334PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006335"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006336Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006337
Barry Warsaw53699e91996-12-10 23:23:01 +00006338static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006339posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006340{
6341 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006342 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006343 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006344 if (!_PyVerify_fd(fd))
6345 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006346 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006347 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006348 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006349 if (res < 0)
6350 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006351 Py_INCREF(Py_None);
6352 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006353}
6354
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006355
Georg Brandl309501a2008-01-19 20:22:13 +00006356PyDoc_STRVAR(posix_closerange__doc__,
6357"closerange(fd_low, fd_high)\n\n\
6358Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6359
6360static PyObject *
6361posix_closerange(PyObject *self, PyObject *args)
6362{
6363 int fd_from, fd_to, i;
6364 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6365 return NULL;
6366 Py_BEGIN_ALLOW_THREADS
6367 for (i = fd_from; i < fd_to; i++)
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006368 if (_PyVerify_fd(i))
6369 close(i);
Georg Brandl309501a2008-01-19 20:22:13 +00006370 Py_END_ALLOW_THREADS
6371 Py_RETURN_NONE;
6372}
6373
6374
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006375PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006376"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006377Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006378
Barry Warsaw53699e91996-12-10 23:23:01 +00006379static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006380posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006381{
6382 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006383 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006384 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006385 if (!_PyVerify_fd(fd))
6386 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006387 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006388 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006389 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006390 if (fd < 0)
6391 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006392 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006393}
6394
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006395
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006396PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006397"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006398Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006399
Barry Warsaw53699e91996-12-10 23:23:01 +00006400static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006401posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006402{
6403 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006404 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00006405 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006406 if (!_PyVerify_fd_dup2(fd, fd2))
6407 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006408 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006409 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00006410 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006411 if (res < 0)
6412 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006413 Py_INCREF(Py_None);
6414 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006415}
6416
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006417
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006418PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006419"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006420Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006421
Barry Warsaw53699e91996-12-10 23:23:01 +00006422static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006423posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006424{
6425 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006426#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006427 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006428#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00006429 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006430#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006431 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006432 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00006433 return NULL;
6434#ifdef SEEK_SET
6435 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6436 switch (how) {
6437 case 0: how = SEEK_SET; break;
6438 case 1: how = SEEK_CUR; break;
6439 case 2: how = SEEK_END; break;
6440 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006441#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006442
6443#if !defined(HAVE_LARGEFILE_SUPPORT)
6444 pos = PyInt_AsLong(posobj);
6445#else
6446 pos = PyLong_Check(posobj) ?
6447 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
6448#endif
6449 if (PyErr_Occurred())
6450 return NULL;
6451
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006452 if (!_PyVerify_fd(fd))
6453 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006454 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006455#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00006456 res = _lseeki64(fd, pos, how);
6457#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006458 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006459#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006460 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006461 if (res < 0)
6462 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006463
6464#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00006465 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006466#else
6467 return PyLong_FromLongLong(res);
6468#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006469}
6470
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006471
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006472PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006473"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006474Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006475
Barry Warsaw53699e91996-12-10 23:23:01 +00006476static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006477posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006478{
Guido van Rossum8bac5461996-06-11 18:38:48 +00006479 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00006480 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006481 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00006482 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00006483 if (size < 0) {
6484 errno = EINVAL;
6485 return posix_error();
6486 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006487 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006488 if (buffer == NULL)
6489 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006490 if (!_PyVerify_fd(fd))
6491 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006492 Py_BEGIN_ALLOW_THREADS
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006493 n = read(fd, PyString_AsString(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00006494 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00006495 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006496 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00006497 return posix_error();
6498 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00006499 if (n != size)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006500 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00006501 return buffer;
6502}
6503
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006504
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006505PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006506"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006507Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006508
Barry Warsaw53699e91996-12-10 23:23:01 +00006509static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006510posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006511{
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006512 Py_buffer pbuf;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006513 int fd;
6514 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006515
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006516 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
Guido van Rossum687dd131993-05-17 08:34:16 +00006517 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006518 if (!_PyVerify_fd(fd))
6519 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006520 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006521 size = write(fd, pbuf.buf, (size_t)pbuf.len);
Barry Warsaw53699e91996-12-10 23:23:01 +00006522 Py_END_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006523 PyBuffer_Release(&pbuf);
Guido van Rossum687dd131993-05-17 08:34:16 +00006524 if (size < 0)
6525 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006526 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006527}
6528
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006529
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006530PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006531"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006532Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006533
Barry Warsaw53699e91996-12-10 23:23:01 +00006534static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006535posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006536{
6537 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00006538 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00006539 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006540 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006541 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006542#ifdef __VMS
6543 /* on OpenVMS we must ensure that all bytes are written to the file */
6544 fsync(fd);
6545#endif
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006546 if (!_PyVerify_fd(fd))
6547 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006548 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00006549 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00006550 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00006551 if (res != 0) {
6552#ifdef MS_WINDOWS
6553 return win32_error("fstat", NULL);
6554#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006555 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006556#endif
6557 }
Tim Peters5aa91602002-01-30 05:46:57 +00006558
Martin v. Löwis14694662006-02-03 12:54:16 +00006559 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006560}
6561
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006562
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006563PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006564"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006565Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006566
Barry Warsaw53699e91996-12-10 23:23:01 +00006567static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006568posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006569{
Guido van Rossum687dd131993-05-17 08:34:16 +00006570 int fd;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006571 char *orgmode = "r";
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006572 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00006573 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00006574 PyObject *f;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006575 char *mode;
6576 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00006577 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006578
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006579 /* Sanitize mode. See fileobject.c */
6580 mode = PyMem_MALLOC(strlen(orgmode)+3);
6581 if (!mode) {
6582 PyErr_NoMemory();
6583 return NULL;
6584 }
6585 strcpy(mode, orgmode);
6586 if (_PyFile_SanitizeMode(mode)) {
6587 PyMem_FREE(mode);
Thomas Heller1f043e22002-11-07 16:00:59 +00006588 return NULL;
6589 }
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006590 if (!_PyVerify_fd(fd))
6591 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006592 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006593#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Georg Brandl54a188a2006-03-31 20:00:11 +00006594 if (mode[0] == 'a') {
6595 /* try to make sure the O_APPEND flag is set */
6596 int flags;
6597 flags = fcntl(fd, F_GETFL);
6598 if (flags != -1)
6599 fcntl(fd, F_SETFL, flags | O_APPEND);
6600 fp = fdopen(fd, mode);
Thomas Wouters2a9a6b02006-03-31 22:38:19 +00006601 if (fp == NULL && flags != -1)
Georg Brandl54a188a2006-03-31 20:00:11 +00006602 /* restore old mode if fdopen failed */
6603 fcntl(fd, F_SETFL, flags);
6604 } else {
6605 fp = fdopen(fd, mode);
6606 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006607#else
6608 fp = fdopen(fd, mode);
6609#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006610 Py_END_ALLOW_THREADS
Neal Norwitzd83eb312007-05-02 04:47:55 +00006611 PyMem_FREE(mode);
Guido van Rossum687dd131993-05-17 08:34:16 +00006612 if (fp == NULL)
6613 return posix_error();
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006614 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006615 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00006616 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006617 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006618}
6619
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006620PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006621"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006622Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006623connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006624
6625static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006626posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006627{
6628 int fd;
6629 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6630 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006631 if (!_PyVerify_fd(fd))
6632 return PyBool_FromLong(0);
Fred Drake106c1a02002-04-23 15:58:02 +00006633 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006634}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006635
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006636#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006637PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006638"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006639Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006640
Barry Warsaw53699e91996-12-10 23:23:01 +00006641static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006642posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006643{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006644#if defined(PYOS_OS2)
6645 HFILE read, write;
6646 APIRET rc;
6647
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006648 Py_BEGIN_ALLOW_THREADS
6649 rc = DosCreatePipe( &read, &write, 4096);
6650 Py_END_ALLOW_THREADS
6651 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006652 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006653
6654 return Py_BuildValue("(ii)", read, write);
6655#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006656#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00006657 int fds[2];
6658 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00006659 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006660 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00006661 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006662 if (res != 0)
6663 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006664 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006665#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00006666 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006667 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00006668 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00006669 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006670 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00006671 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00006672 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006673 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00006674 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6675 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006676 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006677#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006678#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006679}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006680#endif /* HAVE_PIPE */
6681
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006682
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006683#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006684PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006685"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006686Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006687
Barry Warsaw53699e91996-12-10 23:23:01 +00006688static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006689posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006690{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006691 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006692 int mode = 0666;
6693 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006694 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006695 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006696 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006697 res = mkfifo(filename, mode);
6698 Py_END_ALLOW_THREADS
6699 if (res < 0)
6700 return posix_error();
6701 Py_INCREF(Py_None);
6702 return Py_None;
6703}
6704#endif
6705
6706
Neal Norwitz11690112002-07-30 01:08:28 +00006707#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006708PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006709"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006710Create a filesystem node (file, device special file or named pipe)\n\
6711named filename. mode specifies both the permissions to use and the\n\
6712type of node to be created, being combined (bitwise OR) with one of\n\
6713S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006714device defines the newly created device special file (probably using\n\
6715os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006716
6717
6718static PyObject *
6719posix_mknod(PyObject *self, PyObject *args)
6720{
6721 char *filename;
6722 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006723 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006724 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00006725 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006726 return NULL;
6727 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006728 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00006729 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006730 if (res < 0)
6731 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006732 Py_INCREF(Py_None);
6733 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006734}
6735#endif
6736
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006737#ifdef HAVE_DEVICE_MACROS
6738PyDoc_STRVAR(posix_major__doc__,
6739"major(device) -> major number\n\
6740Extracts a device major number from a raw device number.");
6741
6742static PyObject *
6743posix_major(PyObject *self, PyObject *args)
6744{
6745 int device;
6746 if (!PyArg_ParseTuple(args, "i:major", &device))
6747 return NULL;
6748 return PyInt_FromLong((long)major(device));
6749}
6750
6751PyDoc_STRVAR(posix_minor__doc__,
6752"minor(device) -> minor number\n\
6753Extracts a device minor number from a raw device number.");
6754
6755static PyObject *
6756posix_minor(PyObject *self, PyObject *args)
6757{
6758 int device;
6759 if (!PyArg_ParseTuple(args, "i:minor", &device))
6760 return NULL;
6761 return PyInt_FromLong((long)minor(device));
6762}
6763
6764PyDoc_STRVAR(posix_makedev__doc__,
6765"makedev(major, minor) -> device number\n\
6766Composes a raw device number from the major and minor device numbers.");
6767
6768static PyObject *
6769posix_makedev(PyObject *self, PyObject *args)
6770{
6771 int major, minor;
6772 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6773 return NULL;
6774 return PyInt_FromLong((long)makedev(major, minor));
6775}
6776#endif /* device macros */
6777
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006778
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006779#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006780PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006781"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006782Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006783
Barry Warsaw53699e91996-12-10 23:23:01 +00006784static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006785posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006786{
6787 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006788 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006789 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006790 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006791
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006792 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006793 return NULL;
6794
6795#if !defined(HAVE_LARGEFILE_SUPPORT)
6796 length = PyInt_AsLong(lenobj);
6797#else
6798 length = PyLong_Check(lenobj) ?
6799 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6800#endif
6801 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006802 return NULL;
6803
Barry Warsaw53699e91996-12-10 23:23:01 +00006804 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006805 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006806 Py_END_ALLOW_THREADS
Benjamin Peterson943a6dd2009-01-19 15:51:27 +00006807 if (res < 0)
6808 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006809 Py_INCREF(Py_None);
6810 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006811}
6812#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006813
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006814#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006815PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006816"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006817Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006818
Fred Drake762e2061999-08-26 17:23:54 +00006819/* Save putenv() parameters as values here, so we can collect them when they
6820 * get re-set with another call for the same key. */
6821static PyObject *posix_putenv_garbage;
6822
Tim Peters5aa91602002-01-30 05:46:57 +00006823static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006824posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006825{
6826 char *s1, *s2;
Anthony Baxter64182fe2006-04-11 12:14:09 +00006827 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006828 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006829 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006830
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006831 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006832 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006833
6834#if defined(PYOS_OS2)
6835 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6836 APIRET rc;
6837
Guido van Rossumd48f2521997-12-05 22:19:34 +00006838 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6839 if (rc != NO_ERROR)
6840 return os2_error(rc);
6841
6842 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6843 APIRET rc;
6844
Guido van Rossumd48f2521997-12-05 22:19:34 +00006845 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6846 if (rc != NO_ERROR)
6847 return os2_error(rc);
6848 } else {
6849#endif
6850
Fred Drake762e2061999-08-26 17:23:54 +00006851 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006852 len = strlen(s1) + strlen(s2) + 2;
6853 /* len includes space for a trailing \0; the size arg to
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006854 PyString_FromStringAndSize does not count that */
6855 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006856 if (newstr == NULL)
6857 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006858 newenv = PyString_AS_STRING(newstr);
Anthony Baxter64182fe2006-04-11 12:14:09 +00006859 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6860 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006861 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006862 posix_error();
6863 return NULL;
6864 }
Fred Drake762e2061999-08-26 17:23:54 +00006865 /* Install the first arg and newstr in posix_putenv_garbage;
6866 * this will cause previous value to be collected. This has to
6867 * happen after the real putenv() call because the old value
6868 * was still accessible until then. */
6869 if (PyDict_SetItem(posix_putenv_garbage,
6870 PyTuple_GET_ITEM(args, 0), newstr)) {
6871 /* really not much we can do; just leak */
6872 PyErr_Clear();
6873 }
6874 else {
6875 Py_DECREF(newstr);
6876 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006877
6878#if defined(PYOS_OS2)
6879 }
6880#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006881 Py_INCREF(Py_None);
6882 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006883}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006884#endif /* putenv */
6885
Guido van Rossumc524d952001-10-19 01:31:59 +00006886#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006887PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006888"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006889Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006890
6891static PyObject *
6892posix_unsetenv(PyObject *self, PyObject *args)
6893{
6894 char *s1;
6895
6896 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6897 return NULL;
6898
6899 unsetenv(s1);
6900
6901 /* Remove the key from posix_putenv_garbage;
6902 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006903 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006904 * old value was still accessible until then.
6905 */
6906 if (PyDict_DelItem(posix_putenv_garbage,
6907 PyTuple_GET_ITEM(args, 0))) {
6908 /* really not much we can do; just leak */
6909 PyErr_Clear();
6910 }
6911
6912 Py_INCREF(Py_None);
6913 return Py_None;
6914}
6915#endif /* unsetenv */
6916
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006917PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006918"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006919Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006920
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006921static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006922posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006923{
6924 int code;
6925 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006926 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006927 return NULL;
6928 message = strerror(code);
6929 if (message == NULL) {
6930 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006931 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006932 return NULL;
6933 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006934 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006935}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006936
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006937
Guido van Rossumc9641791998-08-04 15:26:23 +00006938#ifdef HAVE_SYS_WAIT_H
6939
Fred Drake106c1a02002-04-23 15:58:02 +00006940#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006941PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006942"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006943Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006944
6945static PyObject *
6946posix_WCOREDUMP(PyObject *self, PyObject *args)
6947{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006948 WAIT_TYPE status;
6949 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006950
Neal Norwitzd5a37542006-03-20 06:48:34 +00006951 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006952 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006953
6954 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006955}
6956#endif /* WCOREDUMP */
6957
6958#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006959PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006960"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006961Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006962job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006963
6964static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006965posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006966{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006967 WAIT_TYPE status;
6968 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006969
Neal Norwitzd5a37542006-03-20 06:48:34 +00006970 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006971 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006972
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006973 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006974}
6975#endif /* WIFCONTINUED */
6976
Guido van Rossumc9641791998-08-04 15:26:23 +00006977#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006978PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006979"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006980Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006981
6982static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006983posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006984{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006985 WAIT_TYPE status;
6986 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006987
Neal Norwitzd5a37542006-03-20 06:48:34 +00006988 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006989 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006990
Fred Drake106c1a02002-04-23 15:58:02 +00006991 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006992}
6993#endif /* WIFSTOPPED */
6994
6995#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006996PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006997"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006998Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006999
7000static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007001posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007002{
Neal Norwitzd5a37542006-03-20 06:48:34 +00007003 WAIT_TYPE status;
7004 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007005
Neal Norwitzd5a37542006-03-20 06:48:34 +00007006 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007007 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007008
Fred Drake106c1a02002-04-23 15:58:02 +00007009 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007010}
7011#endif /* WIFSIGNALED */
7012
7013#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007014PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007015"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007016Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007017system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007018
7019static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007020posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007021{
Neal Norwitzd5a37542006-03-20 06:48:34 +00007022 WAIT_TYPE status;
7023 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007024
Neal Norwitzd5a37542006-03-20 06:48:34 +00007025 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007026 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007027
Fred Drake106c1a02002-04-23 15:58:02 +00007028 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007029}
7030#endif /* WIFEXITED */
7031
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007032#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007033PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007034"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007035Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007036
7037static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007038posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007039{
Neal Norwitzd5a37542006-03-20 06:48:34 +00007040 WAIT_TYPE status;
7041 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007042
Neal Norwitzd5a37542006-03-20 06:48:34 +00007043 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007044 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007045
Guido van Rossumc9641791998-08-04 15:26:23 +00007046 return Py_BuildValue("i", WEXITSTATUS(status));
7047}
7048#endif /* WEXITSTATUS */
7049
7050#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007051PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007052"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007053Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007054value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007055
7056static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007057posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007058{
Neal Norwitzd5a37542006-03-20 06:48:34 +00007059 WAIT_TYPE status;
7060 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007061
Neal Norwitzd5a37542006-03-20 06:48:34 +00007062 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007063 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007064
Guido van Rossumc9641791998-08-04 15:26:23 +00007065 return Py_BuildValue("i", WTERMSIG(status));
7066}
7067#endif /* WTERMSIG */
7068
7069#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007070PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007071"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007072Return the signal that stopped the process that provided\n\
7073the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007074
7075static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007076posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007077{
Neal Norwitzd5a37542006-03-20 06:48:34 +00007078 WAIT_TYPE status;
7079 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007080
Neal Norwitzd5a37542006-03-20 06:48:34 +00007081 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007082 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007083
Guido van Rossumc9641791998-08-04 15:26:23 +00007084 return Py_BuildValue("i", WSTOPSIG(status));
7085}
7086#endif /* WSTOPSIG */
7087
7088#endif /* HAVE_SYS_WAIT_H */
7089
7090
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007091#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00007092#ifdef _SCO_DS
7093/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7094 needed definitions in sys/statvfs.h */
7095#define _SVID3
7096#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007097#include <sys/statvfs.h>
7098
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007099static PyObject*
7100_pystatvfs_fromstructstatvfs(struct statvfs st) {
7101 PyObject *v = PyStructSequence_New(&StatVFSResultType);
7102 if (v == NULL)
7103 return NULL;
7104
7105#if !defined(HAVE_LARGEFILE_SUPPORT)
7106 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7107 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7108 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7109 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7110 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7111 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7112 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7113 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
7114 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7115 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
7116#else
7117 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7118 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00007119 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007120 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00007121 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007122 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007123 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007124 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00007125 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007126 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00007127 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007128 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00007129 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007130 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007131 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7132 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
7133#endif
7134
7135 return v;
7136}
7137
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007138PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007139"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007140Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007141
7142static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007143posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007144{
7145 int fd, res;
7146 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007147
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007148 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00007149 return NULL;
7150 Py_BEGIN_ALLOW_THREADS
7151 res = fstatvfs(fd, &st);
7152 Py_END_ALLOW_THREADS
7153 if (res != 0)
7154 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007155
7156 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007157}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007158#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007159
7160
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007161#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007162#include <sys/statvfs.h>
7163
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007164PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007165"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007166Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007167
7168static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007169posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007170{
7171 char *path;
7172 int res;
7173 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007174 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00007175 return NULL;
7176 Py_BEGIN_ALLOW_THREADS
7177 res = statvfs(path, &st);
7178 Py_END_ALLOW_THREADS
7179 if (res != 0)
7180 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007181
7182 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007183}
7184#endif /* HAVE_STATVFS */
7185
7186
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007187#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007188PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007189"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007190Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007191The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007192or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007193
7194static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007195posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007196{
7197 PyObject *result = NULL;
7198 char *dir = NULL;
7199 char *pfx = NULL;
7200 char *name;
7201
7202 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
7203 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007204
7205 if (PyErr_Warn(PyExc_RuntimeWarning,
7206 "tempnam is a potential security risk to your program") < 0)
7207 return NULL;
7208
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007209#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007210 name = _tempnam(dir, pfx);
7211#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007212 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007213#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007214 if (name == NULL)
7215 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007216 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007217 free(name);
7218 return result;
7219}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007220#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007221
7222
7223#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007224PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007225"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007226Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007227
7228static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007229posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007230{
7231 FILE *fp;
7232
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007233 fp = tmpfile();
7234 if (fp == NULL)
7235 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007236 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007237}
7238#endif
7239
7240
7241#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007242PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007243"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007244Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007245
7246static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007247posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007248{
7249 char buffer[L_tmpnam];
7250 char *name;
7251
Skip Montanaro95618b52001-08-18 18:52:10 +00007252 if (PyErr_Warn(PyExc_RuntimeWarning,
7253 "tmpnam is a potential security risk to your program") < 0)
7254 return NULL;
7255
Greg Wardb48bc172000-03-01 21:51:56 +00007256#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007257 name = tmpnam_r(buffer);
7258#else
7259 name = tmpnam(buffer);
7260#endif
7261 if (name == NULL) {
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007262 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007263#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007264 "unexpected NULL from tmpnam_r"
7265#else
7266 "unexpected NULL from tmpnam"
7267#endif
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007268 );
7269 PyErr_SetObject(PyExc_OSError, err);
7270 Py_XDECREF(err);
7271 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007272 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007273 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007274}
7275#endif
7276
7277
Fred Drakec9680921999-12-13 16:37:25 +00007278/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7279 * It maps strings representing configuration variable names to
7280 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007281 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007282 * rarely-used constants. There are three separate tables that use
7283 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007284 *
7285 * This code is always included, even if none of the interfaces that
7286 * need it are included. The #if hackery needed to avoid it would be
7287 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007288 */
7289struct constdef {
7290 char *name;
7291 long value;
7292};
7293
Fred Drake12c6e2d1999-12-14 21:25:03 +00007294static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007295conv_confname(PyObject *arg, int *valuep, struct constdef *table,
7296 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007297{
7298 if (PyInt_Check(arg)) {
7299 *valuep = PyInt_AS_LONG(arg);
7300 return 1;
7301 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007302 if (PyString_Check(arg)) {
Fred Drake12c6e2d1999-12-14 21:25:03 +00007303 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00007304 size_t lo = 0;
7305 size_t mid;
7306 size_t hi = tablesize;
7307 int cmp;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007308 char *confname = PyString_AS_STRING(arg);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007309 while (lo < hi) {
7310 mid = (lo + hi) / 2;
7311 cmp = strcmp(confname, table[mid].name);
7312 if (cmp < 0)
7313 hi = mid;
7314 else if (cmp > 0)
7315 lo = mid + 1;
7316 else {
7317 *valuep = table[mid].value;
7318 return 1;
7319 }
7320 }
7321 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
7322 }
7323 else
7324 PyErr_SetString(PyExc_TypeError,
7325 "configuration names must be strings or integers");
7326 return 0;
7327}
7328
7329
7330#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7331static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007332#ifdef _PC_ABI_AIO_XFER_MAX
7333 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
7334#endif
7335#ifdef _PC_ABI_ASYNC_IO
7336 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
7337#endif
Fred Drakec9680921999-12-13 16:37:25 +00007338#ifdef _PC_ASYNC_IO
7339 {"PC_ASYNC_IO", _PC_ASYNC_IO},
7340#endif
7341#ifdef _PC_CHOWN_RESTRICTED
7342 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
7343#endif
7344#ifdef _PC_FILESIZEBITS
7345 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
7346#endif
7347#ifdef _PC_LAST
7348 {"PC_LAST", _PC_LAST},
7349#endif
7350#ifdef _PC_LINK_MAX
7351 {"PC_LINK_MAX", _PC_LINK_MAX},
7352#endif
7353#ifdef _PC_MAX_CANON
7354 {"PC_MAX_CANON", _PC_MAX_CANON},
7355#endif
7356#ifdef _PC_MAX_INPUT
7357 {"PC_MAX_INPUT", _PC_MAX_INPUT},
7358#endif
7359#ifdef _PC_NAME_MAX
7360 {"PC_NAME_MAX", _PC_NAME_MAX},
7361#endif
7362#ifdef _PC_NO_TRUNC
7363 {"PC_NO_TRUNC", _PC_NO_TRUNC},
7364#endif
7365#ifdef _PC_PATH_MAX
7366 {"PC_PATH_MAX", _PC_PATH_MAX},
7367#endif
7368#ifdef _PC_PIPE_BUF
7369 {"PC_PIPE_BUF", _PC_PIPE_BUF},
7370#endif
7371#ifdef _PC_PRIO_IO
7372 {"PC_PRIO_IO", _PC_PRIO_IO},
7373#endif
7374#ifdef _PC_SOCK_MAXBUF
7375 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
7376#endif
7377#ifdef _PC_SYNC_IO
7378 {"PC_SYNC_IO", _PC_SYNC_IO},
7379#endif
7380#ifdef _PC_VDISABLE
7381 {"PC_VDISABLE", _PC_VDISABLE},
7382#endif
7383};
7384
Fred Drakec9680921999-12-13 16:37:25 +00007385static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007386conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007387{
7388 return conv_confname(arg, valuep, posix_constants_pathconf,
7389 sizeof(posix_constants_pathconf)
7390 / sizeof(struct constdef));
7391}
7392#endif
7393
7394#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007395PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007396"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007397Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007398If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007399
7400static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007401posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007402{
7403 PyObject *result = NULL;
7404 int name, fd;
7405
Fred Drake12c6e2d1999-12-14 21:25:03 +00007406 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7407 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00007408 long limit;
7409
7410 errno = 0;
7411 limit = fpathconf(fd, name);
7412 if (limit == -1 && errno != 0)
7413 posix_error();
7414 else
7415 result = PyInt_FromLong(limit);
7416 }
7417 return result;
7418}
7419#endif
7420
7421
7422#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007423PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007424"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007425Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007426If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007427
7428static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007429posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007430{
7431 PyObject *result = NULL;
7432 int name;
7433 char *path;
7434
7435 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7436 conv_path_confname, &name)) {
7437 long limit;
7438
7439 errno = 0;
7440 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007441 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00007442 if (errno == EINVAL)
7443 /* could be a path or name problem */
7444 posix_error();
7445 else
7446 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007447 }
Fred Drakec9680921999-12-13 16:37:25 +00007448 else
7449 result = PyInt_FromLong(limit);
7450 }
7451 return result;
7452}
7453#endif
7454
7455#ifdef HAVE_CONFSTR
7456static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007457#ifdef _CS_ARCHITECTURE
7458 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
7459#endif
7460#ifdef _CS_HOSTNAME
7461 {"CS_HOSTNAME", _CS_HOSTNAME},
7462#endif
7463#ifdef _CS_HW_PROVIDER
7464 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
7465#endif
7466#ifdef _CS_HW_SERIAL
7467 {"CS_HW_SERIAL", _CS_HW_SERIAL},
7468#endif
7469#ifdef _CS_INITTAB_NAME
7470 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
7471#endif
Fred Drakec9680921999-12-13 16:37:25 +00007472#ifdef _CS_LFS64_CFLAGS
7473 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
7474#endif
7475#ifdef _CS_LFS64_LDFLAGS
7476 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
7477#endif
7478#ifdef _CS_LFS64_LIBS
7479 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
7480#endif
7481#ifdef _CS_LFS64_LINTFLAGS
7482 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
7483#endif
7484#ifdef _CS_LFS_CFLAGS
7485 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
7486#endif
7487#ifdef _CS_LFS_LDFLAGS
7488 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
7489#endif
7490#ifdef _CS_LFS_LIBS
7491 {"CS_LFS_LIBS", _CS_LFS_LIBS},
7492#endif
7493#ifdef _CS_LFS_LINTFLAGS
7494 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
7495#endif
Fred Draked86ed291999-12-15 15:34:33 +00007496#ifdef _CS_MACHINE
7497 {"CS_MACHINE", _CS_MACHINE},
7498#endif
Fred Drakec9680921999-12-13 16:37:25 +00007499#ifdef _CS_PATH
7500 {"CS_PATH", _CS_PATH},
7501#endif
Fred Draked86ed291999-12-15 15:34:33 +00007502#ifdef _CS_RELEASE
7503 {"CS_RELEASE", _CS_RELEASE},
7504#endif
7505#ifdef _CS_SRPC_DOMAIN
7506 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
7507#endif
7508#ifdef _CS_SYSNAME
7509 {"CS_SYSNAME", _CS_SYSNAME},
7510#endif
7511#ifdef _CS_VERSION
7512 {"CS_VERSION", _CS_VERSION},
7513#endif
Fred Drakec9680921999-12-13 16:37:25 +00007514#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
7515 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
7516#endif
7517#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
7518 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
7519#endif
7520#ifdef _CS_XBS5_ILP32_OFF32_LIBS
7521 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
7522#endif
7523#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
7524 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
7525#endif
7526#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
7527 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
7528#endif
7529#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
7530 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
7531#endif
7532#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
7533 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
7534#endif
7535#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
7536 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
7537#endif
7538#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7539 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
7540#endif
7541#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7542 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7543#endif
7544#ifdef _CS_XBS5_LP64_OFF64_LIBS
7545 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7546#endif
7547#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7548 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7549#endif
7550#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7551 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7552#endif
7553#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7554 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7555#endif
7556#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7557 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7558#endif
7559#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7560 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7561#endif
Fred Draked86ed291999-12-15 15:34:33 +00007562#ifdef _MIPS_CS_AVAIL_PROCESSORS
7563 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7564#endif
7565#ifdef _MIPS_CS_BASE
7566 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7567#endif
7568#ifdef _MIPS_CS_HOSTID
7569 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7570#endif
7571#ifdef _MIPS_CS_HW_NAME
7572 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7573#endif
7574#ifdef _MIPS_CS_NUM_PROCESSORS
7575 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7576#endif
7577#ifdef _MIPS_CS_OSREL_MAJ
7578 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7579#endif
7580#ifdef _MIPS_CS_OSREL_MIN
7581 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7582#endif
7583#ifdef _MIPS_CS_OSREL_PATCH
7584 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7585#endif
7586#ifdef _MIPS_CS_OS_NAME
7587 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7588#endif
7589#ifdef _MIPS_CS_OS_PROVIDER
7590 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7591#endif
7592#ifdef _MIPS_CS_PROCESSORS
7593 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7594#endif
7595#ifdef _MIPS_CS_SERIAL
7596 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7597#endif
7598#ifdef _MIPS_CS_VENDOR
7599 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7600#endif
Fred Drakec9680921999-12-13 16:37:25 +00007601};
7602
7603static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007604conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007605{
7606 return conv_confname(arg, valuep, posix_constants_confstr,
7607 sizeof(posix_constants_confstr)
7608 / sizeof(struct constdef));
7609}
7610
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007611PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007612"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007613Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007614
7615static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007616posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007617{
7618 PyObject *result = NULL;
7619 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007620 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007621
7622 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Skip Montanarodd527fc2006-04-18 00:49:49 +00007623 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007624
Fred Drakec9680921999-12-13 16:37:25 +00007625 errno = 0;
Skip Montanarodd527fc2006-04-18 00:49:49 +00007626 len = confstr(name, buffer, sizeof(buffer));
Skip Montanaro94785ef2006-04-20 01:29:48 +00007627 if (len == 0) {
7628 if (errno) {
7629 posix_error();
7630 }
7631 else {
7632 result = Py_None;
7633 Py_INCREF(Py_None);
7634 }
Fred Drakec9680921999-12-13 16:37:25 +00007635 }
7636 else {
Neal Norwitz0d21b1e2006-04-20 06:44:42 +00007637 if ((unsigned int)len >= sizeof(buffer)) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007638 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007639 if (result != NULL)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007640 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00007641 }
7642 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007643 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007644 }
7645 }
7646 return result;
7647}
7648#endif
7649
7650
7651#ifdef HAVE_SYSCONF
7652static struct constdef posix_constants_sysconf[] = {
7653#ifdef _SC_2_CHAR_TERM
7654 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7655#endif
7656#ifdef _SC_2_C_BIND
7657 {"SC_2_C_BIND", _SC_2_C_BIND},
7658#endif
7659#ifdef _SC_2_C_DEV
7660 {"SC_2_C_DEV", _SC_2_C_DEV},
7661#endif
7662#ifdef _SC_2_C_VERSION
7663 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7664#endif
7665#ifdef _SC_2_FORT_DEV
7666 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7667#endif
7668#ifdef _SC_2_FORT_RUN
7669 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7670#endif
7671#ifdef _SC_2_LOCALEDEF
7672 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7673#endif
7674#ifdef _SC_2_SW_DEV
7675 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7676#endif
7677#ifdef _SC_2_UPE
7678 {"SC_2_UPE", _SC_2_UPE},
7679#endif
7680#ifdef _SC_2_VERSION
7681 {"SC_2_VERSION", _SC_2_VERSION},
7682#endif
Fred Draked86ed291999-12-15 15:34:33 +00007683#ifdef _SC_ABI_ASYNCHRONOUS_IO
7684 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7685#endif
7686#ifdef _SC_ACL
7687 {"SC_ACL", _SC_ACL},
7688#endif
Fred Drakec9680921999-12-13 16:37:25 +00007689#ifdef _SC_AIO_LISTIO_MAX
7690 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7691#endif
Fred Drakec9680921999-12-13 16:37:25 +00007692#ifdef _SC_AIO_MAX
7693 {"SC_AIO_MAX", _SC_AIO_MAX},
7694#endif
7695#ifdef _SC_AIO_PRIO_DELTA_MAX
7696 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7697#endif
7698#ifdef _SC_ARG_MAX
7699 {"SC_ARG_MAX", _SC_ARG_MAX},
7700#endif
7701#ifdef _SC_ASYNCHRONOUS_IO
7702 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7703#endif
7704#ifdef _SC_ATEXIT_MAX
7705 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7706#endif
Fred Draked86ed291999-12-15 15:34:33 +00007707#ifdef _SC_AUDIT
7708 {"SC_AUDIT", _SC_AUDIT},
7709#endif
Fred Drakec9680921999-12-13 16:37:25 +00007710#ifdef _SC_AVPHYS_PAGES
7711 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7712#endif
7713#ifdef _SC_BC_BASE_MAX
7714 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7715#endif
7716#ifdef _SC_BC_DIM_MAX
7717 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7718#endif
7719#ifdef _SC_BC_SCALE_MAX
7720 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7721#endif
7722#ifdef _SC_BC_STRING_MAX
7723 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7724#endif
Fred Draked86ed291999-12-15 15:34:33 +00007725#ifdef _SC_CAP
7726 {"SC_CAP", _SC_CAP},
7727#endif
Fred Drakec9680921999-12-13 16:37:25 +00007728#ifdef _SC_CHARCLASS_NAME_MAX
7729 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7730#endif
7731#ifdef _SC_CHAR_BIT
7732 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7733#endif
7734#ifdef _SC_CHAR_MAX
7735 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7736#endif
7737#ifdef _SC_CHAR_MIN
7738 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7739#endif
7740#ifdef _SC_CHILD_MAX
7741 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7742#endif
7743#ifdef _SC_CLK_TCK
7744 {"SC_CLK_TCK", _SC_CLK_TCK},
7745#endif
7746#ifdef _SC_COHER_BLKSZ
7747 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7748#endif
7749#ifdef _SC_COLL_WEIGHTS_MAX
7750 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7751#endif
7752#ifdef _SC_DCACHE_ASSOC
7753 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7754#endif
7755#ifdef _SC_DCACHE_BLKSZ
7756 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7757#endif
7758#ifdef _SC_DCACHE_LINESZ
7759 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7760#endif
7761#ifdef _SC_DCACHE_SZ
7762 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7763#endif
7764#ifdef _SC_DCACHE_TBLKSZ
7765 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7766#endif
7767#ifdef _SC_DELAYTIMER_MAX
7768 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7769#endif
7770#ifdef _SC_EQUIV_CLASS_MAX
7771 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7772#endif
7773#ifdef _SC_EXPR_NEST_MAX
7774 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7775#endif
7776#ifdef _SC_FSYNC
7777 {"SC_FSYNC", _SC_FSYNC},
7778#endif
7779#ifdef _SC_GETGR_R_SIZE_MAX
7780 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7781#endif
7782#ifdef _SC_GETPW_R_SIZE_MAX
7783 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7784#endif
7785#ifdef _SC_ICACHE_ASSOC
7786 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7787#endif
7788#ifdef _SC_ICACHE_BLKSZ
7789 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7790#endif
7791#ifdef _SC_ICACHE_LINESZ
7792 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7793#endif
7794#ifdef _SC_ICACHE_SZ
7795 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7796#endif
Fred Draked86ed291999-12-15 15:34:33 +00007797#ifdef _SC_INF
7798 {"SC_INF", _SC_INF},
7799#endif
Fred Drakec9680921999-12-13 16:37:25 +00007800#ifdef _SC_INT_MAX
7801 {"SC_INT_MAX", _SC_INT_MAX},
7802#endif
7803#ifdef _SC_INT_MIN
7804 {"SC_INT_MIN", _SC_INT_MIN},
7805#endif
7806#ifdef _SC_IOV_MAX
7807 {"SC_IOV_MAX", _SC_IOV_MAX},
7808#endif
Fred Draked86ed291999-12-15 15:34:33 +00007809#ifdef _SC_IP_SECOPTS
7810 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7811#endif
Fred Drakec9680921999-12-13 16:37:25 +00007812#ifdef _SC_JOB_CONTROL
7813 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7814#endif
Fred Draked86ed291999-12-15 15:34:33 +00007815#ifdef _SC_KERN_POINTERS
7816 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7817#endif
7818#ifdef _SC_KERN_SIM
7819 {"SC_KERN_SIM", _SC_KERN_SIM},
7820#endif
Fred Drakec9680921999-12-13 16:37:25 +00007821#ifdef _SC_LINE_MAX
7822 {"SC_LINE_MAX", _SC_LINE_MAX},
7823#endif
7824#ifdef _SC_LOGIN_NAME_MAX
7825 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7826#endif
7827#ifdef _SC_LOGNAME_MAX
7828 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7829#endif
7830#ifdef _SC_LONG_BIT
7831 {"SC_LONG_BIT", _SC_LONG_BIT},
7832#endif
Fred Draked86ed291999-12-15 15:34:33 +00007833#ifdef _SC_MAC
7834 {"SC_MAC", _SC_MAC},
7835#endif
Fred Drakec9680921999-12-13 16:37:25 +00007836#ifdef _SC_MAPPED_FILES
7837 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7838#endif
7839#ifdef _SC_MAXPID
7840 {"SC_MAXPID", _SC_MAXPID},
7841#endif
7842#ifdef _SC_MB_LEN_MAX
7843 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7844#endif
7845#ifdef _SC_MEMLOCK
7846 {"SC_MEMLOCK", _SC_MEMLOCK},
7847#endif
7848#ifdef _SC_MEMLOCK_RANGE
7849 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7850#endif
7851#ifdef _SC_MEMORY_PROTECTION
7852 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7853#endif
7854#ifdef _SC_MESSAGE_PASSING
7855 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7856#endif
Fred Draked86ed291999-12-15 15:34:33 +00007857#ifdef _SC_MMAP_FIXED_ALIGNMENT
7858 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7859#endif
Fred Drakec9680921999-12-13 16:37:25 +00007860#ifdef _SC_MQ_OPEN_MAX
7861 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7862#endif
7863#ifdef _SC_MQ_PRIO_MAX
7864 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7865#endif
Fred Draked86ed291999-12-15 15:34:33 +00007866#ifdef _SC_NACLS_MAX
7867 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7868#endif
Fred Drakec9680921999-12-13 16:37:25 +00007869#ifdef _SC_NGROUPS_MAX
7870 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7871#endif
7872#ifdef _SC_NL_ARGMAX
7873 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7874#endif
7875#ifdef _SC_NL_LANGMAX
7876 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7877#endif
7878#ifdef _SC_NL_MSGMAX
7879 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7880#endif
7881#ifdef _SC_NL_NMAX
7882 {"SC_NL_NMAX", _SC_NL_NMAX},
7883#endif
7884#ifdef _SC_NL_SETMAX
7885 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7886#endif
7887#ifdef _SC_NL_TEXTMAX
7888 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7889#endif
7890#ifdef _SC_NPROCESSORS_CONF
7891 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7892#endif
7893#ifdef _SC_NPROCESSORS_ONLN
7894 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7895#endif
Fred Draked86ed291999-12-15 15:34:33 +00007896#ifdef _SC_NPROC_CONF
7897 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7898#endif
7899#ifdef _SC_NPROC_ONLN
7900 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7901#endif
Fred Drakec9680921999-12-13 16:37:25 +00007902#ifdef _SC_NZERO
7903 {"SC_NZERO", _SC_NZERO},
7904#endif
7905#ifdef _SC_OPEN_MAX
7906 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7907#endif
7908#ifdef _SC_PAGESIZE
7909 {"SC_PAGESIZE", _SC_PAGESIZE},
7910#endif
7911#ifdef _SC_PAGE_SIZE
7912 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7913#endif
7914#ifdef _SC_PASS_MAX
7915 {"SC_PASS_MAX", _SC_PASS_MAX},
7916#endif
7917#ifdef _SC_PHYS_PAGES
7918 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7919#endif
7920#ifdef _SC_PII
7921 {"SC_PII", _SC_PII},
7922#endif
7923#ifdef _SC_PII_INTERNET
7924 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7925#endif
7926#ifdef _SC_PII_INTERNET_DGRAM
7927 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7928#endif
7929#ifdef _SC_PII_INTERNET_STREAM
7930 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7931#endif
7932#ifdef _SC_PII_OSI
7933 {"SC_PII_OSI", _SC_PII_OSI},
7934#endif
7935#ifdef _SC_PII_OSI_CLTS
7936 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7937#endif
7938#ifdef _SC_PII_OSI_COTS
7939 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7940#endif
7941#ifdef _SC_PII_OSI_M
7942 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7943#endif
7944#ifdef _SC_PII_SOCKET
7945 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7946#endif
7947#ifdef _SC_PII_XTI
7948 {"SC_PII_XTI", _SC_PII_XTI},
7949#endif
7950#ifdef _SC_POLL
7951 {"SC_POLL", _SC_POLL},
7952#endif
7953#ifdef _SC_PRIORITIZED_IO
7954 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7955#endif
7956#ifdef _SC_PRIORITY_SCHEDULING
7957 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7958#endif
7959#ifdef _SC_REALTIME_SIGNALS
7960 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7961#endif
7962#ifdef _SC_RE_DUP_MAX
7963 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7964#endif
7965#ifdef _SC_RTSIG_MAX
7966 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7967#endif
7968#ifdef _SC_SAVED_IDS
7969 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7970#endif
7971#ifdef _SC_SCHAR_MAX
7972 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7973#endif
7974#ifdef _SC_SCHAR_MIN
7975 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7976#endif
7977#ifdef _SC_SELECT
7978 {"SC_SELECT", _SC_SELECT},
7979#endif
7980#ifdef _SC_SEMAPHORES
7981 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7982#endif
7983#ifdef _SC_SEM_NSEMS_MAX
7984 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7985#endif
7986#ifdef _SC_SEM_VALUE_MAX
7987 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7988#endif
7989#ifdef _SC_SHARED_MEMORY_OBJECTS
7990 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7991#endif
7992#ifdef _SC_SHRT_MAX
7993 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7994#endif
7995#ifdef _SC_SHRT_MIN
7996 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7997#endif
7998#ifdef _SC_SIGQUEUE_MAX
7999 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
8000#endif
8001#ifdef _SC_SIGRT_MAX
8002 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
8003#endif
8004#ifdef _SC_SIGRT_MIN
8005 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
8006#endif
Fred Draked86ed291999-12-15 15:34:33 +00008007#ifdef _SC_SOFTPOWER
8008 {"SC_SOFTPOWER", _SC_SOFTPOWER},
8009#endif
Fred Drakec9680921999-12-13 16:37:25 +00008010#ifdef _SC_SPLIT_CACHE
8011 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
8012#endif
8013#ifdef _SC_SSIZE_MAX
8014 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
8015#endif
8016#ifdef _SC_STACK_PROT
8017 {"SC_STACK_PROT", _SC_STACK_PROT},
8018#endif
8019#ifdef _SC_STREAM_MAX
8020 {"SC_STREAM_MAX", _SC_STREAM_MAX},
8021#endif
8022#ifdef _SC_SYNCHRONIZED_IO
8023 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
8024#endif
8025#ifdef _SC_THREADS
8026 {"SC_THREADS", _SC_THREADS},
8027#endif
8028#ifdef _SC_THREAD_ATTR_STACKADDR
8029 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
8030#endif
8031#ifdef _SC_THREAD_ATTR_STACKSIZE
8032 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
8033#endif
8034#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
8035 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
8036#endif
8037#ifdef _SC_THREAD_KEYS_MAX
8038 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
8039#endif
8040#ifdef _SC_THREAD_PRIORITY_SCHEDULING
8041 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
8042#endif
8043#ifdef _SC_THREAD_PRIO_INHERIT
8044 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
8045#endif
8046#ifdef _SC_THREAD_PRIO_PROTECT
8047 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
8048#endif
8049#ifdef _SC_THREAD_PROCESS_SHARED
8050 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
8051#endif
8052#ifdef _SC_THREAD_SAFE_FUNCTIONS
8053 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
8054#endif
8055#ifdef _SC_THREAD_STACK_MIN
8056 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
8057#endif
8058#ifdef _SC_THREAD_THREADS_MAX
8059 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
8060#endif
8061#ifdef _SC_TIMERS
8062 {"SC_TIMERS", _SC_TIMERS},
8063#endif
8064#ifdef _SC_TIMER_MAX
8065 {"SC_TIMER_MAX", _SC_TIMER_MAX},
8066#endif
8067#ifdef _SC_TTY_NAME_MAX
8068 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
8069#endif
8070#ifdef _SC_TZNAME_MAX
8071 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
8072#endif
8073#ifdef _SC_T_IOV_MAX
8074 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
8075#endif
8076#ifdef _SC_UCHAR_MAX
8077 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
8078#endif
8079#ifdef _SC_UINT_MAX
8080 {"SC_UINT_MAX", _SC_UINT_MAX},
8081#endif
8082#ifdef _SC_UIO_MAXIOV
8083 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
8084#endif
8085#ifdef _SC_ULONG_MAX
8086 {"SC_ULONG_MAX", _SC_ULONG_MAX},
8087#endif
8088#ifdef _SC_USHRT_MAX
8089 {"SC_USHRT_MAX", _SC_USHRT_MAX},
8090#endif
8091#ifdef _SC_VERSION
8092 {"SC_VERSION", _SC_VERSION},
8093#endif
8094#ifdef _SC_WORD_BIT
8095 {"SC_WORD_BIT", _SC_WORD_BIT},
8096#endif
8097#ifdef _SC_XBS5_ILP32_OFF32
8098 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
8099#endif
8100#ifdef _SC_XBS5_ILP32_OFFBIG
8101 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
8102#endif
8103#ifdef _SC_XBS5_LP64_OFF64
8104 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
8105#endif
8106#ifdef _SC_XBS5_LPBIG_OFFBIG
8107 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
8108#endif
8109#ifdef _SC_XOPEN_CRYPT
8110 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
8111#endif
8112#ifdef _SC_XOPEN_ENH_I18N
8113 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
8114#endif
8115#ifdef _SC_XOPEN_LEGACY
8116 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
8117#endif
8118#ifdef _SC_XOPEN_REALTIME
8119 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
8120#endif
8121#ifdef _SC_XOPEN_REALTIME_THREADS
8122 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
8123#endif
8124#ifdef _SC_XOPEN_SHM
8125 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
8126#endif
8127#ifdef _SC_XOPEN_UNIX
8128 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
8129#endif
8130#ifdef _SC_XOPEN_VERSION
8131 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
8132#endif
8133#ifdef _SC_XOPEN_XCU_VERSION
8134 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
8135#endif
8136#ifdef _SC_XOPEN_XPG2
8137 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
8138#endif
8139#ifdef _SC_XOPEN_XPG3
8140 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
8141#endif
8142#ifdef _SC_XOPEN_XPG4
8143 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
8144#endif
8145};
8146
8147static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008148conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008149{
8150 return conv_confname(arg, valuep, posix_constants_sysconf,
8151 sizeof(posix_constants_sysconf)
8152 / sizeof(struct constdef));
8153}
8154
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008155PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008156"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008157Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008158
8159static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008160posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008161{
8162 PyObject *result = NULL;
8163 int name;
8164
8165 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
8166 int value;
8167
8168 errno = 0;
8169 value = sysconf(name);
8170 if (value == -1 && errno != 0)
8171 posix_error();
8172 else
8173 result = PyInt_FromLong(value);
8174 }
8175 return result;
8176}
8177#endif
8178
8179
Fred Drakebec628d1999-12-15 18:31:10 +00008180/* This code is used to ensure that the tables of configuration value names
8181 * are in sorted order as required by conv_confname(), and also to build the
8182 * the exported dictionaries that are used to publish information about the
8183 * names available on the host platform.
8184 *
8185 * Sorting the table at runtime ensures that the table is properly ordered
8186 * when used, even for platforms we're not able to test on. It also makes
8187 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008188 */
Fred Drakebec628d1999-12-15 18:31:10 +00008189
8190static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008191cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008192{
8193 const struct constdef *c1 =
8194 (const struct constdef *) v1;
8195 const struct constdef *c2 =
8196 (const struct constdef *) v2;
8197
8198 return strcmp(c1->name, c2->name);
8199}
8200
8201static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008202setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008203 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008204{
Fred Drakebec628d1999-12-15 18:31:10 +00008205 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008206 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008207
8208 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8209 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008210 if (d == NULL)
8211 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008212
Barry Warsaw3155db32000-04-13 15:20:40 +00008213 for (i=0; i < tablesize; ++i) {
8214 PyObject *o = PyInt_FromLong(table[i].value);
8215 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8216 Py_XDECREF(o);
8217 Py_DECREF(d);
8218 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008219 }
Barry Warsaw3155db32000-04-13 15:20:40 +00008220 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008221 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008222 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008223}
8224
Fred Drakebec628d1999-12-15 18:31:10 +00008225/* Return -1 on failure, 0 on success. */
8226static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008227setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008228{
8229#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008230 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008231 sizeof(posix_constants_pathconf)
8232 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008233 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008234 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008235#endif
8236#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008237 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008238 sizeof(posix_constants_confstr)
8239 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008240 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008241 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008242#endif
8243#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008244 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008245 sizeof(posix_constants_sysconf)
8246 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008247 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008248 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008249#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008250 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008251}
Fred Draked86ed291999-12-15 15:34:33 +00008252
8253
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008254PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008255"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008256Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008257in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008258
8259static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008260posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008261{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008262 abort();
8263 /*NOTREACHED*/
8264 Py_FatalError("abort() called from Python code didn't abort!");
8265 return NULL;
8266}
Fred Drakebec628d1999-12-15 18:31:10 +00008267
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008268#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008269PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008270"startfile(filepath [, operation]) - Start a file with its associated\n\
8271application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008272\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008273When \"operation\" is not specified or \"open\", this acts like\n\
8274double-clicking the file in Explorer, or giving the file name as an\n\
8275argument to the DOS \"start\" command: the file is opened with whatever\n\
8276application (if any) its extension is associated.\n\
8277When another \"operation\" is given, it specifies what should be done with\n\
8278the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008279\n\
8280startfile returns as soon as the associated application is launched.\n\
8281There is no option to wait for the application to close, and no way\n\
8282to retrieve the application's exit status.\n\
8283\n\
8284The filepath is relative to the current directory. If you want to use\n\
8285an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008286the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008287
8288static PyObject *
8289win32_startfile(PyObject *self, PyObject *args)
8290{
8291 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00008292 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008293 HINSTANCE rc;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008294
Georg Brandlad89dc82006-04-03 12:26:26 +00008295 if (unicode_file_names()) {
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008296 PyObject *unipath, *woperation = NULL;
Georg Brandlad89dc82006-04-03 12:26:26 +00008297 if (!PyArg_ParseTuple(args, "U|s:startfile",
8298 &unipath, &operation)) {
8299 PyErr_Clear();
8300 goto normal;
8301 }
8302
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008303
8304 if (operation) {
8305 woperation = PyUnicode_DecodeASCII(operation,
8306 strlen(operation), NULL);
8307 if (!woperation) {
8308 PyErr_Clear();
8309 operation = NULL;
8310 goto normal;
8311 }
Georg Brandlad89dc82006-04-03 12:26:26 +00008312 }
8313
8314 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008315 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Georg Brandlad89dc82006-04-03 12:26:26 +00008316 PyUnicode_AS_UNICODE(unipath),
Georg Brandlad89dc82006-04-03 12:26:26 +00008317 NULL, NULL, SW_SHOWNORMAL);
8318 Py_END_ALLOW_THREADS
8319
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008320 Py_XDECREF(woperation);
Georg Brandlad89dc82006-04-03 12:26:26 +00008321 if (rc <= (HINSTANCE)32) {
8322 PyObject *errval = win32_error_unicode("startfile",
8323 PyUnicode_AS_UNICODE(unipath));
8324 return errval;
8325 }
8326 Py_INCREF(Py_None);
8327 return Py_None;
8328 }
Georg Brandlad89dc82006-04-03 12:26:26 +00008329
8330normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00008331 if (!PyArg_ParseTuple(args, "et|s:startfile",
8332 Py_FileSystemDefaultEncoding, &filepath,
8333 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00008334 return NULL;
8335 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00008336 rc = ShellExecute((HWND)0, operation, filepath,
8337 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008338 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00008339 if (rc <= (HINSTANCE)32) {
8340 PyObject *errval = win32_error("startfile", filepath);
8341 PyMem_Free(filepath);
8342 return errval;
8343 }
8344 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008345 Py_INCREF(Py_None);
8346 return Py_None;
8347}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008348#endif /* MS_WINDOWS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008349
Martin v. Löwis438b5342002-12-27 10:16:42 +00008350#ifdef HAVE_GETLOADAVG
8351PyDoc_STRVAR(posix_getloadavg__doc__,
8352"getloadavg() -> (float, float, float)\n\n\
8353Return the number of processes in the system run queue averaged over\n\
8354the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8355was unobtainable");
8356
8357static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008358posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008359{
8360 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008361 if (getloadavg(loadavg, 3)!=3) {
8362 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8363 return NULL;
8364 } else
8365 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
8366}
8367#endif
8368
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008369#ifdef MS_WINDOWS
8370
8371PyDoc_STRVAR(win32_urandom__doc__,
8372"urandom(n) -> str\n\n\
8373Return a string of n random bytes suitable for cryptographic use.");
8374
8375typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8376 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8377 DWORD dwFlags );
8378typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8379 BYTE *pbBuffer );
8380
8381static CRYPTGENRANDOM pCryptGenRandom = NULL;
Martin v. Löwisaf699dd2007-09-04 09:51:57 +00008382/* This handle is never explicitly released. Instead, the operating
8383 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008384static HCRYPTPROV hCryptProv = 0;
8385
Tim Peters4ad82172004-08-30 17:02:04 +00008386static PyObject*
8387win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008388{
Tim Petersd3115382004-08-30 17:36:46 +00008389 int howMany;
8390 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008391
Tim Peters4ad82172004-08-30 17:02:04 +00008392 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00008393 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00008394 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00008395 if (howMany < 0)
8396 return PyErr_Format(PyExc_ValueError,
8397 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008398
Tim Peters4ad82172004-08-30 17:02:04 +00008399 if (hCryptProv == 0) {
8400 HINSTANCE hAdvAPI32 = NULL;
8401 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008402
Tim Peters4ad82172004-08-30 17:02:04 +00008403 /* Obtain handle to the DLL containing CryptoAPI
8404 This should not fail */
8405 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8406 if(hAdvAPI32 == NULL)
8407 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008408
Tim Peters4ad82172004-08-30 17:02:04 +00008409 /* Obtain pointers to the CryptoAPI functions
8410 This will fail on some early versions of Win95 */
8411 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8412 hAdvAPI32,
8413 "CryptAcquireContextA");
8414 if (pCryptAcquireContext == NULL)
8415 return PyErr_Format(PyExc_NotImplementedError,
8416 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008417
Tim Peters4ad82172004-08-30 17:02:04 +00008418 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8419 hAdvAPI32, "CryptGenRandom");
Georg Brandl74bb7832006-09-06 06:03:59 +00008420 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00008421 return PyErr_Format(PyExc_NotImplementedError,
8422 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008423
Tim Peters4ad82172004-08-30 17:02:04 +00008424 /* Acquire context */
8425 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8426 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8427 return win32_error("CryptAcquireContext", NULL);
8428 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008429
Tim Peters4ad82172004-08-30 17:02:04 +00008430 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008431 result = PyString_FromStringAndSize(NULL, howMany);
Tim Petersd3115382004-08-30 17:36:46 +00008432 if (result != NULL) {
8433 /* Get random data */
Amaury Forgeot d'Arc74bd40d2008-07-21 21:06:46 +00008434 memset(PyString_AS_STRING(result), 0, howMany); /* zero seed */
Tim Petersd3115382004-08-30 17:36:46 +00008435 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008436 PyString_AS_STRING(result))) {
Tim Petersd3115382004-08-30 17:36:46 +00008437 Py_DECREF(result);
8438 return win32_error("CryptGenRandom", NULL);
8439 }
Tim Peters4ad82172004-08-30 17:02:04 +00008440 }
Tim Petersd3115382004-08-30 17:36:46 +00008441 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008442}
8443#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008444
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008445#ifdef __VMS
8446/* Use openssl random routine */
8447#include <openssl/rand.h>
8448PyDoc_STRVAR(vms_urandom__doc__,
8449"urandom(n) -> str\n\n\
8450Return a string of n random bytes suitable for cryptographic use.");
8451
8452static PyObject*
8453vms_urandom(PyObject *self, PyObject *args)
8454{
8455 int howMany;
8456 PyObject* result;
8457
8458 /* Read arguments */
8459 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8460 return NULL;
8461 if (howMany < 0)
8462 return PyErr_Format(PyExc_ValueError,
8463 "negative argument not allowed");
8464
8465 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008466 result = PyString_FromStringAndSize(NULL, howMany);
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008467 if (result != NULL) {
8468 /* Get random data */
8469 if (RAND_pseudo_bytes((unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008470 PyString_AS_STRING(result),
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008471 howMany) < 0) {
8472 Py_DECREF(result);
8473 return PyErr_Format(PyExc_ValueError,
8474 "RAND_pseudo_bytes");
8475 }
8476 }
8477 return result;
8478}
8479#endif
8480
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008481static PyMethodDef posix_methods[] = {
8482 {"access", posix_access, METH_VARARGS, posix_access__doc__},
8483#ifdef HAVE_TTYNAME
8484 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
8485#endif
8486 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008487#ifdef HAVE_CHFLAGS
8488 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
8489#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008490 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008491#ifdef HAVE_FCHMOD
8492 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
8493#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008494#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008495 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008496#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008497#ifdef HAVE_LCHMOD
8498 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
8499#endif /* HAVE_LCHMOD */
8500#ifdef HAVE_FCHOWN
8501 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
8502#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008503#ifdef HAVE_LCHFLAGS
8504 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
8505#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008506#ifdef HAVE_LCHOWN
8507 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
8508#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008509#ifdef HAVE_CHROOT
8510 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
8511#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008512#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00008513 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008514#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008515#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00008516 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008517#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00008518 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008519#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008520#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008521#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008522 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008523#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008524 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8525 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8526 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008527#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008528 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008529#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008530#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008531 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008532#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008533 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8534 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8535 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008536 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008537#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008538 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008539#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008540#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008541 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008542#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008543 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008544#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00008545 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008546#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008547 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8548 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8549 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008550#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00008551 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008552#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008553 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008554#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008555 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8556 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008557#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008558#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008559 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8560 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008561#if defined(PYOS_OS2)
8562 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8563 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8564#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008565#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008566#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00008567 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008568#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008569#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00008570 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008571#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008572#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00008573 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008574#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008575#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00008576 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008577#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008578#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008579 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008580#endif /* HAVE_GETEGID */
8581#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008582 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008583#endif /* HAVE_GETEUID */
8584#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008585 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008586#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008587#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00008588 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008589#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008590 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008591#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008592 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008593#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008594#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00008595 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008596#endif /* HAVE_GETPPID */
8597#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008598 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008599#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008600#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00008601 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008602#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008603#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008604 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008605#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008606#ifdef HAVE_KILLPG
8607 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8608#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008609#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008610 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008611#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008612#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008613 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008614#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008615 {"popen2", win32_popen2, METH_VARARGS},
8616 {"popen3", win32_popen3, METH_VARARGS},
8617 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00008618 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008619#else
8620#if defined(PYOS_OS2) && defined(PYCC_GCC)
8621 {"popen2", os2emx_popen2, METH_VARARGS},
8622 {"popen3", os2emx_popen3, METH_VARARGS},
8623 {"popen4", os2emx_popen4, METH_VARARGS},
8624#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008625#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008626#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008627#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008628 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008629#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008630#ifdef HAVE_SETEUID
8631 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8632#endif /* HAVE_SETEUID */
8633#ifdef HAVE_SETEGID
8634 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8635#endif /* HAVE_SETEGID */
8636#ifdef HAVE_SETREUID
8637 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8638#endif /* HAVE_SETREUID */
8639#ifdef HAVE_SETREGID
8640 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8641#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008642#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008643 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008644#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008645#ifdef HAVE_SETGROUPS
Georg Brandl96a8c392006-05-29 21:04:52 +00008646 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008647#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008648#ifdef HAVE_GETPGID
8649 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8650#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008651#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008652 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008653#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008654#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00008655 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008656#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008657#ifdef HAVE_WAIT3
8658 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8659#endif /* HAVE_WAIT3 */
8660#ifdef HAVE_WAIT4
8661 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8662#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008663#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008664 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008665#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008666#ifdef HAVE_GETSID
8667 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8668#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008669#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00008670 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008671#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008672#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008673 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008674#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008675#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008676 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008677#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008678#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008679 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008680#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008681 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8682 {"close", posix_close, METH_VARARGS, posix_close__doc__},
Georg Brandl309501a2008-01-19 20:22:13 +00008683 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008684 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8685 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8686 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8687 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8688 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8689 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8690 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00008691 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008692#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00008693 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008694#endif
8695#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008696 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008697#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008698#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008699 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8700#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008701#ifdef HAVE_DEVICE_MACROS
8702 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8703 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8704 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8705#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008706#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008707 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008708#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008709#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008710 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008711#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008712#ifdef HAVE_UNSETENV
8713 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8714#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008715 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008716#ifdef HAVE_FCHDIR
8717 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8718#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008719#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008720 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008721#endif
8722#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008723 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008724#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008725#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008726#ifdef WCOREDUMP
8727 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8728#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008729#ifdef WIFCONTINUED
8730 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8731#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008732#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008733 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008734#endif /* WIFSTOPPED */
8735#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008736 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008737#endif /* WIFSIGNALED */
8738#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008739 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008740#endif /* WIFEXITED */
8741#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008742 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008743#endif /* WEXITSTATUS */
8744#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008745 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008746#endif /* WTERMSIG */
8747#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008748 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008749#endif /* WSTOPSIG */
8750#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008751#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008752 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008753#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008754#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008755 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008756#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008757#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00008758 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008759#endif
8760#ifdef HAVE_TEMPNAM
8761 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8762#endif
8763#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00008764 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008765#endif
Fred Drakec9680921999-12-13 16:37:25 +00008766#ifdef HAVE_CONFSTR
8767 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8768#endif
8769#ifdef HAVE_SYSCONF
8770 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8771#endif
8772#ifdef HAVE_FPATHCONF
8773 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8774#endif
8775#ifdef HAVE_PATHCONF
8776 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8777#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008778 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008779#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00008780 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8781#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008782#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00008783 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008784#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008785 #ifdef MS_WINDOWS
8786 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8787 #endif
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008788 #ifdef __VMS
8789 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8790 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008791 {NULL, NULL} /* Sentinel */
8792};
8793
8794
Barry Warsaw4a342091996-12-19 23:50:02 +00008795static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008796ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008797{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008798 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008799}
8800
Guido van Rossumd48f2521997-12-05 22:19:34 +00008801#if defined(PYOS_OS2)
8802/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008803static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008804{
8805 APIRET rc;
8806 ULONG values[QSV_MAX+1];
8807 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008808 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008809
8810 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008811 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008812 Py_END_ALLOW_THREADS
8813
8814 if (rc != NO_ERROR) {
8815 os2_error(rc);
8816 return -1;
8817 }
8818
Fred Drake4d1e64b2002-04-15 19:40:07 +00008819 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8820 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8821 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8822 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8823 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8824 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8825 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008826
8827 switch (values[QSV_VERSION_MINOR]) {
8828 case 0: ver = "2.00"; break;
8829 case 10: ver = "2.10"; break;
8830 case 11: ver = "2.11"; break;
8831 case 30: ver = "3.00"; break;
8832 case 40: ver = "4.00"; break;
8833 case 50: ver = "5.00"; break;
8834 default:
Tim Peters885d4572001-11-28 20:27:42 +00008835 PyOS_snprintf(tmp, sizeof(tmp),
8836 "%d-%d", values[QSV_VERSION_MAJOR],
8837 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008838 ver = &tmp[0];
8839 }
8840
8841 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008842 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008843 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008844
8845 /* Add Indicator of Which Drive was Used to Boot the System */
8846 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8847 tmp[1] = ':';
8848 tmp[2] = '\0';
8849
Fred Drake4d1e64b2002-04-15 19:40:07 +00008850 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008851}
8852#endif
8853
Barry Warsaw4a342091996-12-19 23:50:02 +00008854static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008855all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008856{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008857#ifdef F_OK
8858 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008859#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008860#ifdef R_OK
8861 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008862#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008863#ifdef W_OK
8864 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008865#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008866#ifdef X_OK
8867 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008868#endif
Fred Drakec9680921999-12-13 16:37:25 +00008869#ifdef NGROUPS_MAX
8870 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8871#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008872#ifdef TMP_MAX
8873 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8874#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008875#ifdef WCONTINUED
8876 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8877#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008878#ifdef WNOHANG
8879 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008880#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008881#ifdef WUNTRACED
8882 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8883#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008884#ifdef O_RDONLY
8885 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8886#endif
8887#ifdef O_WRONLY
8888 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8889#endif
8890#ifdef O_RDWR
8891 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8892#endif
8893#ifdef O_NDELAY
8894 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8895#endif
8896#ifdef O_NONBLOCK
8897 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8898#endif
8899#ifdef O_APPEND
8900 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8901#endif
8902#ifdef O_DSYNC
8903 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8904#endif
8905#ifdef O_RSYNC
8906 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8907#endif
8908#ifdef O_SYNC
8909 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8910#endif
8911#ifdef O_NOCTTY
8912 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8913#endif
8914#ifdef O_CREAT
8915 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8916#endif
8917#ifdef O_EXCL
8918 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8919#endif
8920#ifdef O_TRUNC
8921 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8922#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008923#ifdef O_BINARY
8924 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8925#endif
8926#ifdef O_TEXT
8927 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8928#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008929#ifdef O_LARGEFILE
8930 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8931#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008932#ifdef O_SHLOCK
8933 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8934#endif
8935#ifdef O_EXLOCK
8936 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8937#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008938
Tim Peters5aa91602002-01-30 05:46:57 +00008939/* MS Windows */
8940#ifdef O_NOINHERIT
8941 /* Don't inherit in child processes. */
8942 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8943#endif
8944#ifdef _O_SHORT_LIVED
8945 /* Optimize for short life (keep in memory). */
8946 /* MS forgot to define this one with a non-underscore form too. */
8947 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8948#endif
8949#ifdef O_TEMPORARY
8950 /* Automatically delete when last handle is closed. */
8951 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8952#endif
8953#ifdef O_RANDOM
8954 /* Optimize for random access. */
8955 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8956#endif
8957#ifdef O_SEQUENTIAL
8958 /* Optimize for sequential access. */
8959 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8960#endif
8961
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008962/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00008963#ifdef O_ASYNC
8964 /* Send a SIGIO signal whenever input or output
8965 becomes available on file descriptor */
8966 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
8967#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008968#ifdef O_DIRECT
8969 /* Direct disk access. */
8970 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8971#endif
8972#ifdef O_DIRECTORY
8973 /* Must be a directory. */
8974 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8975#endif
8976#ifdef O_NOFOLLOW
8977 /* Do not follow links. */
8978 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8979#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00008980#ifdef O_NOATIME
8981 /* Do not update the access time. */
8982 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
8983#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008984
Barry Warsaw5676bd12003-01-07 20:57:09 +00008985 /* These come from sysexits.h */
8986#ifdef EX_OK
8987 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008988#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008989#ifdef EX_USAGE
8990 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008991#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008992#ifdef EX_DATAERR
8993 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008994#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008995#ifdef EX_NOINPUT
8996 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008997#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008998#ifdef EX_NOUSER
8999 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009000#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009001#ifdef EX_NOHOST
9002 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009003#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009004#ifdef EX_UNAVAILABLE
9005 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009006#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009007#ifdef EX_SOFTWARE
9008 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009009#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009010#ifdef EX_OSERR
9011 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009012#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009013#ifdef EX_OSFILE
9014 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009015#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009016#ifdef EX_CANTCREAT
9017 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009018#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009019#ifdef EX_IOERR
9020 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009021#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009022#ifdef EX_TEMPFAIL
9023 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009024#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009025#ifdef EX_PROTOCOL
9026 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009027#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009028#ifdef EX_NOPERM
9029 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009030#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009031#ifdef EX_CONFIG
9032 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009033#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009034#ifdef EX_NOTFOUND
9035 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009036#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009037
Guido van Rossum246bc171999-02-01 23:54:31 +00009038#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009039#if defined(PYOS_OS2) && defined(PYCC_GCC)
9040 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
9041 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
9042 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
9043 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
9044 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
9045 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
9046 if (ins(d, "P_PM", (long)P_PM)) return -1;
9047 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
9048 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
9049 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
9050 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
9051 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
9052 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
9053 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
9054 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
9055 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
9056 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
9057 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
9058 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
9059 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
9060#else
Guido van Rossum7d385291999-02-16 19:38:04 +00009061 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
9062 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
9063 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
9064 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
9065 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00009066#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009067#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00009068
Guido van Rossumd48f2521997-12-05 22:19:34 +00009069#if defined(PYOS_OS2)
9070 if (insertvalues(d)) return -1;
9071#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009072 return 0;
9073}
9074
9075
Tim Peters5aa91602002-01-30 05:46:57 +00009076#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009077#define INITFUNC initnt
9078#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009079
9080#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009081#define INITFUNC initos2
9082#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009083
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009084#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009085#define INITFUNC initposix
9086#define MODNAME "posix"
9087#endif
9088
Mark Hammondfe51c6d2002-08-02 02:27:13 +00009089PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009090INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00009091{
Fred Drake4d1e64b2002-04-15 19:40:07 +00009092 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00009093
Fred Drake4d1e64b2002-04-15 19:40:07 +00009094 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009095 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00009096 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00009097 if (m == NULL)
9098 return;
Tim Peters5aa91602002-01-30 05:46:57 +00009099
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009100 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009101 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00009102 Py_XINCREF(v);
9103 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009104 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00009105 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00009106
Fred Drake4d1e64b2002-04-15 19:40:07 +00009107 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00009108 return;
9109
Fred Drake4d1e64b2002-04-15 19:40:07 +00009110 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00009111 return;
9112
Fred Drake4d1e64b2002-04-15 19:40:07 +00009113 Py_INCREF(PyExc_OSError);
9114 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00009115
Guido van Rossumb3d39562000-01-31 18:41:26 +00009116#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00009117 if (posix_putenv_garbage == NULL)
9118 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00009119#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009120
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009121 if (!initialized) {
9122 stat_result_desc.name = MODNAME ".stat_result";
9123 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9124 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9125 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9126 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9127 structseq_new = StatResultType.tp_new;
9128 StatResultType.tp_new = statresult_new;
9129
9130 statvfs_result_desc.name = MODNAME ".statvfs_result";
9131 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009132#ifdef NEED_TICKS_PER_SECOND
9133# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
9134 ticks_per_second = sysconf(_SC_CLK_TCK);
9135# elif defined(HZ)
9136 ticks_per_second = HZ;
9137# else
9138 ticks_per_second = 60; /* magic fallback value; may be bogus */
9139# endif
9140#endif
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009141 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009142 Py_INCREF((PyObject*) &StatResultType);
9143 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00009144 Py_INCREF((PyObject*) &StatVFSResultType);
9145 PyModule_AddObject(m, "statvfs_result",
9146 (PyObject*) &StatVFSResultType);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009147 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009148
9149#ifdef __APPLE__
9150 /*
9151 * Step 2 of weak-linking support on Mac OS X.
9152 *
9153 * The code below removes functions that are not available on the
9154 * currently active platform.
9155 *
9156 * This block allow one to use a python binary that was build on
9157 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9158 * OSX 10.4.
9159 */
9160#ifdef HAVE_FSTATVFS
9161 if (fstatvfs == NULL) {
9162 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9163 return;
9164 }
9165 }
9166#endif /* HAVE_FSTATVFS */
9167
9168#ifdef HAVE_STATVFS
9169 if (statvfs == NULL) {
9170 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9171 return;
9172 }
9173 }
9174#endif /* HAVE_STATVFS */
9175
9176# ifdef HAVE_LCHOWN
9177 if (lchown == NULL) {
9178 if (PyObject_DelAttrString(m, "lchown") == -1) {
9179 return;
9180 }
9181 }
9182#endif /* HAVE_LCHOWN */
9183
9184
9185#endif /* __APPLE__ */
9186
Guido van Rossumb6775db1994-08-01 11:34:53 +00009187}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009188
9189#ifdef __cplusplus
9190}
9191#endif
9192
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009193