blob: 3dd324116f7fd17d4d104fb5caf4a3bcc9eebeb1 [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 */
Antoine Pitrou4fe38582009-05-24 12:15:04 +0000315#if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT
Antoine Pitrou5e858fe2009-05-23 15:37:45 +0000316#define PARSE_PID "i"
317#define PyLong_FromPid PyInt_FromLong
318#define PyLong_AsPid PyInt_AsLong
319#elif SIZEOF_PID_T == SIZEOF_LONG
320#define PARSE_PID "l"
321#define PyLong_FromPid PyInt_FromLong
322#define PyLong_AsPid PyInt_AsLong
323#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
324#define PARSE_PID "L"
325#define PyLong_FromPid PyLong_FromLongLong
326#define PyLong_AsPid PyInt_AsLongLong
327#else
328#error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)"
Antoine Pitrou5e858fe2009-05-23 15:37:45 +0000329#endif /* SIZEOF_PID_T */
330
Greg Wardb48bc172000-03-01 21:51:56 +0000331/* Don't use the "_r" form if we don't need it (also, won't have a
332 prototype for it, at least on Solaris -- maybe others as well?). */
333#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
334#define USE_CTERMID_R
335#endif
336
337#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
338#define USE_TMPNAM_R
339#endif
340
Fred Drake699f3522000-06-29 21:12:41 +0000341/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000342#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000343#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000344# define STAT win32_stat
345# define FSTAT win32_fstat
346# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000347#else
348# define STAT stat
349# define FSTAT fstat
350# define STRUCT_STAT struct stat
351#endif
352
Tim Peters11b23062003-04-23 02:39:17 +0000353#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000354#include <sys/mkdev.h>
355#else
356#if defined(MAJOR_IN_SYSMACROS)
357#include <sys/sysmacros.h>
358#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000359#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
360#include <sys/mkdev.h>
361#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000362#endif
Fred Drake699f3522000-06-29 21:12:41 +0000363
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000364#if defined _MSC_VER && _MSC_VER >= 1400
365/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
366 * valid and throw an assertion if it isn't.
367 * Normally, an invalid fd is likely to be a C program error and therefore
368 * an assertion can be useful, but it does contradict the POSIX standard
369 * which for write(2) states:
370 * "Otherwise, -1 shall be returned and errno set to indicate the error."
371 * "[EBADF] The fildes argument is not a valid file descriptor open for
372 * writing."
373 * Furthermore, python allows the user to enter any old integer
374 * as a fd and should merely raise a python exception on error.
375 * The Microsoft CRT doesn't provide an official way to check for the
376 * validity of a file descriptor, but we can emulate its internal behaviour
377 * by using the exported __pinfo data member and knowledge of the
378 * internal structures involved.
379 * The structures below must be updated for each version of visual studio
380 * according to the file internal.h in the CRT source, until MS comes
381 * up with a less hacky way to do this.
382 * (all of this is to avoid globally modifying the CRT behaviour using
383 * _set_invalid_parameter_handler() and _CrtSetReportMode())
384 */
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000385/* The actual size of the structure is determined at runtime.
386 * Only the first items must be present.
387 */
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000388typedef struct {
389 intptr_t osfhnd;
390 char osfile;
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000391} my_ioinfo;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000392
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000393extern __declspec(dllimport) char * __pioinfo[];
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000394#define IOINFO_L2E 5
395#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
396#define IOINFO_ARRAYS 64
397#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
398#define FOPEN 0x01
399#define _NO_CONSOLE_FILENO (intptr_t)-2
400
401/* This function emulates what the windows CRT does to validate file handles */
402int
403_PyVerify_fd(int fd)
404{
405 const int i1 = fd >> IOINFO_L2E;
406 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000407
408 static int sizeof_ioinfo = 0;
409
410 /* Determine the actual size of the ioinfo structure,
411 * as used by the CRT loaded in memory
412 */
413 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
414 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
415 }
416 if (sizeof_ioinfo == 0) {
417 /* This should not happen... */
418 goto fail;
419 }
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000420
421 /* See that it isn't a special CLEAR fileno */
422 if (fd != _NO_CONSOLE_FILENO) {
423 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
424 * we check pointer validity and other info
425 */
426 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
427 /* finally, check that the file is open */
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000428 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
429 if (info->osfile & FOPEN) {
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000430 return 1;
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000431 }
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000432 }
433 }
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000434 fail:
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000435 errno = EBADF;
436 return 0;
437}
438
439/* the special case of checking dup2. The target fd must be in a sensible range */
440static int
441_PyVerify_fd_dup2(int fd1, int fd2)
442{
443 if (!_PyVerify_fd(fd1))
444 return 0;
445 if (fd2 == _NO_CONSOLE_FILENO)
446 return 0;
447 if ((unsigned)fd2 < _NHANDLE_)
448 return 1;
449 else
450 return 0;
451}
452#else
453/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
454#define _PyVerify_fd_dup2(A, B) (1)
455#endif
456
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000457/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000458#ifdef WITH_NEXT_FRAMEWORK
459/* On Darwin/MacOSX a shared library or framework has no access to
460** environ directly, we must obtain it with _NSGetEnviron().
461*/
462#include <crt_externs.h>
463static char **environ;
464#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000465extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000466#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000467
Barry Warsaw53699e91996-12-10 23:23:01 +0000468static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000469convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000470{
Barry Warsaw53699e91996-12-10 23:23:01 +0000471 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000472 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000473 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000474 if (d == NULL)
475 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000476#ifdef WITH_NEXT_FRAMEWORK
477 if (environ == NULL)
478 environ = *_NSGetEnviron();
479#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000480 if (environ == NULL)
481 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000482 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000483 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000484 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000485 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000486 char *p = strchr(*e, '=');
487 if (p == NULL)
488 continue;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000489 k = PyString_FromStringAndSize(*e, (int)(p-*e));
Guido van Rossum6a619f41999-08-03 19:41:10 +0000490 if (k == NULL) {
491 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000492 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000493 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000494 v = PyString_FromString(p+1);
Guido van Rossum6a619f41999-08-03 19:41:10 +0000495 if (v == NULL) {
496 PyErr_Clear();
497 Py_DECREF(k);
498 continue;
499 }
500 if (PyDict_GetItem(d, k) == NULL) {
501 if (PyDict_SetItem(d, k, v) != 0)
502 PyErr_Clear();
503 }
504 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000505 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000506 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000507#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000508 {
509 APIRET rc;
510 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
511
512 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000513 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000514 PyObject *v = PyString_FromString(buffer);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000515 PyDict_SetItemString(d, "BEGINLIBPATH", v);
516 Py_DECREF(v);
517 }
518 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
519 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000520 PyObject *v = PyString_FromString(buffer);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000521 PyDict_SetItemString(d, "ENDLIBPATH", v);
522 Py_DECREF(v);
523 }
524 }
525#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000526 return d;
527}
528
529
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000530/* Set a POSIX-specific error from errno, and return NULL */
531
Barry Warsawd58d7641998-07-23 16:14:40 +0000532static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000533posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000534{
Barry Warsawca74da41999-02-09 19:31:45 +0000535 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000536}
Barry Warsawd58d7641998-07-23 16:14:40 +0000537static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000538posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000539{
Barry Warsawca74da41999-02-09 19:31:45 +0000540 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000541}
542
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000543#ifdef MS_WINDOWS
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000544static PyObject *
545posix_error_with_unicode_filename(Py_UNICODE* name)
546{
547 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
548}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000549#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000550
551
Mark Hammondef8b6542001-05-13 08:04:26 +0000552static PyObject *
553posix_error_with_allocated_filename(char* name)
554{
555 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
556 PyMem_Free(name);
557 return rc;
558}
559
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000560#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000561static PyObject *
562win32_error(char* function, char* filename)
563{
Mark Hammond33a6da92000-08-15 00:46:38 +0000564 /* XXX We should pass the function name along in the future.
565 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000566 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000567 Windows error object, which is non-trivial.
568 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000569 errno = GetLastError();
570 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000571 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000572 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000573 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000574}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000575
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000576static PyObject *
577win32_error_unicode(char* function, Py_UNICODE* filename)
578{
579 /* XXX - see win32_error for comments on 'function' */
580 errno = GetLastError();
581 if (filename)
582 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
583 else
584 return PyErr_SetFromWindowsErr(errno);
585}
586
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000587static int
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000588convert_to_unicode(PyObject **param)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000589{
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000590 if (PyUnicode_CheckExact(*param))
591 Py_INCREF(*param);
592 else if (PyUnicode_Check(*param))
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000593 /* For a Unicode subtype that's not a Unicode object,
594 return a true Unicode object with the same data. */
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000595 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
596 PyUnicode_GET_SIZE(*param));
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000597 else
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000598 *param = PyUnicode_FromEncodedObject(*param,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000599 Py_FileSystemDefaultEncoding,
600 "strict");
601 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000602}
603
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000604#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000605
Guido van Rossumd48f2521997-12-05 22:19:34 +0000606#if defined(PYOS_OS2)
607/**********************************************************************
608 * Helper Function to Trim and Format OS/2 Messages
609 **********************************************************************/
610 static void
611os2_formatmsg(char *msgbuf, int msglen, char *reason)
612{
613 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
614
615 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
616 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
617
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000618 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000619 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
620 }
621
622 /* Add Optional Reason Text */
623 if (reason) {
624 strcat(msgbuf, " : ");
625 strcat(msgbuf, reason);
626 }
627}
628
629/**********************************************************************
630 * Decode an OS/2 Operating System Error Code
631 *
632 * A convenience function to lookup an OS/2 error code and return a
633 * text message we can use to raise a Python exception.
634 *
635 * Notes:
636 * The messages for errors returned from the OS/2 kernel reside in
637 * the file OSO001.MSG in the \OS2 directory hierarchy.
638 *
639 **********************************************************************/
640 static char *
641os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
642{
643 APIRET rc;
644 ULONG msglen;
645
646 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
647 Py_BEGIN_ALLOW_THREADS
648 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
649 errorcode, "oso001.msg", &msglen);
650 Py_END_ALLOW_THREADS
651
652 if (rc == NO_ERROR)
653 os2_formatmsg(msgbuf, msglen, reason);
654 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000655 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000656 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000657
658 return msgbuf;
659}
660
661/* Set an OS/2-specific error and return NULL. OS/2 kernel
662 errors are not in a global variable e.g. 'errno' nor are
663 they congruent with posix error numbers. */
664
665static PyObject * os2_error(int code)
666{
667 char text[1024];
668 PyObject *v;
669
670 os2_strerror(text, sizeof(text), code, "");
671
672 v = Py_BuildValue("(is)", code, text);
673 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000674 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000675 Py_DECREF(v);
676 }
677 return NULL; /* Signal to Python that an Exception is Pending */
678}
679
680#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000681
682/* POSIX generic methods */
683
Barry Warsaw53699e91996-12-10 23:23:01 +0000684static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000685posix_fildes(PyObject *fdobj, int (*func)(int))
686{
687 int fd;
688 int res;
689 fd = PyObject_AsFileDescriptor(fdobj);
690 if (fd < 0)
691 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000692 if (!_PyVerify_fd(fd))
693 return posix_error();
Fred Drake4d1e64b2002-04-15 19:40:07 +0000694 Py_BEGIN_ALLOW_THREADS
695 res = (*func)(fd);
696 Py_END_ALLOW_THREADS
697 if (res < 0)
698 return posix_error();
699 Py_INCREF(Py_None);
700 return Py_None;
701}
Guido van Rossum21142a01999-01-08 21:05:37 +0000702
703static PyObject *
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000704posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000705{
Mark Hammondef8b6542001-05-13 08:04:26 +0000706 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000707 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000708 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000709 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000710 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000711 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000712 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000713 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000714 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000715 return posix_error_with_allocated_filename(path1);
716 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000717 Py_INCREF(Py_None);
718 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000719}
720
Barry Warsaw53699e91996-12-10 23:23:01 +0000721static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000722posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000723 char *format,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000724 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000725{
Mark Hammondef8b6542001-05-13 08:04:26 +0000726 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000727 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000728 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000729 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000730 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000731 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000732 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000733 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000734 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000735 PyMem_Free(path1);
736 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000737 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000738 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000739 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000740 Py_INCREF(Py_None);
741 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000742}
743
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000744#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000745static PyObject*
746win32_1str(PyObject* args, char* func,
747 char* format, BOOL (__stdcall *funcA)(LPCSTR),
748 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
749{
750 PyObject *uni;
751 char *ansi;
752 BOOL result;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +0000753
754 if (!PyArg_ParseTuple(args, wformat, &uni))
755 PyErr_Clear();
756 else {
757 Py_BEGIN_ALLOW_THREADS
758 result = funcW(PyUnicode_AsUnicode(uni));
759 Py_END_ALLOW_THREADS
760 if (!result)
761 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
762 Py_INCREF(Py_None);
763 return Py_None;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000764 }
765 if (!PyArg_ParseTuple(args, format, &ansi))
766 return NULL;
767 Py_BEGIN_ALLOW_THREADS
768 result = funcA(ansi);
769 Py_END_ALLOW_THREADS
770 if (!result)
771 return win32_error(func, ansi);
772 Py_INCREF(Py_None);
773 return Py_None;
774
775}
776
777/* This is a reimplementation of the C library's chdir function,
778 but one that produces Win32 errors instead of DOS error codes.
779 chdir is essentially a wrapper around SetCurrentDirectory; however,
780 it also needs to set "magic" environment variables indicating
781 the per-drive current directory, which are of the form =<drive>: */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000782static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000783win32_chdir(LPCSTR path)
784{
785 char new_path[MAX_PATH+1];
786 int result;
787 char env[4] = "=x:";
788
789 if(!SetCurrentDirectoryA(path))
790 return FALSE;
791 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
792 if (!result)
793 return FALSE;
794 /* In the ANSI API, there should not be any paths longer
795 than MAX_PATH. */
796 assert(result <= MAX_PATH+1);
797 if (strncmp(new_path, "\\\\", 2) == 0 ||
798 strncmp(new_path, "//", 2) == 0)
799 /* UNC path, nothing to do. */
800 return TRUE;
801 env[1] = new_path[0];
802 return SetEnvironmentVariableA(env, new_path);
803}
804
805/* The Unicode version differs from the ANSI version
806 since the current directory might exceed MAX_PATH characters */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000807static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000808win32_wchdir(LPCWSTR path)
809{
810 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
811 int result;
812 wchar_t env[4] = L"=x:";
813
814 if(!SetCurrentDirectoryW(path))
815 return FALSE;
816 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
817 if (!result)
818 return FALSE;
819 if (result > MAX_PATH+1) {
Hirokazu Yamamoto10a018c2008-10-09 10:00:30 +0000820 new_path = malloc(result * sizeof(wchar_t));
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000821 if (!new_path) {
822 SetLastError(ERROR_OUTOFMEMORY);
823 return FALSE;
824 }
Hirokazu Yamamoto10a018c2008-10-09 10:00:30 +0000825 result = GetCurrentDirectoryW(result, new_path);
Hirokazu Yamamoto6c75a302008-10-09 10:11:21 +0000826 if (!result) {
827 free(new_path);
Hirokazu Yamamoto10a018c2008-10-09 10:00:30 +0000828 return FALSE;
Hirokazu Yamamoto6c75a302008-10-09 10:11:21 +0000829 }
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000830 }
831 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
832 wcsncmp(new_path, L"//", 2) == 0)
833 /* UNC path, nothing to do. */
834 return TRUE;
835 env[1] = new_path[0];
836 result = SetEnvironmentVariableW(env, new_path);
837 if (new_path != _new_path)
838 free(new_path);
839 return result;
840}
841#endif
842
Martin v. Löwis14694662006-02-03 12:54:16 +0000843#ifdef MS_WINDOWS
844/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
845 - time stamps are restricted to second resolution
846 - file modification times suffer from forth-and-back conversions between
847 UTC and local time
848 Therefore, we implement our own stat, based on the Win32 API directly.
849*/
850#define HAVE_STAT_NSEC 1
851
852struct win32_stat{
853 int st_dev;
854 __int64 st_ino;
855 unsigned short st_mode;
856 int st_nlink;
857 int st_uid;
858 int st_gid;
859 int st_rdev;
860 __int64 st_size;
861 int st_atime;
862 int st_atime_nsec;
863 int st_mtime;
864 int st_mtime_nsec;
865 int st_ctime;
866 int st_ctime_nsec;
867};
868
869static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
870
871static void
872FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
873{
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000874 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
875 /* Cannot simply cast and dereference in_ptr,
876 since it might not be aligned properly */
877 __int64 in;
878 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000879 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
880 /* XXX Win32 supports time stamps past 2038; we currently don't */
881 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
882}
883
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000884static void
885time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
886{
887 /* XXX endianness */
888 __int64 out;
889 out = time_in + secs_between_epochs;
Martin v. Löwisf43893a2006-10-09 20:44:25 +0000890 out = out * 10000000 + nsec_in / 100;
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000891 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000892}
893
Martin v. Löwis14694662006-02-03 12:54:16 +0000894/* Below, we *know* that ugo+r is 0444 */
895#if _S_IREAD != 0400
896#error Unsupported C library
897#endif
898static int
899attributes_to_mode(DWORD attr)
900{
901 int m = 0;
902 if (attr & FILE_ATTRIBUTE_DIRECTORY)
903 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
904 else
905 m |= _S_IFREG;
906 if (attr & FILE_ATTRIBUTE_READONLY)
907 m |= 0444;
908 else
909 m |= 0666;
910 return m;
911}
912
913static int
914attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
915{
916 memset(result, 0, sizeof(*result));
917 result->st_mode = attributes_to_mode(info->dwFileAttributes);
918 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
919 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
920 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
921 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
922
923 return 0;
924}
925
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000926static BOOL
927attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
928{
929 HANDLE hFindFile;
930 WIN32_FIND_DATAA FileData;
931 hFindFile = FindFirstFileA(pszFile, &FileData);
932 if (hFindFile == INVALID_HANDLE_VALUE)
933 return FALSE;
934 FindClose(hFindFile);
935 pfad->dwFileAttributes = FileData.dwFileAttributes;
936 pfad->ftCreationTime = FileData.ftCreationTime;
937 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
938 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
939 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
940 pfad->nFileSizeLow = FileData.nFileSizeLow;
941 return TRUE;
942}
943
944static BOOL
945attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
946{
947 HANDLE hFindFile;
948 WIN32_FIND_DATAW FileData;
949 hFindFile = FindFirstFileW(pszFile, &FileData);
950 if (hFindFile == INVALID_HANDLE_VALUE)
951 return FALSE;
952 FindClose(hFindFile);
953 pfad->dwFileAttributes = FileData.dwFileAttributes;
954 pfad->ftCreationTime = FileData.ftCreationTime;
955 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
956 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
957 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
958 pfad->nFileSizeLow = FileData.nFileSizeLow;
959 return TRUE;
960}
961
Martin v. Löwis012bc722006-10-15 09:43:39 +0000962static BOOL WINAPI
963Py_GetFileAttributesExA(LPCSTR pszFile,
964 GET_FILEEX_INFO_LEVELS level,
965 LPVOID pv)
966{
967 BOOL result;
Martin v. Löwis012bc722006-10-15 09:43:39 +0000968 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
969 /* First try to use the system's implementation, if that is
970 available and either succeeds to gives an error other than
971 that it isn't implemented. */
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +0000972 result = GetFileAttributesExA(pszFile, level, pv);
973 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
974 return result;
Martin v. Löwis012bc722006-10-15 09:43:39 +0000975 /* It's either not present, or not implemented.
976 Emulate using FindFirstFile. */
977 if (level != GetFileExInfoStandard) {
978 SetLastError(ERROR_INVALID_PARAMETER);
979 return FALSE;
980 }
981 /* Use GetFileAttributes to validate that the file name
982 does not contain wildcards (which FindFirstFile would
983 accept). */
984 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
985 return FALSE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000986 return attributes_from_dir(pszFile, pfad);
Martin v. Löwis012bc722006-10-15 09:43:39 +0000987}
988
989static BOOL WINAPI
990Py_GetFileAttributesExW(LPCWSTR pszFile,
991 GET_FILEEX_INFO_LEVELS level,
992 LPVOID pv)
993{
994 BOOL result;
Martin v. Löwis012bc722006-10-15 09:43:39 +0000995 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
996 /* First try to use the system's implementation, if that is
997 available and either succeeds to gives an error other than
998 that it isn't implemented. */
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +0000999 result = GetFileAttributesExW(pszFile, level, pv);
1000 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1001 return result;
Martin v. Löwis012bc722006-10-15 09:43:39 +00001002 /* It's either not present, or not implemented.
1003 Emulate using FindFirstFile. */
1004 if (level != GetFileExInfoStandard) {
1005 SetLastError(ERROR_INVALID_PARAMETER);
1006 return FALSE;
1007 }
1008 /* Use GetFileAttributes to validate that the file name
1009 does not contain wildcards (which FindFirstFile would
1010 accept). */
1011 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
1012 return FALSE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001013 return attributes_from_dir_w(pszFile, pfad);
Martin v. Löwis012bc722006-10-15 09:43:39 +00001014}
1015
Martin v. Löwis14694662006-02-03 12:54:16 +00001016static int
1017win32_stat(const char* path, struct win32_stat *result)
1018{
1019 WIN32_FILE_ATTRIBUTE_DATA info;
1020 int code;
1021 char *dot;
1022 /* XXX not supported on Win95 and NT 3.x */
Martin v. Löwis012bc722006-10-15 09:43:39 +00001023 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001024 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1025 /* Protocol violation: we explicitly clear errno, instead of
1026 setting it to a POSIX error. Callers should use GetLastError. */
1027 errno = 0;
1028 return -1;
1029 } else {
1030 /* Could not get attributes on open file. Fall back to
1031 reading the directory. */
1032 if (!attributes_from_dir(path, &info)) {
1033 /* Very strange. This should not fail now */
1034 errno = 0;
1035 return -1;
1036 }
1037 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001038 }
1039 code = attribute_data_to_stat(&info, result);
1040 if (code != 0)
1041 return code;
1042 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1043 dot = strrchr(path, '.');
1044 if (dot) {
1045 if (stricmp(dot, ".bat") == 0 ||
1046 stricmp(dot, ".cmd") == 0 ||
1047 stricmp(dot, ".exe") == 0 ||
1048 stricmp(dot, ".com") == 0)
1049 result->st_mode |= 0111;
1050 }
1051 return code;
1052}
1053
1054static int
1055win32_wstat(const wchar_t* path, struct win32_stat *result)
1056{
1057 int code;
1058 const wchar_t *dot;
1059 WIN32_FILE_ATTRIBUTE_DATA info;
1060 /* XXX not supported on Win95 and NT 3.x */
Martin v. Löwis012bc722006-10-15 09:43:39 +00001061 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001062 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1063 /* Protocol violation: we explicitly clear errno, instead of
1064 setting it to a POSIX error. Callers should use GetLastError. */
1065 errno = 0;
1066 return -1;
1067 } else {
1068 /* Could not get attributes on open file. Fall back to
1069 reading the directory. */
1070 if (!attributes_from_dir_w(path, &info)) {
1071 /* Very strange. This should not fail now */
1072 errno = 0;
1073 return -1;
1074 }
1075 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001076 }
1077 code = attribute_data_to_stat(&info, result);
1078 if (code < 0)
1079 return code;
1080 /* Set IFEXEC if it is an .exe, .bat, ... */
1081 dot = wcsrchr(path, '.');
1082 if (dot) {
1083 if (_wcsicmp(dot, L".bat") == 0 ||
1084 _wcsicmp(dot, L".cmd") == 0 ||
1085 _wcsicmp(dot, L".exe") == 0 ||
1086 _wcsicmp(dot, L".com") == 0)
1087 result->st_mode |= 0111;
1088 }
1089 return code;
1090}
1091
1092static int
1093win32_fstat(int file_number, struct win32_stat *result)
1094{
1095 BY_HANDLE_FILE_INFORMATION info;
1096 HANDLE h;
1097 int type;
1098
1099 h = (HANDLE)_get_osfhandle(file_number);
1100
1101 /* Protocol violation: we explicitly clear errno, instead of
1102 setting it to a POSIX error. Callers should use GetLastError. */
1103 errno = 0;
1104
1105 if (h == INVALID_HANDLE_VALUE) {
1106 /* This is really a C library error (invalid file handle).
1107 We set the Win32 error to the closes one matching. */
1108 SetLastError(ERROR_INVALID_HANDLE);
1109 return -1;
1110 }
1111 memset(result, 0, sizeof(*result));
1112
1113 type = GetFileType(h);
1114 if (type == FILE_TYPE_UNKNOWN) {
1115 DWORD error = GetLastError();
1116 if (error != 0) {
1117 return -1;
1118 }
1119 /* else: valid but unknown file */
1120 }
1121
1122 if (type != FILE_TYPE_DISK) {
1123 if (type == FILE_TYPE_CHAR)
1124 result->st_mode = _S_IFCHR;
1125 else if (type == FILE_TYPE_PIPE)
1126 result->st_mode = _S_IFIFO;
1127 return 0;
1128 }
1129
1130 if (!GetFileInformationByHandle(h, &info)) {
1131 return -1;
1132 }
1133
1134 /* similar to stat() */
1135 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1136 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1137 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1138 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1139 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1140 /* specific to fstat() */
1141 result->st_nlink = info.nNumberOfLinks;
1142 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1143 return 0;
1144}
1145
1146#endif /* MS_WINDOWS */
1147
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001148PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001149"stat_result: Result from stat or lstat.\n\n\
1150This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001151 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001152or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1153\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001154Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1155or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001156\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001157See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001158
1159static PyStructSequence_Field stat_result_fields[] = {
1160 {"st_mode", "protection bits"},
1161 {"st_ino", "inode"},
1162 {"st_dev", "device"},
1163 {"st_nlink", "number of hard links"},
1164 {"st_uid", "user ID of owner"},
1165 {"st_gid", "group ID of owner"},
1166 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001167 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1168 {NULL, "integer time of last access"},
1169 {NULL, "integer time of last modification"},
1170 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001171 {"st_atime", "time of last access"},
1172 {"st_mtime", "time of last modification"},
1173 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001174#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001175 {"st_blksize", "blocksize for filesystem I/O"},
1176#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001177#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001178 {"st_blocks", "number of blocks allocated"},
1179#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001180#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001181 {"st_rdev", "device type (if inode device)"},
1182#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001183#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1184 {"st_flags", "user defined flags for file"},
1185#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001186#ifdef HAVE_STRUCT_STAT_ST_GEN
1187 {"st_gen", "generation number"},
1188#endif
1189#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1190 {"st_birthtime", "time of creation"},
1191#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001192 {0}
1193};
1194
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001195#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001196#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001197#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001198#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001199#endif
1200
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001201#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001202#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1203#else
1204#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1205#endif
1206
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001207#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001208#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1209#else
1210#define ST_RDEV_IDX ST_BLOCKS_IDX
1211#endif
1212
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001213#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1214#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1215#else
1216#define ST_FLAGS_IDX ST_RDEV_IDX
1217#endif
1218
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001219#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001220#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001221#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001222#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001223#endif
1224
1225#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1226#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1227#else
1228#define ST_BIRTHTIME_IDX ST_GEN_IDX
1229#endif
1230
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001231static PyStructSequence_Desc stat_result_desc = {
1232 "stat_result", /* name */
1233 stat_result__doc__, /* doc */
1234 stat_result_fields,
1235 10
1236};
1237
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001238PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001239"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1240This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001241 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001242or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001243\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001244See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001245
1246static PyStructSequence_Field statvfs_result_fields[] = {
1247 {"f_bsize", },
1248 {"f_frsize", },
1249 {"f_blocks", },
1250 {"f_bfree", },
1251 {"f_bavail", },
1252 {"f_files", },
1253 {"f_ffree", },
1254 {"f_favail", },
1255 {"f_flag", },
1256 {"f_namemax",},
1257 {0}
1258};
1259
1260static PyStructSequence_Desc statvfs_result_desc = {
1261 "statvfs_result", /* name */
1262 statvfs_result__doc__, /* doc */
1263 statvfs_result_fields,
1264 10
1265};
1266
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001267static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001268static PyTypeObject StatResultType;
1269static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001270static newfunc structseq_new;
1271
1272static PyObject *
1273statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1274{
1275 PyStructSequence *result;
1276 int i;
1277
1278 result = (PyStructSequence*)structseq_new(type, args, kwds);
1279 if (!result)
1280 return NULL;
1281 /* If we have been initialized from a tuple,
1282 st_?time might be set to None. Initialize it
1283 from the int slots. */
1284 for (i = 7; i <= 9; i++) {
1285 if (result->ob_item[i+3] == Py_None) {
1286 Py_DECREF(Py_None);
1287 Py_INCREF(result->ob_item[i]);
1288 result->ob_item[i+3] = result->ob_item[i];
1289 }
1290 }
1291 return (PyObject*)result;
1292}
1293
1294
1295
1296/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001297static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001298
1299PyDoc_STRVAR(stat_float_times__doc__,
1300"stat_float_times([newval]) -> oldval\n\n\
1301Determine whether os.[lf]stat represents time stamps as float objects.\n\
1302If newval is True, future calls to stat() return floats, if it is False,\n\
1303future calls return ints. \n\
1304If newval is omitted, return the current setting.\n");
1305
1306static PyObject*
1307stat_float_times(PyObject* self, PyObject *args)
1308{
1309 int newval = -1;
1310 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1311 return NULL;
1312 if (newval == -1)
1313 /* Return old value */
1314 return PyBool_FromLong(_stat_float_times);
1315 _stat_float_times = newval;
1316 Py_INCREF(Py_None);
1317 return Py_None;
1318}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001319
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001320static void
1321fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1322{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001323 PyObject *fval,*ival;
1324#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001325 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001326#else
1327 ival = PyInt_FromLong((long)sec);
1328#endif
Neal Norwitze0a81af2006-08-12 01:50:38 +00001329 if (!ival)
1330 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001331 if (_stat_float_times) {
1332 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1333 } else {
1334 fval = ival;
1335 Py_INCREF(fval);
1336 }
1337 PyStructSequence_SET_ITEM(v, index, ival);
1338 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001339}
1340
Tim Peters5aa91602002-01-30 05:46:57 +00001341/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001342 (used by posix_stat() and posix_fstat()) */
1343static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001344_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001345{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001346 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001347 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001348 if (v == NULL)
1349 return NULL;
1350
Martin v. Löwis14694662006-02-03 12:54:16 +00001351 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001352#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001353 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001354 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001355#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001356 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001357#endif
1358#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001359 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001360 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001361#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001362 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001363#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001364 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1365 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1366 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001367#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001368 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001369 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001370#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001371 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001372#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001373
Martin v. Löwis14694662006-02-03 12:54:16 +00001374#if defined(HAVE_STAT_TV_NSEC)
1375 ansec = st->st_atim.tv_nsec;
1376 mnsec = st->st_mtim.tv_nsec;
1377 cnsec = st->st_ctim.tv_nsec;
1378#elif defined(HAVE_STAT_TV_NSEC2)
1379 ansec = st->st_atimespec.tv_nsec;
1380 mnsec = st->st_mtimespec.tv_nsec;
1381 cnsec = st->st_ctimespec.tv_nsec;
1382#elif defined(HAVE_STAT_NSEC)
1383 ansec = st->st_atime_nsec;
1384 mnsec = st->st_mtime_nsec;
1385 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001386#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001387 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001388#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001389 fill_time(v, 7, st->st_atime, ansec);
1390 fill_time(v, 8, st->st_mtime, mnsec);
1391 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001392
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001393#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001394 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001395 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001396#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001397#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001398 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001399 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001400#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001401#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001402 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001403 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001404#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001405#ifdef HAVE_STRUCT_STAT_ST_GEN
1406 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001407 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001408#endif
1409#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1410 {
1411 PyObject *val;
1412 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001413 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001414#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001415 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001416#else
1417 bnsec = 0;
1418#endif
1419 if (_stat_float_times) {
1420 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1421 } else {
1422 val = PyInt_FromLong((long)bsec);
1423 }
1424 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1425 val);
1426 }
1427#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001428#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1429 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001430 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001431#endif
Fred Drake699f3522000-06-29 21:12:41 +00001432
1433 if (PyErr_Occurred()) {
1434 Py_DECREF(v);
1435 return NULL;
1436 }
1437
1438 return v;
1439}
1440
Martin v. Löwisd8948722004-06-02 09:57:56 +00001441#ifdef MS_WINDOWS
1442
1443/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1444 where / can be used in place of \ and the trailing slash is optional.
1445 Both SERVER and SHARE must have at least one character.
1446*/
1447
1448#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1449#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001450#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001451#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001452#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001453
Tim Peters4ad82172004-08-30 17:02:04 +00001454static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001455IsUNCRootA(char *path, int pathlen)
1456{
1457 #define ISSLASH ISSLASHA
1458
1459 int i, share;
1460
1461 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1462 /* minimum UNCRoot is \\x\y */
1463 return FALSE;
1464 for (i = 2; i < pathlen ; i++)
1465 if (ISSLASH(path[i])) break;
1466 if (i == 2 || i == pathlen)
1467 /* do not allow \\\SHARE or \\SERVER */
1468 return FALSE;
1469 share = i+1;
1470 for (i = share; i < pathlen; i++)
1471 if (ISSLASH(path[i])) break;
1472 return (i != share && (i == pathlen || i == pathlen-1));
1473
1474 #undef ISSLASH
1475}
1476
Tim Peters4ad82172004-08-30 17:02:04 +00001477static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001478IsUNCRootW(Py_UNICODE *path, int pathlen)
1479{
1480 #define ISSLASH ISSLASHW
1481
1482 int i, share;
1483
1484 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1485 /* minimum UNCRoot is \\x\y */
1486 return FALSE;
1487 for (i = 2; i < pathlen ; i++)
1488 if (ISSLASH(path[i])) break;
1489 if (i == 2 || i == pathlen)
1490 /* do not allow \\\SHARE or \\SERVER */
1491 return FALSE;
1492 share = i+1;
1493 for (i = share; i < pathlen; i++)
1494 if (ISSLASH(path[i])) break;
1495 return (i != share && (i == pathlen || i == pathlen-1));
1496
1497 #undef ISSLASH
1498}
Martin v. Löwisd8948722004-06-02 09:57:56 +00001499#endif /* MS_WINDOWS */
1500
Barry Warsaw53699e91996-12-10 23:23:01 +00001501static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001502posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001503 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001504#ifdef __VMS
1505 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1506#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001507 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001508#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001509 char *wformat,
1510 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001511{
Fred Drake699f3522000-06-29 21:12:41 +00001512 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001513 char *path = NULL; /* pass this to stat; do not free() it */
1514 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001515 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001516 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001517
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001518#ifdef MS_WINDOWS
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001519 PyUnicodeObject *po;
1520 if (PyArg_ParseTuple(args, wformat, &po)) {
1521 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001522
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001523 Py_BEGIN_ALLOW_THREADS
1524 /* PyUnicode_AS_UNICODE result OK without
1525 thread lock as it is a simple dereference. */
1526 res = wstatfunc(wpath, &st);
1527 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001528
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001529 if (res != 0)
1530 return win32_error_unicode("stat", wpath);
1531 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001532 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001533 /* Drop the argument parsing error as narrow strings
1534 are also valid. */
1535 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001536#endif
1537
Tim Peters5aa91602002-01-30 05:46:57 +00001538 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001539 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001540 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001541 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001542
Barry Warsaw53699e91996-12-10 23:23:01 +00001543 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001544 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001545 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001546
1547 if (res != 0) {
1548#ifdef MS_WINDOWS
1549 result = win32_error("stat", pathfree);
1550#else
1551 result = posix_error_with_filename(pathfree);
1552#endif
1553 }
1554 else
1555 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001556
Tim Peters500bd032001-12-19 19:05:01 +00001557 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001558 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001559}
1560
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001561/* POSIX methods */
1562
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001563PyDoc_STRVAR(posix_access__doc__,
Georg Brandl7a284472007-01-27 19:38:50 +00001564"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001565Use the real uid/gid to test for access to a path. Note that most\n\
1566operations will use the effective uid/gid, therefore this routine can\n\
1567be used in a suid/sgid environment to test if the invoking user has the\n\
1568specified access to the path. The mode argument can be F_OK to test\n\
1569existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001570
1571static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001572posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001573{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001574 char *path;
1575 int mode;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001576
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001577#ifdef MS_WINDOWS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001578 DWORD attr;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001579 PyUnicodeObject *po;
1580 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1581 Py_BEGIN_ALLOW_THREADS
1582 /* PyUnicode_AS_UNICODE OK without thread lock as
1583 it is a simple dereference. */
1584 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1585 Py_END_ALLOW_THREADS
1586 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001587 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001588 /* Drop the argument parsing error as narrow strings
1589 are also valid. */
1590 PyErr_Clear();
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001591 if (!PyArg_ParseTuple(args, "eti:access",
1592 Py_FileSystemDefaultEncoding, &path, &mode))
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001593 return NULL;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001594 Py_BEGIN_ALLOW_THREADS
1595 attr = GetFileAttributesA(path);
1596 Py_END_ALLOW_THREADS
1597 PyMem_Free(path);
1598finish:
1599 if (attr == 0xFFFFFFFF)
1600 /* File does not exist, or cannot read attributes */
1601 return PyBool_FromLong(0);
1602 /* Access is possible if either write access wasn't requested, or
Martin v. Löwis7b3cc062007-12-03 23:09:04 +00001603 the file isn't read-only, or if it's a directory, as there are
1604 no read-only directories on Windows. */
1605 return PyBool_FromLong(!(mode & 2)
1606 || !(attr & FILE_ATTRIBUTE_READONLY)
1607 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001608#else /* MS_WINDOWS */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001609 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001610 if (!PyArg_ParseTuple(args, "eti:access",
1611 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001612 return NULL;
1613 Py_BEGIN_ALLOW_THREADS
1614 res = access(path, mode);
1615 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001616 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001617 return PyBool_FromLong(res == 0);
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001618#endif /* MS_WINDOWS */
Guido van Rossum94f6f721999-01-06 18:42:14 +00001619}
1620
Guido van Rossumd371ff11999-01-25 16:12:23 +00001621#ifndef F_OK
1622#define F_OK 0
1623#endif
1624#ifndef R_OK
1625#define R_OK 4
1626#endif
1627#ifndef W_OK
1628#define W_OK 2
1629#endif
1630#ifndef X_OK
1631#define X_OK 1
1632#endif
1633
1634#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001635PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001636"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001637Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001638
1639static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001640posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001641{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001642 int id;
1643 char *ret;
1644
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001645 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001646 return NULL;
1647
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001648#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001649 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001650 if (id == 0) {
1651 ret = ttyname();
1652 }
1653 else {
1654 ret = NULL;
1655 }
1656#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001657 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001658#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001659 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001660 return posix_error();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001661 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001662}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001663#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001664
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001665#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001666PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001667"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001668Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001669
1670static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001671posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001672{
1673 char *ret;
1674 char buffer[L_ctermid];
1675
Greg Wardb48bc172000-03-01 21:51:56 +00001676#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001677 ret = ctermid_r(buffer);
1678#else
1679 ret = ctermid(buffer);
1680#endif
1681 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001682 return posix_error();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001683 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001684}
1685#endif
1686
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001687PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001688"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001689Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001690
Barry Warsaw53699e91996-12-10 23:23:01 +00001691static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001692posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001693{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001694#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001695 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001696#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001697 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001698#elif defined(__VMS)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001699 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001700#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001701 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001702#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001703}
1704
Fred Drake4d1e64b2002-04-15 19:40:07 +00001705#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001706PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001707"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001708Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001709opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001710
1711static PyObject *
1712posix_fchdir(PyObject *self, PyObject *fdobj)
1713{
1714 return posix_fildes(fdobj, fchdir);
1715}
1716#endif /* HAVE_FCHDIR */
1717
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001718
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001719PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001720"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001721Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001722
Barry Warsaw53699e91996-12-10 23:23:01 +00001723static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001724posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001725{
Mark Hammondef8b6542001-05-13 08:04:26 +00001726 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001727 int i;
1728 int res;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001729#ifdef MS_WINDOWS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001730 DWORD attr;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001731 PyUnicodeObject *po;
1732 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1733 Py_BEGIN_ALLOW_THREADS
1734 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1735 if (attr != 0xFFFFFFFF) {
1736 if (i & _S_IWRITE)
1737 attr &= ~FILE_ATTRIBUTE_READONLY;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001738 else
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001739 attr |= FILE_ATTRIBUTE_READONLY;
1740 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
Mark Hammond817c9292003-12-03 01:22:38 +00001741 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001742 else
1743 res = 0;
1744 Py_END_ALLOW_THREADS
1745 if (!res)
1746 return win32_error_unicode("chmod",
1747 PyUnicode_AS_UNICODE(po));
1748 Py_INCREF(Py_None);
1749 return Py_None;
Mark Hammond817c9292003-12-03 01:22:38 +00001750 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001751 /* Drop the argument parsing error as narrow strings
1752 are also valid. */
1753 PyErr_Clear();
1754
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001755 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1756 &path, &i))
1757 return NULL;
1758 Py_BEGIN_ALLOW_THREADS
1759 attr = GetFileAttributesA(path);
1760 if (attr != 0xFFFFFFFF) {
1761 if (i & _S_IWRITE)
1762 attr &= ~FILE_ATTRIBUTE_READONLY;
1763 else
1764 attr |= FILE_ATTRIBUTE_READONLY;
1765 res = SetFileAttributesA(path, attr);
1766 }
1767 else
1768 res = 0;
1769 Py_END_ALLOW_THREADS
1770 if (!res) {
1771 win32_error("chmod", path);
1772 PyMem_Free(path);
1773 return NULL;
1774 }
Martin v. Löwis9f485bc2006-05-08 05:25:56 +00001775 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001776 Py_INCREF(Py_None);
1777 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001778#else /* MS_WINDOWS */
Mark Hammond817c9292003-12-03 01:22:38 +00001779 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001780 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001781 return NULL;
1782 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001783 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001784 Py_END_ALLOW_THREADS
1785 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001786 return posix_error_with_allocated_filename(path);
1787 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001788 Py_INCREF(Py_None);
1789 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001790#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001791}
1792
Christian Heimes36281872007-11-30 21:11:28 +00001793#ifdef HAVE_FCHMOD
1794PyDoc_STRVAR(posix_fchmod__doc__,
1795"fchmod(fd, mode)\n\n\
1796Change the access permissions of the file given by file\n\
1797descriptor fd.");
1798
1799static PyObject *
1800posix_fchmod(PyObject *self, PyObject *args)
1801{
1802 int fd, mode, res;
1803 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1804 return NULL;
1805 Py_BEGIN_ALLOW_THREADS
1806 res = fchmod(fd, mode);
1807 Py_END_ALLOW_THREADS
1808 if (res < 0)
1809 return posix_error();
1810 Py_RETURN_NONE;
1811}
1812#endif /* HAVE_FCHMOD */
1813
1814#ifdef HAVE_LCHMOD
1815PyDoc_STRVAR(posix_lchmod__doc__,
1816"lchmod(path, mode)\n\n\
1817Change the access permissions of a file. If path is a symlink, this\n\
1818affects the link itself rather than the target.");
1819
1820static PyObject *
1821posix_lchmod(PyObject *self, PyObject *args)
1822{
1823 char *path = NULL;
1824 int i;
1825 int res;
1826 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1827 &path, &i))
1828 return NULL;
1829 Py_BEGIN_ALLOW_THREADS
1830 res = lchmod(path, i);
1831 Py_END_ALLOW_THREADS
1832 if (res < 0)
1833 return posix_error_with_allocated_filename(path);
1834 PyMem_Free(path);
1835 Py_RETURN_NONE;
1836}
1837#endif /* HAVE_LCHMOD */
1838
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001839
Martin v. Löwis382abef2007-02-19 10:55:19 +00001840#ifdef HAVE_CHFLAGS
1841PyDoc_STRVAR(posix_chflags__doc__,
1842"chflags(path, flags)\n\n\
1843Set file flags.");
1844
1845static PyObject *
1846posix_chflags(PyObject *self, PyObject *args)
1847{
1848 char *path;
1849 unsigned long flags;
1850 int res;
1851 if (!PyArg_ParseTuple(args, "etk:chflags",
1852 Py_FileSystemDefaultEncoding, &path, &flags))
1853 return NULL;
1854 Py_BEGIN_ALLOW_THREADS
1855 res = chflags(path, flags);
1856 Py_END_ALLOW_THREADS
1857 if (res < 0)
1858 return posix_error_with_allocated_filename(path);
1859 PyMem_Free(path);
1860 Py_INCREF(Py_None);
1861 return Py_None;
1862}
1863#endif /* HAVE_CHFLAGS */
1864
1865#ifdef HAVE_LCHFLAGS
1866PyDoc_STRVAR(posix_lchflags__doc__,
1867"lchflags(path, flags)\n\n\
1868Set file flags.\n\
1869This function will not follow symbolic links.");
1870
1871static PyObject *
1872posix_lchflags(PyObject *self, PyObject *args)
1873{
1874 char *path;
1875 unsigned long flags;
1876 int res;
1877 if (!PyArg_ParseTuple(args, "etk:lchflags",
1878 Py_FileSystemDefaultEncoding, &path, &flags))
1879 return NULL;
1880 Py_BEGIN_ALLOW_THREADS
1881 res = lchflags(path, flags);
1882 Py_END_ALLOW_THREADS
1883 if (res < 0)
1884 return posix_error_with_allocated_filename(path);
1885 PyMem_Free(path);
1886 Py_INCREF(Py_None);
1887 return Py_None;
1888}
1889#endif /* HAVE_LCHFLAGS */
1890
Martin v. Löwis244edc82001-10-04 22:44:26 +00001891#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001892PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001893"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001894Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001895
1896static PyObject *
1897posix_chroot(PyObject *self, PyObject *args)
1898{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001899 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001900}
1901#endif
1902
Guido van Rossum21142a01999-01-08 21:05:37 +00001903#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001904PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001905"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001906force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001907
1908static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001909posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001910{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001911 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001912}
1913#endif /* HAVE_FSYNC */
1914
1915#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001916
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001917#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001918extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1919#endif
1920
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001921PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001922"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001923force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001924 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001925
1926static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001927posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001928{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001929 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001930}
1931#endif /* HAVE_FDATASYNC */
1932
1933
Fredrik Lundh10723342000-07-10 16:38:09 +00001934#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001935PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001936"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001937Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001938
Barry Warsaw53699e91996-12-10 23:23:01 +00001939static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001940posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001941{
Mark Hammondef8b6542001-05-13 08:04:26 +00001942 char *path = NULL;
Gregory P. Smithf48da8f2008-03-18 19:05:32 +00001943 long uid, gid;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001944 int res;
Gregory P. Smithf48da8f2008-03-18 19:05:32 +00001945 if (!PyArg_ParseTuple(args, "etll:chown",
Tim Peters5aa91602002-01-30 05:46:57 +00001946 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001947 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001948 return NULL;
1949 Py_BEGIN_ALLOW_THREADS
1950 res = chown(path, (uid_t) uid, (gid_t) gid);
1951 Py_END_ALLOW_THREADS
1952 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001953 return posix_error_with_allocated_filename(path);
1954 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001955 Py_INCREF(Py_None);
1956 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001957}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001958#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001959
Christian Heimes36281872007-11-30 21:11:28 +00001960#ifdef HAVE_FCHOWN
1961PyDoc_STRVAR(posix_fchown__doc__,
1962"fchown(fd, uid, gid)\n\n\
1963Change the owner and group id of the file given by file descriptor\n\
1964fd to the numeric uid and gid.");
1965
1966static PyObject *
1967posix_fchown(PyObject *self, PyObject *args)
1968{
1969 int fd, uid, gid;
1970 int res;
1971 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
1972 return NULL;
1973 Py_BEGIN_ALLOW_THREADS
1974 res = fchown(fd, (uid_t) uid, (gid_t) gid);
1975 Py_END_ALLOW_THREADS
1976 if (res < 0)
1977 return posix_error();
1978 Py_RETURN_NONE;
1979}
1980#endif /* HAVE_FCHOWN */
1981
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001982#ifdef HAVE_LCHOWN
1983PyDoc_STRVAR(posix_lchown__doc__,
1984"lchown(path, uid, gid)\n\n\
1985Change the owner and group id of path to the numeric uid and gid.\n\
1986This function will not follow symbolic links.");
1987
1988static PyObject *
1989posix_lchown(PyObject *self, PyObject *args)
1990{
1991 char *path = NULL;
1992 int uid, gid;
1993 int res;
1994 if (!PyArg_ParseTuple(args, "etii:lchown",
1995 Py_FileSystemDefaultEncoding, &path,
1996 &uid, &gid))
1997 return NULL;
1998 Py_BEGIN_ALLOW_THREADS
1999 res = lchown(path, (uid_t) uid, (gid_t) gid);
2000 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00002001 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002002 return posix_error_with_allocated_filename(path);
2003 PyMem_Free(path);
2004 Py_INCREF(Py_None);
2005 return Py_None;
2006}
2007#endif /* HAVE_LCHOWN */
2008
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002009
Guido van Rossum36bc6801995-06-14 22:54:23 +00002010#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002011PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002012"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002013Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002014
Barry Warsaw53699e91996-12-10 23:23:01 +00002015static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002016posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002017{
Facundo Batista5596b0c2008-06-22 13:36:20 +00002018 int bufsize_incr = 1024;
2019 int bufsize = 0;
2020 char *tmpbuf = NULL;
2021 char *res = NULL;
2022 PyObject *dynamic_return;
Neal Norwitze241ce82003-02-17 18:17:05 +00002023
Barry Warsaw53699e91996-12-10 23:23:01 +00002024 Py_BEGIN_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00002025 do {
2026 bufsize = bufsize + bufsize_incr;
2027 tmpbuf = malloc(bufsize);
2028 if (tmpbuf == NULL) {
2029 break;
2030 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002031#if defined(PYOS_OS2) && defined(PYCC_GCC)
Facundo Batista5596b0c2008-06-22 13:36:20 +00002032 res = _getcwd2(tmpbuf, bufsize);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002033#else
Facundo Batista5596b0c2008-06-22 13:36:20 +00002034 res = getcwd(tmpbuf, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002035#endif
Facundo Batista5596b0c2008-06-22 13:36:20 +00002036
2037 if (res == NULL) {
2038 free(tmpbuf);
2039 }
2040 } while ((res == NULL) && (errno == ERANGE));
Barry Warsaw53699e91996-12-10 23:23:01 +00002041 Py_END_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00002042
Guido van Rossumff4949e1992-08-05 19:58:53 +00002043 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002044 return posix_error();
Facundo Batista5596b0c2008-06-22 13:36:20 +00002045
2046 dynamic_return = PyString_FromString(tmpbuf);
2047 free(tmpbuf);
2048
2049 return dynamic_return;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002050}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002051
Walter Dörwald3b918c32002-11-21 20:18:46 +00002052#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002053PyDoc_STRVAR(posix_getcwdu__doc__,
2054"getcwdu() -> path\n\n\
2055Return a unicode string representing the current working directory.");
2056
2057static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002058posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002059{
2060 char buf[1026];
2061 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002062
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002063#ifdef MS_WINDOWS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002064 DWORD len;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002065 wchar_t wbuf[1026];
2066 wchar_t *wbuf2 = wbuf;
2067 PyObject *resobj;
2068 Py_BEGIN_ALLOW_THREADS
2069 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2070 /* If the buffer is large enough, len does not include the
2071 terminating \0. If the buffer is too small, len includes
2072 the space needed for the terminator. */
2073 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2074 wbuf2 = malloc(len * sizeof(wchar_t));
2075 if (wbuf2)
2076 len = GetCurrentDirectoryW(len, wbuf2);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002077 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002078 Py_END_ALLOW_THREADS
2079 if (!wbuf2) {
2080 PyErr_NoMemory();
2081 return NULL;
2082 }
2083 if (!len) {
2084 if (wbuf2 != wbuf) free(wbuf2);
2085 return win32_error("getcwdu", NULL);
2086 }
2087 resobj = PyUnicode_FromWideChar(wbuf2, len);
2088 if (wbuf2 != wbuf) free(wbuf2);
2089 return resobj;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002090#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002091
2092 Py_BEGIN_ALLOW_THREADS
2093#if defined(PYOS_OS2) && defined(PYCC_GCC)
2094 res = _getcwd2(buf, sizeof buf);
2095#else
2096 res = getcwd(buf, sizeof buf);
2097#endif
2098 Py_END_ALLOW_THREADS
2099 if (res == NULL)
2100 return posix_error();
2101 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
2102}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002103#endif /* Py_USING_UNICODE */
2104#endif /* HAVE_GETCWD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002105
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002106
Guido van Rossumb6775db1994-08-01 11:34:53 +00002107#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002108PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002109"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002110Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002111
Barry Warsaw53699e91996-12-10 23:23:01 +00002112static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002113posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002114{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002115 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002116}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002117#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002118
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002119
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002120PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002121"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002122Return a list containing the names of the entries in the directory.\n\
2123\n\
2124 path: path of directory to list\n\
2125\n\
2126The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002127entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002128
Barry Warsaw53699e91996-12-10 23:23:01 +00002129static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002130posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002131{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002132 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002133 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002134#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002135
Barry Warsaw53699e91996-12-10 23:23:01 +00002136 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002137 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002138 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002139 WIN32_FIND_DATA FileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002140 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00002141 char *bufptr = namebuf;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002142 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002143
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002144 PyObject *po;
2145 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2146 WIN32_FIND_DATAW wFileData;
2147 Py_UNICODE *wnamebuf;
2148 /* Overallocate for \\*.*\0 */
2149 len = PyUnicode_GET_SIZE(po);
2150 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2151 if (!wnamebuf) {
2152 PyErr_NoMemory();
2153 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002154 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002155 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2156 if (len > 0) {
2157 Py_UNICODE wch = wnamebuf[len-1];
2158 if (wch != L'/' && wch != L'\\' && wch != L':')
2159 wnamebuf[len++] = L'\\';
2160 wcscpy(wnamebuf + len, L"*.*");
2161 }
2162 if ((d = PyList_New(0)) == NULL) {
2163 free(wnamebuf);
2164 return NULL;
2165 }
2166 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2167 if (hFindFile == INVALID_HANDLE_VALUE) {
2168 int error = GetLastError();
2169 if (error == ERROR_FILE_NOT_FOUND) {
2170 free(wnamebuf);
2171 return d;
2172 }
2173 Py_DECREF(d);
2174 win32_error_unicode("FindFirstFileW", wnamebuf);
2175 free(wnamebuf);
2176 return NULL;
2177 }
2178 do {
2179 /* Skip over . and .. */
2180 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2181 wcscmp(wFileData.cFileName, L"..") != 0) {
2182 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2183 if (v == NULL) {
2184 Py_DECREF(d);
2185 d = NULL;
2186 break;
2187 }
2188 if (PyList_Append(d, v) != 0) {
2189 Py_DECREF(v);
2190 Py_DECREF(d);
2191 d = NULL;
2192 break;
2193 }
2194 Py_DECREF(v);
2195 }
2196 Py_BEGIN_ALLOW_THREADS
2197 result = FindNextFileW(hFindFile, &wFileData);
2198 Py_END_ALLOW_THREADS
2199 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2200 it got to the end of the directory. */
2201 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2202 Py_DECREF(d);
2203 win32_error_unicode("FindNextFileW", wnamebuf);
2204 FindClose(hFindFile);
2205 free(wnamebuf);
2206 return NULL;
2207 }
2208 } while (result == TRUE);
2209
2210 if (FindClose(hFindFile) == FALSE) {
2211 Py_DECREF(d);
2212 win32_error_unicode("FindClose", wnamebuf);
2213 free(wnamebuf);
2214 return NULL;
2215 }
2216 free(wnamebuf);
2217 return d;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002218 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002219 /* Drop the argument parsing error as narrow strings
2220 are also valid. */
2221 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002222
Tim Peters5aa91602002-01-30 05:46:57 +00002223 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002224 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002225 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002226 if (len > 0) {
2227 char ch = namebuf[len-1];
2228 if (ch != SEP && ch != ALTSEP && ch != ':')
2229 namebuf[len++] = '/';
Hirokazu Yamamoto406d7aa2009-05-04 05:28:39 +00002230 strcpy(namebuf + len, "*.*");
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002231 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002232
Barry Warsaw53699e91996-12-10 23:23:01 +00002233 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002234 return NULL;
2235
2236 hFindFile = FindFirstFile(namebuf, &FileData);
2237 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002238 int error = GetLastError();
2239 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002240 return d;
2241 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002242 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002243 }
2244 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002245 /* Skip over . and .. */
2246 if (strcmp(FileData.cFileName, ".") != 0 &&
2247 strcmp(FileData.cFileName, "..") != 0) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002248 v = PyString_FromString(FileData.cFileName);
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002249 if (v == NULL) {
2250 Py_DECREF(d);
2251 d = NULL;
2252 break;
2253 }
2254 if (PyList_Append(d, v) != 0) {
2255 Py_DECREF(v);
2256 Py_DECREF(d);
2257 d = NULL;
2258 break;
2259 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002260 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002261 }
Georg Brandl622927b2006-03-07 12:48:03 +00002262 Py_BEGIN_ALLOW_THREADS
2263 result = FindNextFile(hFindFile, &FileData);
2264 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00002265 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2266 it got to the end of the directory. */
2267 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2268 Py_DECREF(d);
2269 win32_error("FindNextFile", namebuf);
2270 FindClose(hFindFile);
2271 return NULL;
2272 }
Georg Brandl622927b2006-03-07 12:48:03 +00002273 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002274
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002275 if (FindClose(hFindFile) == FALSE) {
2276 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002277 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002278 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002279
2280 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002281
Tim Peters0bb44a42000-09-15 07:44:49 +00002282#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002283
2284#ifndef MAX_PATH
2285#define MAX_PATH CCHMAXPATH
2286#endif
2287 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002288 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002289 PyObject *d, *v;
2290 char namebuf[MAX_PATH+5];
2291 HDIR hdir = 1;
2292 ULONG srchcnt = 1;
2293 FILEFINDBUF3 ep;
2294 APIRET rc;
2295
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002296 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002297 return NULL;
2298 if (len >= MAX_PATH) {
2299 PyErr_SetString(PyExc_ValueError, "path too long");
2300 return NULL;
2301 }
2302 strcpy(namebuf, name);
2303 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002304 if (*pt == ALTSEP)
2305 *pt = SEP;
2306 if (namebuf[len-1] != SEP)
2307 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002308 strcpy(namebuf + len, "*.*");
2309
2310 if ((d = PyList_New(0)) == NULL)
2311 return NULL;
2312
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002313 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2314 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002315 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002316 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2317 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2318 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002319
2320 if (rc != NO_ERROR) {
2321 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002322 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002323 }
2324
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002325 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002326 do {
2327 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002328 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002329 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002330
2331 strcpy(namebuf, ep.achName);
2332
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002333 /* Leave Case of Name Alone -- In Native Form */
2334 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002335
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002336 v = PyString_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002337 if (v == NULL) {
2338 Py_DECREF(d);
2339 d = NULL;
2340 break;
2341 }
2342 if (PyList_Append(d, v) != 0) {
2343 Py_DECREF(v);
2344 Py_DECREF(d);
2345 d = NULL;
2346 break;
2347 }
2348 Py_DECREF(v);
2349 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2350 }
2351
2352 return d;
2353#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002354
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002355 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002356 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002357 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002358 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002359 int arg_is_unicode = 1;
2360
Georg Brandl05e89b82006-04-11 07:04:06 +00002361 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002362 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2363 arg_is_unicode = 0;
2364 PyErr_Clear();
2365 }
2366 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002367 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002368 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002369 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002370 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002371 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002372 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002373 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002374 return NULL;
2375 }
Georg Brandl622927b2006-03-07 12:48:03 +00002376 for (;;) {
Georg Brandl86cbf812008-07-16 21:31:41 +00002377 errno = 0;
Georg Brandl622927b2006-03-07 12:48:03 +00002378 Py_BEGIN_ALLOW_THREADS
2379 ep = readdir(dirp);
2380 Py_END_ALLOW_THREADS
Georg Brandl86cbf812008-07-16 21:31:41 +00002381 if (ep == NULL) {
2382 if (errno == 0) {
2383 break;
2384 } else {
2385 closedir(dirp);
2386 Py_DECREF(d);
2387 return posix_error_with_allocated_filename(name);
2388 }
2389 }
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002390 if (ep->d_name[0] == '.' &&
2391 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002392 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002393 continue;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002394 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002395 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002396 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002397 d = NULL;
2398 break;
2399 }
Just van Rossum46c97842003-02-25 21:42:15 +00002400#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00002401 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002402 PyObject *w;
2403
2404 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002405 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002406 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002407 if (w != NULL) {
2408 Py_DECREF(v);
2409 v = w;
2410 }
2411 else {
2412 /* fall back to the original byte string, as
2413 discussed in patch #683592 */
2414 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002415 }
Just van Rossum46c97842003-02-25 21:42:15 +00002416 }
2417#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002418 if (PyList_Append(d, v) != 0) {
2419 Py_DECREF(v);
2420 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002421 d = NULL;
2422 break;
2423 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002424 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002425 }
2426 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002427 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002428
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002429 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002430
Tim Peters0bb44a42000-09-15 07:44:49 +00002431#endif /* which OS */
2432} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002433
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002434#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002435/* A helper function for abspath on win32 */
2436static PyObject *
2437posix__getfullpathname(PyObject *self, PyObject *args)
2438{
Mark Dickinson3e4caeb2009-02-21 20:27:01 +00002439 /* assume encoded strings won't more than double no of chars */
Mark Hammondef8b6542001-05-13 08:04:26 +00002440 char inbuf[MAX_PATH*2];
2441 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002442 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002443 char outbuf[MAX_PATH*2];
2444 char *temp;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002445
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002446 PyUnicodeObject *po;
2447 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2448 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2449 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2450 Py_UNICODE *wtemp;
2451 DWORD result;
2452 PyObject *v;
2453 result = GetFullPathNameW(wpath,
2454 sizeof(woutbuf)/sizeof(woutbuf[0]),
2455 woutbuf, &wtemp);
2456 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2457 woutbufp = malloc(result * sizeof(Py_UNICODE));
2458 if (!woutbufp)
2459 return PyErr_NoMemory();
2460 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002461 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002462 if (result)
2463 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2464 else
2465 v = win32_error_unicode("GetFullPathNameW", wpath);
2466 if (woutbufp != woutbuf)
2467 free(woutbufp);
2468 return v;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002469 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002470 /* Drop the argument parsing error as narrow strings
2471 are also valid. */
2472 PyErr_Clear();
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002473
Tim Peters5aa91602002-01-30 05:46:57 +00002474 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2475 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002476 &insize))
2477 return NULL;
2478 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2479 outbuf, &temp))
2480 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002481 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2482 return PyUnicode_Decode(outbuf, strlen(outbuf),
2483 Py_FileSystemDefaultEncoding, NULL);
2484 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002485 return PyString_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002486} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002487#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002488
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002489PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002490"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002491Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002492
Barry Warsaw53699e91996-12-10 23:23:01 +00002493static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002494posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002495{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002496 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002497 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002498 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002499
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002500#ifdef MS_WINDOWS
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002501 PyUnicodeObject *po;
2502 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2503 Py_BEGIN_ALLOW_THREADS
2504 /* PyUnicode_AS_UNICODE OK without thread lock as
2505 it is a simple dereference. */
2506 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2507 Py_END_ALLOW_THREADS
2508 if (!res)
2509 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2510 Py_INCREF(Py_None);
2511 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002512 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002513 /* Drop the argument parsing error as narrow strings
2514 are also valid. */
2515 PyErr_Clear();
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002516 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2517 Py_FileSystemDefaultEncoding, &path, &mode))
2518 return NULL;
2519 Py_BEGIN_ALLOW_THREADS
2520 /* PyUnicode_AS_UNICODE OK without thread lock as
2521 it is a simple dereference. */
2522 res = CreateDirectoryA(path, NULL);
2523 Py_END_ALLOW_THREADS
2524 if (!res) {
2525 win32_error("mkdir", path);
2526 PyMem_Free(path);
2527 return NULL;
2528 }
2529 PyMem_Free(path);
2530 Py_INCREF(Py_None);
2531 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002532#else /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002533
Tim Peters5aa91602002-01-30 05:46:57 +00002534 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002535 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002536 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002537 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002538#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002539 res = mkdir(path);
2540#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002541 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002542#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002543 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002544 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002545 return posix_error_with_allocated_filename(path);
2546 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002547 Py_INCREF(Py_None);
2548 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002549#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002550}
2551
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002552
Neal Norwitz1818ed72006-03-26 00:29:48 +00002553/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2554#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002555#include <sys/resource.h>
2556#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002557
Neal Norwitz1818ed72006-03-26 00:29:48 +00002558
2559#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002560PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002561"nice(inc) -> new_priority\n\n\
2562Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002563
Barry Warsaw53699e91996-12-10 23:23:01 +00002564static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002565posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002566{
2567 int increment, value;
2568
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002569 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002570 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002571
2572 /* There are two flavours of 'nice': one that returns the new
2573 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002574 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2575 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002576
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002577 If we are of the nice family that returns the new priority, we
2578 need to clear errno before the call, and check if errno is filled
2579 before calling posix_error() on a returnvalue of -1, because the
2580 -1 may be the actual new priority! */
2581
2582 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002583 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002584#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002585 if (value == 0)
2586 value = getpriority(PRIO_PROCESS, 0);
2587#endif
2588 if (value == -1 && errno != 0)
2589 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002590 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002591 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002592}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002593#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002594
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002595PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002596"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002597Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002598
Barry Warsaw53699e91996-12-10 23:23:01 +00002599static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002600posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002601{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002602#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002603 PyObject *o1, *o2;
2604 char *p1, *p2;
2605 BOOL result;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002606 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002607 goto error;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002608 if (!convert_to_unicode(&o1))
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002609 goto error;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002610 if (!convert_to_unicode(&o2)) {
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002611 Py_DECREF(o1);
2612 goto error;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002613 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002614 Py_BEGIN_ALLOW_THREADS
2615 result = MoveFileW(PyUnicode_AsUnicode(o1),
2616 PyUnicode_AsUnicode(o2));
2617 Py_END_ALLOW_THREADS
2618 Py_DECREF(o1);
2619 Py_DECREF(o2);
2620 if (!result)
2621 return win32_error("rename", NULL);
2622 Py_INCREF(Py_None);
2623 return Py_None;
2624error:
2625 PyErr_Clear();
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002626 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2627 return NULL;
2628 Py_BEGIN_ALLOW_THREADS
2629 result = MoveFileA(p1, p2);
2630 Py_END_ALLOW_THREADS
2631 if (!result)
2632 return win32_error("rename", NULL);
2633 Py_INCREF(Py_None);
2634 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002635#else
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002636 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002637#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002638}
2639
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002640
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002641PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002642"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002643Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002644
Barry Warsaw53699e91996-12-10 23:23:01 +00002645static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002646posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002647{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002648#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002649 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002650#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002651 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002652#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002653}
2654
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002655
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002656PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002657"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002658Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002659
Barry Warsaw53699e91996-12-10 23:23:01 +00002660static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002661posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002662{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002663#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002664 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002665#else
2666 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2667#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002668}
2669
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002670
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002671#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002672PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002673"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002674Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002675
Barry Warsaw53699e91996-12-10 23:23:01 +00002676static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002677posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002678{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002679 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002680 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002681 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002682 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002683 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002684 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002685 Py_END_ALLOW_THREADS
2686 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002687}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002688#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002689
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002690
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002691PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002692"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002693Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002694
Barry Warsaw53699e91996-12-10 23:23:01 +00002695static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002696posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002697{
2698 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002699 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002700 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002701 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002702 if (i < 0)
2703 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002704 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002705}
2706
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002707
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002708PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002709"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002710Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002711
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002712PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002713"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002714Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002715
Barry Warsaw53699e91996-12-10 23:23:01 +00002716static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002717posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002718{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002719#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002720 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002721#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002722 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002723#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002724}
2725
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002726
Guido van Rossumb6775db1994-08-01 11:34:53 +00002727#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002728PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002729"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002730Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002731
Barry Warsaw53699e91996-12-10 23:23:01 +00002732static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002733posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002734{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002735 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002736 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002737
Barry Warsaw53699e91996-12-10 23:23:01 +00002738 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002739 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002740 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002741 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002742 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002743 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002744 u.sysname,
2745 u.nodename,
2746 u.release,
2747 u.version,
2748 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002749}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002750#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002751
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002752static int
2753extract_time(PyObject *t, long* sec, long* usec)
2754{
2755 long intval;
2756 if (PyFloat_Check(t)) {
2757 double tval = PyFloat_AsDouble(t);
Christian Heimese93237d2007-12-19 02:37:44 +00002758 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002759 if (!intobj)
2760 return -1;
2761 intval = PyInt_AsLong(intobj);
2762 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002763 if (intval == -1 && PyErr_Occurred())
2764 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002765 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002766 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002767 if (*usec < 0)
2768 /* If rounding gave us a negative number,
2769 truncate. */
2770 *usec = 0;
2771 return 0;
2772 }
2773 intval = PyInt_AsLong(t);
2774 if (intval == -1 && PyErr_Occurred())
2775 return -1;
2776 *sec = intval;
2777 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002778 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002779}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002780
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002781PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002782"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002783utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002784Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002785second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002786
Barry Warsaw53699e91996-12-10 23:23:01 +00002787static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002788posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002789{
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002790#ifdef MS_WINDOWS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002791 PyObject *arg;
2792 PyUnicodeObject *obwpath;
2793 wchar_t *wpath = NULL;
2794 char *apath = NULL;
2795 HANDLE hFile;
2796 long atimesec, mtimesec, ausec, musec;
2797 FILETIME atime, mtime;
2798 PyObject *result = NULL;
2799
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002800 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2801 wpath = PyUnicode_AS_UNICODE(obwpath);
2802 Py_BEGIN_ALLOW_THREADS
2803 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2804 NULL, OPEN_EXISTING,
2805 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2806 Py_END_ALLOW_THREADS
2807 if (hFile == INVALID_HANDLE_VALUE)
2808 return win32_error_unicode("utime", wpath);
2809 } else
2810 /* Drop the argument parsing error as narrow strings
2811 are also valid. */
2812 PyErr_Clear();
2813
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002814 if (!wpath) {
2815 if (!PyArg_ParseTuple(args, "etO:utime",
2816 Py_FileSystemDefaultEncoding, &apath, &arg))
2817 return NULL;
2818 Py_BEGIN_ALLOW_THREADS
2819 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002820 NULL, OPEN_EXISTING,
2821 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002822 Py_END_ALLOW_THREADS
2823 if (hFile == INVALID_HANDLE_VALUE) {
2824 win32_error("utime", apath);
2825 PyMem_Free(apath);
2826 return NULL;
2827 }
2828 PyMem_Free(apath);
2829 }
2830
2831 if (arg == Py_None) {
2832 SYSTEMTIME now;
2833 GetSystemTime(&now);
2834 if (!SystemTimeToFileTime(&now, &mtime) ||
2835 !SystemTimeToFileTime(&now, &atime)) {
2836 win32_error("utime", NULL);
2837 goto done;
2838 }
2839 }
2840 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2841 PyErr_SetString(PyExc_TypeError,
2842 "utime() arg 2 must be a tuple (atime, mtime)");
2843 goto done;
2844 }
2845 else {
2846 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2847 &atimesec, &ausec) == -1)
2848 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002849 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002850 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2851 &mtimesec, &musec) == -1)
2852 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002853 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002854 }
2855 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2856 /* Avoid putting the file name into the error here,
2857 as that may confuse the user into believing that
2858 something is wrong with the file, when it also
2859 could be the time stamp that gives a problem. */
2860 win32_error("utime", NULL);
2861 }
2862 Py_INCREF(Py_None);
2863 result = Py_None;
2864done:
2865 CloseHandle(hFile);
2866 return result;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002867#else /* MS_WINDOWS */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002868
Neal Norwitz2adf2102004-06-09 01:46:02 +00002869 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002870 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002871 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002872 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002873
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002874#if defined(HAVE_UTIMES)
2875 struct timeval buf[2];
2876#define ATIME buf[0].tv_sec
2877#define MTIME buf[1].tv_sec
2878#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002879/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002880 struct utimbuf buf;
2881#define ATIME buf.actime
2882#define MTIME buf.modtime
2883#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002884#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002885 time_t buf[2];
2886#define ATIME buf[0]
2887#define MTIME buf[1]
2888#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002889#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002890
Mark Hammond817c9292003-12-03 01:22:38 +00002891
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002892 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002893 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002894 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002895 if (arg == Py_None) {
2896 /* optional time values not given */
2897 Py_BEGIN_ALLOW_THREADS
2898 res = utime(path, NULL);
2899 Py_END_ALLOW_THREADS
2900 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002901 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002902 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002903 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002904 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002905 return NULL;
2906 }
2907 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002908 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002909 &atime, &ausec) == -1) {
2910 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002911 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002912 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002913 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002914 &mtime, &musec) == -1) {
2915 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002916 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002917 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002918 ATIME = atime;
2919 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002920#ifdef HAVE_UTIMES
2921 buf[0].tv_usec = ausec;
2922 buf[1].tv_usec = musec;
2923 Py_BEGIN_ALLOW_THREADS
2924 res = utimes(path, buf);
2925 Py_END_ALLOW_THREADS
2926#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002927 Py_BEGIN_ALLOW_THREADS
2928 res = utime(path, UTIME_ARG);
2929 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002930#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002931 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002932 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002933 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002934 }
Neal Norwitz96652712004-06-06 20:40:27 +00002935 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002936 Py_INCREF(Py_None);
2937 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002938#undef UTIME_ARG
2939#undef ATIME
2940#undef MTIME
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002941#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002942}
2943
Guido van Rossum85e3b011991-06-03 12:42:10 +00002944
Guido van Rossum3b066191991-06-04 19:40:25 +00002945/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002946
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002947PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002948"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002949Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002950
Barry Warsaw53699e91996-12-10 23:23:01 +00002951static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002952posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002953{
2954 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002955 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002956 return NULL;
2957 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002958 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002959}
2960
Martin v. Löwis114619e2002-10-07 06:44:21 +00002961#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2962static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002963free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002964{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002965 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002966 for (i = 0; i < count; i++)
2967 PyMem_Free(array[i]);
2968 PyMem_DEL(array);
2969}
2970#endif
2971
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002972
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002973#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002974PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002975"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002976Execute an executable path with arguments, replacing current process.\n\
2977\n\
2978 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002979 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002980
Barry Warsaw53699e91996-12-10 23:23:01 +00002981static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002982posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002983{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002984 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002985 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002986 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002987 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002988 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002989
Guido van Rossum89b33251993-10-22 14:26:06 +00002990 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002991 argv is a list or tuple of strings. */
2992
Martin v. Löwis114619e2002-10-07 06:44:21 +00002993 if (!PyArg_ParseTuple(args, "etO:execv",
2994 Py_FileSystemDefaultEncoding,
2995 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002996 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002997 if (PyList_Check(argv)) {
2998 argc = PyList_Size(argv);
2999 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003000 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003001 else if (PyTuple_Check(argv)) {
3002 argc = PyTuple_Size(argv);
3003 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003004 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003005 else {
Fred Drake661ea262000-10-24 19:57:45 +00003006 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003007 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00003008 return NULL;
3009 }
3010
Barry Warsaw53699e91996-12-10 23:23:01 +00003011 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003012 if (argvlist == NULL) {
3013 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003014 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003015 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00003016 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003017 if (!PyArg_Parse((*getitem)(argv, i), "et",
3018 Py_FileSystemDefaultEncoding,
3019 &argvlist[i])) {
3020 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00003021 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00003022 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003023 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00003024 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003025
Guido van Rossum85e3b011991-06-03 12:42:10 +00003026 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00003027 }
3028 argvlist[argc] = NULL;
3029
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003030 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003031
Guido van Rossum85e3b011991-06-03 12:42:10 +00003032 /* If we get here it's definitely an error */
3033
Martin v. Löwis114619e2002-10-07 06:44:21 +00003034 free_string_array(argvlist, argc);
3035 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003036 return posix_error();
3037}
3038
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003039
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003040PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003041"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003042Execute a path with arguments and environment, replacing current process.\n\
3043\n\
3044 path: path of executable file\n\
3045 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003046 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003047
Barry Warsaw53699e91996-12-10 23:23:01 +00003048static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003049posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003050{
3051 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003052 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003053 char **argvlist;
3054 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003055 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003056 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003057 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003058 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003059
3060 /* execve has three arguments: (path, argv, env), where
3061 argv is a list or tuple of strings and env is a dictionary
3062 like posix.environ. */
3063
Martin v. Löwis114619e2002-10-07 06:44:21 +00003064 if (!PyArg_ParseTuple(args, "etOO:execve",
3065 Py_FileSystemDefaultEncoding,
3066 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003067 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003068 if (PyList_Check(argv)) {
3069 argc = PyList_Size(argv);
3070 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003071 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003072 else if (PyTuple_Check(argv)) {
3073 argc = PyTuple_Size(argv);
3074 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003075 }
3076 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003077 PyErr_SetString(PyExc_TypeError,
3078 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003079 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003080 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003081 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003082 PyErr_SetString(PyExc_TypeError,
3083 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003084 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003085 }
3086
Barry Warsaw53699e91996-12-10 23:23:01 +00003087 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003088 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003089 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003090 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003091 }
3092 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003093 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00003094 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00003095 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00003096 &argvlist[i]))
3097 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003098 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003099 goto fail_1;
3100 }
3101 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003102 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003103 argvlist[argc] = NULL;
3104
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003105 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003106 if (i < 0)
3107 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00003108 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003109 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003110 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003111 goto fail_1;
3112 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003113 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003114 keys = PyMapping_Keys(env);
3115 vals = PyMapping_Values(env);
3116 if (!keys || !vals)
3117 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003118 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3119 PyErr_SetString(PyExc_TypeError,
3120 "execve(): env.keys() or env.values() is not a list");
3121 goto fail_2;
3122 }
Tim Peters5aa91602002-01-30 05:46:57 +00003123
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003124 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003125 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003126 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003127
3128 key = PyList_GetItem(keys, pos);
3129 val = PyList_GetItem(vals, pos);
3130 if (!key || !val)
3131 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003132
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003133 if (!PyArg_Parse(
3134 key,
3135 "s;execve() arg 3 contains a non-string key",
3136 &k) ||
3137 !PyArg_Parse(
3138 val,
3139 "s;execve() arg 3 contains a non-string value",
3140 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003141 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003142 goto fail_2;
3143 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003144
3145#if defined(PYOS_OS2)
3146 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3147 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3148#endif
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003149 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003150 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003151 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003152 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003153 goto fail_2;
3154 }
Tim Petersc8996f52001-12-03 20:41:00 +00003155 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003156 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003157#if defined(PYOS_OS2)
3158 }
3159#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003160 }
3161 envlist[envc] = 0;
3162
3163 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003164
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003165 /* If we get here it's definitely an error */
3166
3167 (void) posix_error();
3168
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003169 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003170 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003171 PyMem_DEL(envlist[envc]);
3172 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003173 fail_1:
3174 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003175 Py_XDECREF(vals);
3176 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003177 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003178 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003179 return NULL;
3180}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003181#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003182
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003183
Guido van Rossuma1065681999-01-25 23:20:23 +00003184#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003185PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003186"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003187Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003188\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003189 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003190 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003191 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003192
3193static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003194posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003195{
3196 char *path;
3197 PyObject *argv;
3198 char **argvlist;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003199 int mode, i;
3200 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003201 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003202 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003203
3204 /* spawnv has three arguments: (mode, path, argv), where
3205 argv is a list or tuple of strings. */
3206
Martin v. Löwis114619e2002-10-07 06:44:21 +00003207 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3208 Py_FileSystemDefaultEncoding,
3209 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003210 return NULL;
3211 if (PyList_Check(argv)) {
3212 argc = PyList_Size(argv);
3213 getitem = PyList_GetItem;
3214 }
3215 else if (PyTuple_Check(argv)) {
3216 argc = PyTuple_Size(argv);
3217 getitem = PyTuple_GetItem;
3218 }
3219 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003220 PyErr_SetString(PyExc_TypeError,
3221 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003222 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003223 return NULL;
3224 }
3225
3226 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003227 if (argvlist == NULL) {
3228 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003229 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003230 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003231 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003232 if (!PyArg_Parse((*getitem)(argv, i), "et",
3233 Py_FileSystemDefaultEncoding,
3234 &argvlist[i])) {
3235 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003236 PyErr_SetString(
3237 PyExc_TypeError,
3238 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003239 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00003240 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003241 }
3242 }
3243 argvlist[argc] = NULL;
3244
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003245#if defined(PYOS_OS2) && defined(PYCC_GCC)
3246 Py_BEGIN_ALLOW_THREADS
3247 spawnval = spawnv(mode, path, argvlist);
3248 Py_END_ALLOW_THREADS
3249#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003250 if (mode == _OLD_P_OVERLAY)
3251 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003252
Tim Peters25059d32001-12-07 20:35:43 +00003253 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003254 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003255 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003256#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003257
Martin v. Löwis114619e2002-10-07 06:44:21 +00003258 free_string_array(argvlist, argc);
3259 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003260
Fred Drake699f3522000-06-29 21:12:41 +00003261 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003262 return posix_error();
3263 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003264#if SIZEOF_LONG == SIZEOF_VOID_P
3265 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003266#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003267 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003268#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003269}
3270
3271
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003272PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003273"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003274Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003275\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003276 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003277 path: path of executable file\n\
3278 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003279 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003280
3281static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003282posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003283{
3284 char *path;
3285 PyObject *argv, *env;
3286 char **argvlist;
3287 char **envlist;
3288 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003289 int mode, pos, envc;
3290 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003291 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003292 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003293 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003294
3295 /* spawnve has four arguments: (mode, path, argv, env), where
3296 argv is a list or tuple of strings and env is a dictionary
3297 like posix.environ. */
3298
Martin v. Löwis114619e2002-10-07 06:44:21 +00003299 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3300 Py_FileSystemDefaultEncoding,
3301 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003302 return NULL;
3303 if (PyList_Check(argv)) {
3304 argc = PyList_Size(argv);
3305 getitem = PyList_GetItem;
3306 }
3307 else if (PyTuple_Check(argv)) {
3308 argc = PyTuple_Size(argv);
3309 getitem = PyTuple_GetItem;
3310 }
3311 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003312 PyErr_SetString(PyExc_TypeError,
3313 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003314 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003315 }
3316 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003317 PyErr_SetString(PyExc_TypeError,
3318 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003319 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003320 }
3321
3322 argvlist = PyMem_NEW(char *, argc+1);
3323 if (argvlist == NULL) {
3324 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003325 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003326 }
3327 for (i = 0; i < argc; i++) {
3328 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003329 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00003330 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00003331 &argvlist[i]))
3332 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003333 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003334 goto fail_1;
3335 }
3336 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003337 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003338 argvlist[argc] = NULL;
3339
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003340 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003341 if (i < 0)
3342 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003343 envlist = PyMem_NEW(char *, i + 1);
3344 if (envlist == NULL) {
3345 PyErr_NoMemory();
3346 goto fail_1;
3347 }
3348 envc = 0;
3349 keys = PyMapping_Keys(env);
3350 vals = PyMapping_Values(env);
3351 if (!keys || !vals)
3352 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003353 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3354 PyErr_SetString(PyExc_TypeError,
3355 "spawnve(): env.keys() or env.values() is not a list");
3356 goto fail_2;
3357 }
Tim Peters5aa91602002-01-30 05:46:57 +00003358
Guido van Rossuma1065681999-01-25 23:20:23 +00003359 for (pos = 0; pos < i; pos++) {
3360 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003361 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003362
3363 key = PyList_GetItem(keys, pos);
3364 val = PyList_GetItem(vals, pos);
3365 if (!key || !val)
3366 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003367
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003368 if (!PyArg_Parse(
3369 key,
3370 "s;spawnve() arg 3 contains a non-string key",
3371 &k) ||
3372 !PyArg_Parse(
3373 val,
3374 "s;spawnve() arg 3 contains a non-string value",
3375 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003376 {
3377 goto fail_2;
3378 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003379 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003380 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003381 if (p == NULL) {
3382 PyErr_NoMemory();
3383 goto fail_2;
3384 }
Tim Petersc8996f52001-12-03 20:41:00 +00003385 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003386 envlist[envc++] = p;
3387 }
3388 envlist[envc] = 0;
3389
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003390#if defined(PYOS_OS2) && defined(PYCC_GCC)
3391 Py_BEGIN_ALLOW_THREADS
3392 spawnval = spawnve(mode, path, argvlist, envlist);
3393 Py_END_ALLOW_THREADS
3394#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003395 if (mode == _OLD_P_OVERLAY)
3396 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003397
3398 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003399 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003400 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003401#endif
Tim Peters25059d32001-12-07 20:35:43 +00003402
Fred Drake699f3522000-06-29 21:12:41 +00003403 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003404 (void) posix_error();
3405 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003406#if SIZEOF_LONG == SIZEOF_VOID_P
3407 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003408#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003409 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003410#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003411
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003412 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003413 while (--envc >= 0)
3414 PyMem_DEL(envlist[envc]);
3415 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003416 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003417 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003418 Py_XDECREF(vals);
3419 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003420 fail_0:
3421 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003422 return res;
3423}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003424
3425/* OS/2 supports spawnvp & spawnvpe natively */
3426#if defined(PYOS_OS2)
3427PyDoc_STRVAR(posix_spawnvp__doc__,
3428"spawnvp(mode, file, args)\n\n\
3429Execute the program 'file' in a new process, using the environment\n\
3430search path to find the file.\n\
3431\n\
3432 mode: mode of process creation\n\
3433 file: executable file name\n\
3434 args: tuple or list of strings");
3435
3436static PyObject *
3437posix_spawnvp(PyObject *self, PyObject *args)
3438{
3439 char *path;
3440 PyObject *argv;
3441 char **argvlist;
3442 int mode, i, argc;
3443 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003444 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003445
3446 /* spawnvp has three arguments: (mode, path, argv), where
3447 argv is a list or tuple of strings. */
3448
3449 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3450 Py_FileSystemDefaultEncoding,
3451 &path, &argv))
3452 return NULL;
3453 if (PyList_Check(argv)) {
3454 argc = PyList_Size(argv);
3455 getitem = PyList_GetItem;
3456 }
3457 else if (PyTuple_Check(argv)) {
3458 argc = PyTuple_Size(argv);
3459 getitem = PyTuple_GetItem;
3460 }
3461 else {
3462 PyErr_SetString(PyExc_TypeError,
3463 "spawnvp() arg 2 must be a tuple or list");
3464 PyMem_Free(path);
3465 return NULL;
3466 }
3467
3468 argvlist = PyMem_NEW(char *, argc+1);
3469 if (argvlist == NULL) {
3470 PyMem_Free(path);
3471 return PyErr_NoMemory();
3472 }
3473 for (i = 0; i < argc; i++) {
3474 if (!PyArg_Parse((*getitem)(argv, i), "et",
3475 Py_FileSystemDefaultEncoding,
3476 &argvlist[i])) {
3477 free_string_array(argvlist, i);
3478 PyErr_SetString(
3479 PyExc_TypeError,
3480 "spawnvp() arg 2 must contain only strings");
3481 PyMem_Free(path);
3482 return NULL;
3483 }
3484 }
3485 argvlist[argc] = NULL;
3486
3487 Py_BEGIN_ALLOW_THREADS
3488#if defined(PYCC_GCC)
3489 spawnval = spawnvp(mode, path, argvlist);
3490#else
3491 spawnval = _spawnvp(mode, path, argvlist);
3492#endif
3493 Py_END_ALLOW_THREADS
3494
3495 free_string_array(argvlist, argc);
3496 PyMem_Free(path);
3497
3498 if (spawnval == -1)
3499 return posix_error();
3500 else
3501 return Py_BuildValue("l", (long) spawnval);
3502}
3503
3504
3505PyDoc_STRVAR(posix_spawnvpe__doc__,
3506"spawnvpe(mode, file, args, env)\n\n\
3507Execute the program 'file' in a new process, using the environment\n\
3508search path to find the file.\n\
3509\n\
3510 mode: mode of process creation\n\
3511 file: executable file name\n\
3512 args: tuple or list of arguments\n\
3513 env: dictionary of strings mapping to strings");
3514
3515static PyObject *
3516posix_spawnvpe(PyObject *self, PyObject *args)
3517{
3518 char *path;
3519 PyObject *argv, *env;
3520 char **argvlist;
3521 char **envlist;
3522 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3523 int mode, i, pos, argc, envc;
3524 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003525 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003526 int lastarg = 0;
3527
3528 /* spawnvpe has four arguments: (mode, path, argv, env), where
3529 argv is a list or tuple of strings and env is a dictionary
3530 like posix.environ. */
3531
3532 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3533 Py_FileSystemDefaultEncoding,
3534 &path, &argv, &env))
3535 return NULL;
3536 if (PyList_Check(argv)) {
3537 argc = PyList_Size(argv);
3538 getitem = PyList_GetItem;
3539 }
3540 else if (PyTuple_Check(argv)) {
3541 argc = PyTuple_Size(argv);
3542 getitem = PyTuple_GetItem;
3543 }
3544 else {
3545 PyErr_SetString(PyExc_TypeError,
3546 "spawnvpe() arg 2 must be a tuple or list");
3547 goto fail_0;
3548 }
3549 if (!PyMapping_Check(env)) {
3550 PyErr_SetString(PyExc_TypeError,
3551 "spawnvpe() arg 3 must be a mapping object");
3552 goto fail_0;
3553 }
3554
3555 argvlist = PyMem_NEW(char *, argc+1);
3556 if (argvlist == NULL) {
3557 PyErr_NoMemory();
3558 goto fail_0;
3559 }
3560 for (i = 0; i < argc; i++) {
3561 if (!PyArg_Parse((*getitem)(argv, i),
3562 "et;spawnvpe() arg 2 must contain only strings",
3563 Py_FileSystemDefaultEncoding,
3564 &argvlist[i]))
3565 {
3566 lastarg = i;
3567 goto fail_1;
3568 }
3569 }
3570 lastarg = argc;
3571 argvlist[argc] = NULL;
3572
3573 i = PyMapping_Size(env);
3574 if (i < 0)
3575 goto fail_1;
3576 envlist = PyMem_NEW(char *, i + 1);
3577 if (envlist == NULL) {
3578 PyErr_NoMemory();
3579 goto fail_1;
3580 }
3581 envc = 0;
3582 keys = PyMapping_Keys(env);
3583 vals = PyMapping_Values(env);
3584 if (!keys || !vals)
3585 goto fail_2;
3586 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3587 PyErr_SetString(PyExc_TypeError,
3588 "spawnvpe(): env.keys() or env.values() is not a list");
3589 goto fail_2;
3590 }
3591
3592 for (pos = 0; pos < i; pos++) {
3593 char *p, *k, *v;
3594 size_t len;
3595
3596 key = PyList_GetItem(keys, pos);
3597 val = PyList_GetItem(vals, pos);
3598 if (!key || !val)
3599 goto fail_2;
3600
3601 if (!PyArg_Parse(
3602 key,
3603 "s;spawnvpe() arg 3 contains a non-string key",
3604 &k) ||
3605 !PyArg_Parse(
3606 val,
3607 "s;spawnvpe() arg 3 contains a non-string value",
3608 &v))
3609 {
3610 goto fail_2;
3611 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003612 len = PyString_Size(key) + PyString_Size(val) + 2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003613 p = PyMem_NEW(char, len);
3614 if (p == NULL) {
3615 PyErr_NoMemory();
3616 goto fail_2;
3617 }
3618 PyOS_snprintf(p, len, "%s=%s", k, v);
3619 envlist[envc++] = p;
3620 }
3621 envlist[envc] = 0;
3622
3623 Py_BEGIN_ALLOW_THREADS
3624#if defined(PYCC_GCC)
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003625 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003626#else
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003627 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003628#endif
3629 Py_END_ALLOW_THREADS
3630
3631 if (spawnval == -1)
3632 (void) posix_error();
3633 else
3634 res = Py_BuildValue("l", (long) spawnval);
3635
3636 fail_2:
3637 while (--envc >= 0)
3638 PyMem_DEL(envlist[envc]);
3639 PyMem_DEL(envlist);
3640 fail_1:
3641 free_string_array(argvlist, lastarg);
3642 Py_XDECREF(vals);
3643 Py_XDECREF(keys);
3644 fail_0:
3645 PyMem_Free(path);
3646 return res;
3647}
3648#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003649#endif /* HAVE_SPAWNV */
3650
3651
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003652#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003653PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003654"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003655Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3656\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003657Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003658
3659static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003660posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003661{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003662 pid_t pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003663 if (pid == -1)
3664 return posix_error();
Gregory P. Smithfb7a50f2008-07-14 06:06:48 +00003665 if (pid == 0)
3666 PyOS_AfterFork();
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00003667 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003668}
3669#endif
3670
3671
Guido van Rossumad0ee831995-03-01 10:34:45 +00003672#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003673PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003674"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003675Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003676Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003677
Barry Warsaw53699e91996-12-10 23:23:01 +00003678static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003679posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003680{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003681 pid_t pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003682 if (pid == -1)
3683 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003684 if (pid == 0)
3685 PyOS_AfterFork();
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00003686 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003687}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003688#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003689
Neal Norwitzb59798b2003-03-21 01:43:31 +00003690/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003691/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3692#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003693#define DEV_PTY_FILE "/dev/ptc"
3694#define HAVE_DEV_PTMX
3695#else
3696#define DEV_PTY_FILE "/dev/ptmx"
3697#endif
3698
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003699#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003700#ifdef HAVE_PTY_H
3701#include <pty.h>
3702#else
3703#ifdef HAVE_LIBUTIL_H
3704#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003705#endif /* HAVE_LIBUTIL_H */
3706#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003707#ifdef HAVE_STROPTS_H
3708#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003709#endif
3710#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003711
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003712#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003713PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003714"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003715Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003716
3717static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003718posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003719{
3720 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003721#ifndef HAVE_OPENPTY
3722 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003723#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003724#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003725 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003726#ifdef sun
Neal Norwitz84a98e02006-04-10 07:44:23 +00003727 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003728#endif
3729#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003730
Thomas Wouters70c21a12000-07-14 14:28:33 +00003731#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003732 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3733 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003734#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003735 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3736 if (slave_name == NULL)
3737 return posix_error();
3738
3739 slave_fd = open(slave_name, O_RDWR);
3740 if (slave_fd < 0)
3741 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003742#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003743 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003744 if (master_fd < 0)
3745 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003746 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003747 /* change permission of slave */
3748 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003749 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003750 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003751 }
3752 /* unlock slave */
3753 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003754 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003755 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003756 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003757 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003758 slave_name = ptsname(master_fd); /* get name of slave */
3759 if (slave_name == NULL)
3760 return posix_error();
3761 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3762 if (slave_fd < 0)
3763 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003764#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003765 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3766 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003767#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003768 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003769#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003770#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003771#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003772
Fred Drake8cef4cf2000-06-28 16:40:38 +00003773 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003774
Fred Drake8cef4cf2000-06-28 16:40:38 +00003775}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003776#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003777
3778#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003779PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003780"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003781Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3782Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003783To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003784
3785static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003786posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003787{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003788 int master_fd = -1;
3789 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003790
Fred Drake8cef4cf2000-06-28 16:40:38 +00003791 pid = forkpty(&master_fd, NULL, NULL, NULL);
3792 if (pid == -1)
3793 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003794 if (pid == 0)
3795 PyOS_AfterFork();
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00003796 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003797}
3798#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003799
Guido van Rossumad0ee831995-03-01 10:34:45 +00003800#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003801PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003802"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003803Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003804
Barry Warsaw53699e91996-12-10 23:23:01 +00003805static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003806posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003807{
Barry Warsaw53699e91996-12-10 23:23:01 +00003808 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003809}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003810#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003811
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003812
Guido van Rossumad0ee831995-03-01 10:34:45 +00003813#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003814PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003815"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003816Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003817
Barry Warsaw53699e91996-12-10 23:23:01 +00003818static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003819posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003820{
Barry Warsaw53699e91996-12-10 23:23:01 +00003821 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003822}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003823#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003824
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003825
Guido van Rossumad0ee831995-03-01 10:34:45 +00003826#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003827PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003828"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003829Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003830
Barry Warsaw53699e91996-12-10 23:23:01 +00003831static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003832posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003833{
Barry Warsaw53699e91996-12-10 23:23:01 +00003834 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003835}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003836#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003837
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003838
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003839PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003840"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003841Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003842
Barry Warsaw53699e91996-12-10 23:23:01 +00003843static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003844posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003845{
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00003846 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003847}
3848
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003849
Fred Drakec9680921999-12-13 16:37:25 +00003850#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003851PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003852"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003853Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003854
3855static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003856posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003857{
3858 PyObject *result = NULL;
3859
Fred Drakec9680921999-12-13 16:37:25 +00003860#ifdef NGROUPS_MAX
3861#define MAX_GROUPS NGROUPS_MAX
3862#else
3863 /* defined to be 16 on Solaris7, so this should be a small number */
3864#define MAX_GROUPS 64
3865#endif
3866 gid_t grouplist[MAX_GROUPS];
3867 int n;
3868
3869 n = getgroups(MAX_GROUPS, grouplist);
3870 if (n < 0)
3871 posix_error();
3872 else {
3873 result = PyList_New(n);
3874 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003875 int i;
3876 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003877 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003878 if (o == NULL) {
3879 Py_DECREF(result);
3880 result = NULL;
3881 break;
3882 }
3883 PyList_SET_ITEM(result, i, o);
3884 }
3885 }
3886 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003887
Fred Drakec9680921999-12-13 16:37:25 +00003888 return result;
3889}
3890#endif
3891
Martin v. Löwis606edc12002-06-13 21:09:11 +00003892#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003893PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003894"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003895Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003896
3897static PyObject *
3898posix_getpgid(PyObject *self, PyObject *args)
3899{
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00003900 pid_t pid, pgid;
3901 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
Martin v. Löwis606edc12002-06-13 21:09:11 +00003902 return NULL;
3903 pgid = getpgid(pid);
3904 if (pgid < 0)
3905 return posix_error();
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00003906 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00003907}
3908#endif /* HAVE_GETPGID */
3909
3910
Guido van Rossumb6775db1994-08-01 11:34:53 +00003911#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003912PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003913"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003914Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003915
Barry Warsaw53699e91996-12-10 23:23:01 +00003916static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003917posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003918{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003919#ifdef GETPGRP_HAVE_ARG
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00003920 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003921#else /* GETPGRP_HAVE_ARG */
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00003922 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003923#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003924}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003925#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003926
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003927
Guido van Rossumb6775db1994-08-01 11:34:53 +00003928#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003929PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003930"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003931Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003932
Barry Warsaw53699e91996-12-10 23:23:01 +00003933static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003934posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003935{
Guido van Rossum64933891994-10-20 21:56:42 +00003936#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003937 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003938#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003939 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003940#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003941 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003942 Py_INCREF(Py_None);
3943 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003944}
3945
Guido van Rossumb6775db1994-08-01 11:34:53 +00003946#endif /* HAVE_SETPGRP */
3947
Guido van Rossumad0ee831995-03-01 10:34:45 +00003948#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003949PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003950"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003951Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003952
Barry Warsaw53699e91996-12-10 23:23:01 +00003953static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003954posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003955{
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00003956 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003957}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003958#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003959
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003960
Fred Drake12c6e2d1999-12-14 21:25:03 +00003961#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003962PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003963"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003964Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003965
3966static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003967posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003968{
Neal Norwitze241ce82003-02-17 18:17:05 +00003969 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003970 char *name;
3971 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003972
Fred Drakea30680b2000-12-06 21:24:28 +00003973 errno = 0;
3974 name = getlogin();
3975 if (name == NULL) {
3976 if (errno)
3977 posix_error();
3978 else
3979 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003980 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003981 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003982 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003983 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003984 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003985
Fred Drake12c6e2d1999-12-14 21:25:03 +00003986 return result;
3987}
3988#endif
3989
Guido van Rossumad0ee831995-03-01 10:34:45 +00003990#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003991PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003992"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003993Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003994
Barry Warsaw53699e91996-12-10 23:23:01 +00003995static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003996posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003997{
Barry Warsaw53699e91996-12-10 23:23:01 +00003998 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003999}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004000#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004001
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004002
Guido van Rossumad0ee831995-03-01 10:34:45 +00004003#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004004PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004005"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004006Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004007
Barry Warsaw53699e91996-12-10 23:23:01 +00004008static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004009posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004010{
Christian Heimesd491d712008-02-01 18:49:26 +00004011 pid_t pid;
4012 int sig;
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00004013 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00004014 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004015#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004016 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4017 APIRET rc;
4018 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004019 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004020
4021 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4022 APIRET rc;
4023 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004024 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004025
4026 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004027 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004028#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00004029 if (kill(pid, sig) == -1)
4030 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004031#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004032 Py_INCREF(Py_None);
4033 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004034}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004035#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004036
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004037#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004038PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004039"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004040Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004041
4042static PyObject *
4043posix_killpg(PyObject *self, PyObject *args)
4044{
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00004045 int sig;
4046 pid_t pgid;
4047 /* XXX some man pages make the `pgid` parameter an int, others
4048 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4049 take the same type. Moreover, pid_t is always at least as wide as
4050 int (else compilation of this module fails), which is safe. */
4051 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004052 return NULL;
4053 if (killpg(pgid, sig) == -1)
4054 return posix_error();
4055 Py_INCREF(Py_None);
4056 return Py_None;
4057}
4058#endif
4059
Guido van Rossumc0125471996-06-28 18:55:32 +00004060#ifdef HAVE_PLOCK
4061
4062#ifdef HAVE_SYS_LOCK_H
4063#include <sys/lock.h>
4064#endif
4065
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004066PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004067"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004068Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004069
Barry Warsaw53699e91996-12-10 23:23:01 +00004070static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004071posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004072{
4073 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004074 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00004075 return NULL;
4076 if (plock(op) == -1)
4077 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004078 Py_INCREF(Py_None);
4079 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004080}
4081#endif
4082
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004083
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004084#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004085PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004086"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004087Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004088
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004089#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004090#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004091static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004092async_system(const char *command)
4093{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004094 char errormsg[256], args[1024];
4095 RESULTCODES rcodes;
4096 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004097
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004098 char *shell = getenv("COMSPEC");
4099 if (!shell)
4100 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004101
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004102 /* avoid overflowing the argument buffer */
4103 if (strlen(shell) + 3 + strlen(command) >= 1024)
4104 return ERROR_NOT_ENOUGH_MEMORY
4105
4106 args[0] = '\0';
4107 strcat(args, shell);
4108 strcat(args, "/c ");
4109 strcat(args, command);
4110
4111 /* execute asynchronously, inheriting the environment */
4112 rc = DosExecPgm(errormsg,
4113 sizeof(errormsg),
4114 EXEC_ASYNC,
4115 args,
4116 NULL,
4117 &rcodes,
4118 shell);
4119 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004120}
4121
Guido van Rossumd48f2521997-12-05 22:19:34 +00004122static FILE *
4123popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004124{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004125 int oldfd, tgtfd;
4126 HFILE pipeh[2];
4127 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004128
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004129 /* mode determines which of stdin or stdout is reconnected to
4130 * the pipe to the child
4131 */
4132 if (strchr(mode, 'r') != NULL) {
4133 tgt_fd = 1; /* stdout */
4134 } else if (strchr(mode, 'w')) {
4135 tgt_fd = 0; /* stdin */
4136 } else {
4137 *err = ERROR_INVALID_ACCESS;
4138 return NULL;
4139 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004140
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00004141 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004142 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4143 *err = rc;
4144 return NULL;
4145 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004146
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004147 /* prevent other threads accessing stdio */
4148 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004149
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004150 /* reconnect stdio and execute child */
4151 oldfd = dup(tgtfd);
4152 close(tgtfd);
4153 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4154 DosClose(pipeh[tgtfd]);
4155 rc = async_system(command);
4156 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004157
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004158 /* restore stdio */
4159 dup2(oldfd, tgtfd);
4160 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004161
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004162 /* allow other threads access to stdio */
4163 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004164
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004165 /* if execution of child was successful return file stream */
4166 if (rc == NO_ERROR)
4167 return fdopen(pipeh[1 - tgtfd], mode);
4168 else {
4169 DosClose(pipeh[1 - tgtfd]);
4170 *err = rc;
4171 return NULL;
4172 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004173}
4174
4175static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004176posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004177{
4178 char *name;
4179 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00004180 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004181 FILE *fp;
4182 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004183 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004184 return NULL;
4185 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00004186 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004187 Py_END_ALLOW_THREADS
4188 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004189 return os2_error(err);
4190
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004191 f = PyFile_FromFile(fp, name, mode, fclose);
4192 if (f != NULL)
4193 PyFile_SetBufSize(f, bufsize);
4194 return f;
4195}
4196
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004197#elif defined(PYCC_GCC)
4198
4199/* standard posix version of popen() support */
4200static PyObject *
4201posix_popen(PyObject *self, PyObject *args)
4202{
4203 char *name;
4204 char *mode = "r";
4205 int bufsize = -1;
4206 FILE *fp;
4207 PyObject *f;
4208 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4209 return NULL;
4210 Py_BEGIN_ALLOW_THREADS
4211 fp = popen(name, mode);
4212 Py_END_ALLOW_THREADS
4213 if (fp == NULL)
4214 return posix_error();
4215 f = PyFile_FromFile(fp, name, mode, pclose);
4216 if (f != NULL)
4217 PyFile_SetBufSize(f, bufsize);
4218 return f;
4219}
4220
4221/* fork() under OS/2 has lots'o'warts
4222 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4223 * most of this code is a ripoff of the win32 code, but using the
4224 * capabilities of EMX's C library routines
4225 */
4226
4227/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4228#define POPEN_1 1
4229#define POPEN_2 2
4230#define POPEN_3 3
4231#define POPEN_4 4
4232
4233static PyObject *_PyPopen(char *, int, int, int);
4234static int _PyPclose(FILE *file);
4235
4236/*
4237 * Internal dictionary mapping popen* file pointers to process handles,
4238 * for use when retrieving the process exit code. See _PyPclose() below
4239 * for more information on this dictionary's use.
4240 */
4241static PyObject *_PyPopenProcs = NULL;
4242
4243/* os2emx version of popen2()
4244 *
4245 * The result of this function is a pipe (file) connected to the
4246 * process's stdin, and a pipe connected to the process's stdout.
4247 */
4248
4249static PyObject *
4250os2emx_popen2(PyObject *self, PyObject *args)
4251{
4252 PyObject *f;
4253 int tm=0;
4254
4255 char *cmdstring;
4256 char *mode = "t";
4257 int bufsize = -1;
4258 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4259 return NULL;
4260
4261 if (*mode == 't')
4262 tm = O_TEXT;
4263 else if (*mode != 'b') {
4264 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4265 return NULL;
4266 } else
4267 tm = O_BINARY;
4268
4269 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
4270
4271 return f;
4272}
4273
4274/*
4275 * Variation on os2emx.popen2
4276 *
4277 * The result of this function is 3 pipes - the process's stdin,
4278 * stdout and stderr
4279 */
4280
4281static PyObject *
4282os2emx_popen3(PyObject *self, PyObject *args)
4283{
4284 PyObject *f;
4285 int tm = 0;
4286
4287 char *cmdstring;
4288 char *mode = "t";
4289 int bufsize = -1;
4290 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4291 return NULL;
4292
4293 if (*mode == 't')
4294 tm = O_TEXT;
4295 else if (*mode != 'b') {
4296 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4297 return NULL;
4298 } else
4299 tm = O_BINARY;
4300
4301 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
4302
4303 return f;
4304}
4305
4306/*
4307 * Variation on os2emx.popen2
4308 *
Tim Peters11b23062003-04-23 02:39:17 +00004309 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004310 * and stdout+stderr combined as a single pipe.
4311 */
4312
4313static PyObject *
4314os2emx_popen4(PyObject *self, PyObject *args)
4315{
4316 PyObject *f;
4317 int tm = 0;
4318
4319 char *cmdstring;
4320 char *mode = "t";
4321 int bufsize = -1;
4322 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4323 return NULL;
4324
4325 if (*mode == 't')
4326 tm = O_TEXT;
4327 else if (*mode != 'b') {
4328 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4329 return NULL;
4330 } else
4331 tm = O_BINARY;
4332
4333 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
4334
4335 return f;
4336}
4337
4338/* a couple of structures for convenient handling of multiple
4339 * file handles and pipes
4340 */
4341struct file_ref
4342{
4343 int handle;
4344 int flags;
4345};
4346
4347struct pipe_ref
4348{
4349 int rd;
4350 int wr;
4351};
4352
4353/* The following code is derived from the win32 code */
4354
4355static PyObject *
4356_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4357{
4358 struct file_ref stdio[3];
4359 struct pipe_ref p_fd[3];
4360 FILE *p_s[3];
Christian Heimesd491d712008-02-01 18:49:26 +00004361 int file_count, i, pipe_err;
4362 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004363 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4364 PyObject *f, *p_f[3];
4365
4366 /* file modes for subsequent fdopen's on pipe handles */
4367 if (mode == O_TEXT)
4368 {
4369 rd_mode = "rt";
4370 wr_mode = "wt";
4371 }
4372 else
4373 {
4374 rd_mode = "rb";
4375 wr_mode = "wb";
4376 }
4377
4378 /* prepare shell references */
4379 if ((shell = getenv("EMXSHELL")) == NULL)
4380 if ((shell = getenv("COMSPEC")) == NULL)
4381 {
4382 errno = ENOENT;
4383 return posix_error();
4384 }
4385
4386 sh_name = _getname(shell);
4387 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4388 opt = "/c";
4389 else
4390 opt = "-c";
4391
4392 /* save current stdio fds + their flags, and set not inheritable */
4393 i = pipe_err = 0;
4394 while (pipe_err >= 0 && i < 3)
4395 {
4396 pipe_err = stdio[i].handle = dup(i);
4397 stdio[i].flags = fcntl(i, F_GETFD, 0);
4398 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4399 i++;
4400 }
4401 if (pipe_err < 0)
4402 {
4403 /* didn't get them all saved - clean up and bail out */
4404 int saved_err = errno;
4405 while (i-- > 0)
4406 {
4407 close(stdio[i].handle);
4408 }
4409 errno = saved_err;
4410 return posix_error();
4411 }
4412
4413 /* create pipe ends */
4414 file_count = 2;
4415 if (n == POPEN_3)
4416 file_count = 3;
4417 i = pipe_err = 0;
4418 while ((pipe_err == 0) && (i < file_count))
4419 pipe_err = pipe((int *)&p_fd[i++]);
4420 if (pipe_err < 0)
4421 {
4422 /* didn't get them all made - clean up and bail out */
4423 while (i-- > 0)
4424 {
4425 close(p_fd[i].wr);
4426 close(p_fd[i].rd);
4427 }
4428 errno = EPIPE;
4429 return posix_error();
4430 }
4431
4432 /* change the actual standard IO streams over temporarily,
4433 * making the retained pipe ends non-inheritable
4434 */
4435 pipe_err = 0;
4436
4437 /* - stdin */
4438 if (dup2(p_fd[0].rd, 0) == 0)
4439 {
4440 close(p_fd[0].rd);
4441 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4442 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4443 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4444 {
4445 close(p_fd[0].wr);
4446 pipe_err = -1;
4447 }
4448 }
4449 else
4450 {
4451 pipe_err = -1;
4452 }
4453
4454 /* - stdout */
4455 if (pipe_err == 0)
4456 {
4457 if (dup2(p_fd[1].wr, 1) == 1)
4458 {
4459 close(p_fd[1].wr);
4460 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4461 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4462 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4463 {
4464 close(p_fd[1].rd);
4465 pipe_err = -1;
4466 }
4467 }
4468 else
4469 {
4470 pipe_err = -1;
4471 }
4472 }
4473
4474 /* - stderr, as required */
4475 if (pipe_err == 0)
4476 switch (n)
4477 {
4478 case POPEN_3:
4479 {
4480 if (dup2(p_fd[2].wr, 2) == 2)
4481 {
4482 close(p_fd[2].wr);
4483 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4484 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4485 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4486 {
4487 close(p_fd[2].rd);
4488 pipe_err = -1;
4489 }
4490 }
4491 else
4492 {
4493 pipe_err = -1;
4494 }
4495 break;
4496 }
4497
4498 case POPEN_4:
4499 {
4500 if (dup2(1, 2) != 2)
4501 {
4502 pipe_err = -1;
4503 }
4504 break;
4505 }
4506 }
4507
4508 /* spawn the child process */
4509 if (pipe_err == 0)
4510 {
4511 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4512 if (pipe_pid == -1)
4513 {
4514 pipe_err = -1;
4515 }
4516 else
4517 {
4518 /* save the PID into the FILE structure
4519 * NOTE: this implementation doesn't actually
4520 * take advantage of this, but do it for
4521 * completeness - AIM Apr01
4522 */
4523 for (i = 0; i < file_count; i++)
4524 p_s[i]->_pid = pipe_pid;
4525 }
4526 }
4527
4528 /* reset standard IO to normal */
4529 for (i = 0; i < 3; i++)
4530 {
4531 dup2(stdio[i].handle, i);
4532 fcntl(i, F_SETFD, stdio[i].flags);
4533 close(stdio[i].handle);
4534 }
4535
4536 /* if any remnant problems, clean up and bail out */
4537 if (pipe_err < 0)
4538 {
4539 for (i = 0; i < 3; i++)
4540 {
4541 close(p_fd[i].rd);
4542 close(p_fd[i].wr);
4543 }
4544 errno = EPIPE;
4545 return posix_error_with_filename(cmdstring);
4546 }
4547
4548 /* build tuple of file objects to return */
4549 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4550 PyFile_SetBufSize(p_f[0], bufsize);
4551 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4552 PyFile_SetBufSize(p_f[1], bufsize);
4553 if (n == POPEN_3)
4554 {
4555 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4556 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004557 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004558 }
4559 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004560 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004561
4562 /*
4563 * Insert the files we've created into the process dictionary
4564 * all referencing the list with the process handle and the
4565 * initial number of files (see description below in _PyPclose).
4566 * Since if _PyPclose later tried to wait on a process when all
4567 * handles weren't closed, it could create a deadlock with the
4568 * child, we spend some energy here to try to ensure that we
4569 * either insert all file handles into the dictionary or none
4570 * at all. It's a little clumsy with the various popen modes
4571 * and variable number of files involved.
4572 */
4573 if (!_PyPopenProcs)
4574 {
4575 _PyPopenProcs = PyDict_New();
4576 }
4577
4578 if (_PyPopenProcs)
4579 {
4580 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4581 int ins_rc[3];
4582
4583 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4584 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4585
4586 procObj = PyList_New(2);
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00004587 pidObj = PyLong_FromPid(pipe_pid);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004588 intObj = PyInt_FromLong((long) file_count);
4589
4590 if (procObj && pidObj && intObj)
4591 {
4592 PyList_SetItem(procObj, 0, pidObj);
4593 PyList_SetItem(procObj, 1, intObj);
4594
4595 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4596 if (fileObj[0])
4597 {
4598 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4599 fileObj[0],
4600 procObj);
4601 }
4602 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4603 if (fileObj[1])
4604 {
4605 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4606 fileObj[1],
4607 procObj);
4608 }
4609 if (file_count >= 3)
4610 {
4611 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4612 if (fileObj[2])
4613 {
4614 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4615 fileObj[2],
4616 procObj);
4617 }
4618 }
4619
4620 if (ins_rc[0] < 0 || !fileObj[0] ||
4621 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4622 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4623 {
4624 /* Something failed - remove any dictionary
4625 * entries that did make it.
4626 */
4627 if (!ins_rc[0] && fileObj[0])
4628 {
4629 PyDict_DelItem(_PyPopenProcs,
4630 fileObj[0]);
4631 }
4632 if (!ins_rc[1] && fileObj[1])
4633 {
4634 PyDict_DelItem(_PyPopenProcs,
4635 fileObj[1]);
4636 }
4637 if (!ins_rc[2] && fileObj[2])
4638 {
4639 PyDict_DelItem(_PyPopenProcs,
4640 fileObj[2]);
4641 }
4642 }
4643 }
Tim Peters11b23062003-04-23 02:39:17 +00004644
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004645 /*
4646 * Clean up our localized references for the dictionary keys
4647 * and value since PyDict_SetItem will Py_INCREF any copies
4648 * that got placed in the dictionary.
4649 */
4650 Py_XDECREF(procObj);
4651 Py_XDECREF(fileObj[0]);
4652 Py_XDECREF(fileObj[1]);
4653 Py_XDECREF(fileObj[2]);
4654 }
4655
4656 /* Child is launched. */
4657 return f;
4658}
4659
4660/*
4661 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4662 * exit code for the child process and return as a result of the close.
4663 *
4664 * This function uses the _PyPopenProcs dictionary in order to map the
4665 * input file pointer to information about the process that was
4666 * originally created by the popen* call that created the file pointer.
4667 * The dictionary uses the file pointer as a key (with one entry
4668 * inserted for each file returned by the original popen* call) and a
4669 * single list object as the value for all files from a single call.
4670 * The list object contains the Win32 process handle at [0], and a file
4671 * count at [1], which is initialized to the total number of file
4672 * handles using that list.
4673 *
4674 * This function closes whichever handle it is passed, and decrements
4675 * the file count in the dictionary for the process handle pointed to
4676 * by this file. On the last close (when the file count reaches zero),
4677 * this function will wait for the child process and then return its
4678 * exit code as the result of the close() operation. This permits the
4679 * files to be closed in any order - it is always the close() of the
4680 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004681 *
4682 * NOTE: This function is currently called with the GIL released.
4683 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004684 */
4685
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004686static int _PyPclose(FILE *file)
4687{
4688 int result;
4689 int exit_code;
Christian Heimesd491d712008-02-01 18:49:26 +00004690 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004691 PyObject *procObj, *pidObj, *intObj, *fileObj;
4692 int file_count;
4693#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004694 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004695#endif
4696
4697 /* Close the file handle first, to ensure it can't block the
4698 * child from exiting if it's the last handle.
4699 */
4700 result = fclose(file);
4701
4702#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004703 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004704#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004705 if (_PyPopenProcs)
4706 {
4707 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4708 (procObj = PyDict_GetItem(_PyPopenProcs,
4709 fileObj)) != NULL &&
4710 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4711 (intObj = PyList_GetItem(procObj,1)) != NULL)
4712 {
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00004713 pipe_pid = (pid_t) PyLong_AsPid(pidObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004714 file_count = (int) PyInt_AsLong(intObj);
4715
4716 if (file_count > 1)
4717 {
4718 /* Still other files referencing process */
4719 file_count--;
4720 PyList_SetItem(procObj,1,
4721 PyInt_FromLong((long) file_count));
4722 }
4723 else
4724 {
4725 /* Last file for this process */
4726 if (result != EOF &&
4727 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4728 {
4729 /* extract exit status */
4730 if (WIFEXITED(exit_code))
4731 {
4732 result = WEXITSTATUS(exit_code);
4733 }
4734 else
4735 {
4736 errno = EPIPE;
4737 result = -1;
4738 }
4739 }
4740 else
4741 {
4742 /* Indicate failure - this will cause the file object
4743 * to raise an I/O error and translate the last
4744 * error code from errno. We do have a problem with
4745 * last errors that overlap the normal errno table,
4746 * but that's a consistent problem with the file object.
4747 */
4748 result = -1;
4749 }
4750 }
4751
4752 /* Remove this file pointer from dictionary */
4753 PyDict_DelItem(_PyPopenProcs, fileObj);
4754
4755 if (PyDict_Size(_PyPopenProcs) == 0)
4756 {
4757 Py_DECREF(_PyPopenProcs);
4758 _PyPopenProcs = NULL;
4759 }
4760
4761 } /* if object retrieval ok */
4762
4763 Py_XDECREF(fileObj);
4764 } /* if _PyPopenProcs */
4765
4766#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004767 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004768#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004769 return result;
4770}
4771
4772#endif /* PYCC_??? */
4773
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004774#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004775
4776/*
4777 * Portable 'popen' replacement for Win32.
4778 *
4779 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4780 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004781 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004782 */
4783
4784#include <malloc.h>
4785#include <io.h>
4786#include <fcntl.h>
4787
4788/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4789#define POPEN_1 1
4790#define POPEN_2 2
4791#define POPEN_3 3
4792#define POPEN_4 4
4793
4794static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004795static int _PyPclose(FILE *file);
4796
4797/*
4798 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004799 * for use when retrieving the process exit code. See _PyPclose() below
4800 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004801 */
4802static PyObject *_PyPopenProcs = NULL;
4803
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004804
4805/* popen that works from a GUI.
4806 *
4807 * The result of this function is a pipe (file) connected to the
4808 * processes stdin or stdout, depending on the requested mode.
4809 */
4810
4811static PyObject *
4812posix_popen(PyObject *self, PyObject *args)
4813{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004814 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004815 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004816
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004817 char *cmdstring;
4818 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004819 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004820 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004821 return NULL;
4822
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004823 if (*mode == 'r')
4824 tm = _O_RDONLY;
4825 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004826 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004827 return NULL;
4828 } else
4829 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004830
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004831 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004832 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004833 return NULL;
4834 }
4835
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004836 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004837 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004838 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004839 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004840 else
4841 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4842
4843 return f;
4844}
4845
4846/* Variation on win32pipe.popen
4847 *
4848 * The result of this function is a pipe (file) connected to the
4849 * process's stdin, and a pipe connected to the process's stdout.
4850 */
4851
4852static PyObject *
4853win32_popen2(PyObject *self, PyObject *args)
4854{
4855 PyObject *f;
4856 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004857
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004858 char *cmdstring;
4859 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004860 int bufsize = -1;
4861 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004862 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004863
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004864 if (*mode == 't')
4865 tm = _O_TEXT;
4866 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004867 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004868 return NULL;
4869 } else
4870 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004871
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004872 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004873 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004874 return NULL;
4875 }
4876
4877 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004878
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004879 return f;
4880}
4881
4882/*
4883 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004884 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004885 * The result of this function is 3 pipes - the process's stdin,
4886 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004887 */
4888
4889static PyObject *
4890win32_popen3(PyObject *self, PyObject *args)
4891{
4892 PyObject *f;
4893 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004894
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004895 char *cmdstring;
4896 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004897 int bufsize = -1;
4898 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004899 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004900
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004901 if (*mode == 't')
4902 tm = _O_TEXT;
4903 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004904 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004905 return NULL;
4906 } else
4907 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004908
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004909 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004910 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004911 return NULL;
4912 }
4913
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004914 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004915
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004916 return f;
4917}
4918
4919/*
4920 * Variation on win32pipe.popen
4921 *
Tim Peters5aa91602002-01-30 05:46:57 +00004922 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004923 * and stdout+stderr combined as a single pipe.
4924 */
4925
4926static PyObject *
4927win32_popen4(PyObject *self, PyObject *args)
4928{
4929 PyObject *f;
4930 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004931
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004932 char *cmdstring;
4933 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004934 int bufsize = -1;
4935 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004936 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004937
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004938 if (*mode == 't')
4939 tm = _O_TEXT;
4940 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004941 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004942 return NULL;
4943 } else
4944 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004945
4946 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004947 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004948 return NULL;
4949 }
4950
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004951 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004952
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004953 return f;
4954}
4955
Mark Hammond08501372001-01-31 07:30:29 +00004956static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004957_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004958 HANDLE hStdin,
4959 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004960 HANDLE hStderr,
4961 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004962{
4963 PROCESS_INFORMATION piProcInfo;
4964 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004965 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004966 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004967 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004968 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004969 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004970
4971 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004972 char *comshell;
4973
Tim Peters92e4dd82002-10-05 01:47:34 +00004974 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004975 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004976 /* x < i, so x fits into an integer */
4977 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004978
4979 /* Explicitly check if we are using COMMAND.COM. If we are
4980 * then use the w9xpopen hack.
4981 */
4982 comshell = s1 + x;
4983 while (comshell >= s1 && *comshell != '\\')
4984 --comshell;
4985 ++comshell;
4986
4987 if (GetVersion() < 0x80000000 &&
4988 _stricmp(comshell, "command.com") != 0) {
4989 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004990 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004991 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004992 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004993 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004994 }
4995 else {
4996 /*
Tim Peters402d5982001-08-27 06:37:48 +00004997 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4998 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004999 */
Mark Hammond08501372001-01-31 07:30:29 +00005000 char modulepath[_MAX_PATH];
5001 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005002 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Martin v. Löwis26fd9602006-04-22 11:15:41 +00005003 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005004 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005005 x = i+1;
5006 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00005007 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00005008 strncat(modulepath,
5009 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00005010 (sizeof(modulepath)/sizeof(modulepath[0]))
5011 -strlen(modulepath));
5012 if (stat(modulepath, &statinfo) != 0) {
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00005013 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
Tim Peters5aa91602002-01-30 05:46:57 +00005014 /* Eeek - file-not-found - possibly an embedding
5015 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00005016 */
Tim Peters5aa91602002-01-30 05:46:57 +00005017 strncpy(modulepath,
5018 Py_GetExecPrefix(),
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00005019 mplen);
5020 modulepath[mplen-1] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00005021 if (modulepath[strlen(modulepath)-1] != '\\')
5022 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00005023 strncat(modulepath,
5024 szConsoleSpawn,
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00005025 mplen-strlen(modulepath));
Mark Hammond08501372001-01-31 07:30:29 +00005026 /* No where else to look - raise an easily identifiable
5027 error, rather than leaving Windows to report
5028 "file not found" - as the user is probably blissfully
5029 unaware this shim EXE is used, and it will confuse them.
5030 (well, it confused me for a while ;-)
5031 */
5032 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00005033 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00005034 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00005035 "for popen to work with your shell "
5036 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00005037 szConsoleSpawn);
5038 return FALSE;
5039 }
5040 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005041 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00005042 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005043 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00005044
Tim Peters92e4dd82002-10-05 01:47:34 +00005045 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005046 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00005047 /* To maintain correct argument passing semantics,
5048 we pass the command-line as it stands, and allow
5049 quoting to be applied. w9xpopen.exe will then
5050 use its argv vector, and re-quote the necessary
5051 args for the ultimate child process.
5052 */
Tim Peters75cdad52001-11-28 22:07:30 +00005053 PyOS_snprintf(
5054 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00005055 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005056 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005057 s1,
5058 s3,
5059 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005060 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00005061 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005062 dialog:
5063 "Your program accessed mem currently in use at xxx"
5064 and a hopeful warning about the stability of your
5065 system.
Mark Dickinson3e4caeb2009-02-21 20:27:01 +00005066 Cost is Ctrl+C won't kill children, but anyone
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005067 who cares can have a go!
5068 */
5069 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005070 }
5071 }
5072
5073 /* Could be an else here to try cmd.exe / command.com in the path
5074 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00005075 else {
Tim Peters402d5982001-08-27 06:37:48 +00005076 PyErr_SetString(PyExc_RuntimeError,
5077 "Cannot locate a COMSPEC environment variable to "
5078 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00005079 return FALSE;
5080 }
Tim Peters5aa91602002-01-30 05:46:57 +00005081
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005082 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5083 siStartInfo.cb = sizeof(STARTUPINFO);
5084 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5085 siStartInfo.hStdInput = hStdin;
5086 siStartInfo.hStdOutput = hStdout;
5087 siStartInfo.hStdError = hStderr;
5088 siStartInfo.wShowWindow = SW_HIDE;
5089
5090 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005091 s2,
5092 NULL,
5093 NULL,
5094 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005095 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005096 NULL,
5097 NULL,
5098 &siStartInfo,
5099 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005100 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005101 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005102
Mark Hammondb37a3732000-08-14 04:47:33 +00005103 /* Return process handle */
5104 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005105 return TRUE;
5106 }
Tim Peters402d5982001-08-27 06:37:48 +00005107 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005108 return FALSE;
5109}
5110
5111/* The following code is based off of KB: Q190351 */
5112
5113static PyObject *
5114_PyPopen(char *cmdstring, int mode, int n)
5115{
5116 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5117 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00005118 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005119
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005120 SECURITY_ATTRIBUTES saAttr;
5121 BOOL fSuccess;
5122 int fd1, fd2, fd3;
5123 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00005124 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005125 PyObject *f;
5126
5127 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5128 saAttr.bInheritHandle = TRUE;
5129 saAttr.lpSecurityDescriptor = NULL;
5130
5131 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5132 return win32_error("CreatePipe", NULL);
5133
5134 /* Create new output read handle and the input write handle. Set
5135 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005136 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005137 * being created. */
5138 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005139 GetCurrentProcess(), &hChildStdinWrDup, 0,
5140 FALSE,
5141 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005142 if (!fSuccess)
5143 return win32_error("DuplicateHandle", NULL);
5144
5145 /* Close the inheritable version of ChildStdin
5146 that we're using. */
5147 CloseHandle(hChildStdinWr);
5148
5149 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5150 return win32_error("CreatePipe", NULL);
5151
5152 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005153 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5154 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005155 if (!fSuccess)
5156 return win32_error("DuplicateHandle", NULL);
5157
5158 /* Close the inheritable version of ChildStdout
5159 that we're using. */
5160 CloseHandle(hChildStdoutRd);
5161
5162 if (n != POPEN_4) {
5163 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5164 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005165 fSuccess = DuplicateHandle(GetCurrentProcess(),
5166 hChildStderrRd,
5167 GetCurrentProcess(),
5168 &hChildStderrRdDup, 0,
5169 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005170 if (!fSuccess)
5171 return win32_error("DuplicateHandle", NULL);
5172 /* Close the inheritable version of ChildStdErr that we're using. */
5173 CloseHandle(hChildStderrRd);
5174 }
Tim Peters5aa91602002-01-30 05:46:57 +00005175
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005176 switch (n) {
5177 case POPEN_1:
5178 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5179 case _O_WRONLY | _O_TEXT:
5180 /* Case for writing to child Stdin in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005181 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005182 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005183 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005184 PyFile_SetBufSize(f, 0);
5185 /* We don't care about these pipes anymore, so close them. */
5186 CloseHandle(hChildStdoutRdDup);
5187 CloseHandle(hChildStderrRdDup);
5188 break;
5189
5190 case _O_RDONLY | _O_TEXT:
5191 /* Case for reading from child Stdout in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005192 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005193 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005194 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005195 PyFile_SetBufSize(f, 0);
5196 /* We don't care about these pipes anymore, so close them. */
5197 CloseHandle(hChildStdinWrDup);
5198 CloseHandle(hChildStderrRdDup);
5199 break;
5200
5201 case _O_RDONLY | _O_BINARY:
5202 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005203 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005204 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005205 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005206 PyFile_SetBufSize(f, 0);
5207 /* We don't care about these pipes anymore, so close them. */
5208 CloseHandle(hChildStdinWrDup);
5209 CloseHandle(hChildStderrRdDup);
5210 break;
5211
5212 case _O_WRONLY | _O_BINARY:
5213 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005214 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005215 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005216 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005217 PyFile_SetBufSize(f, 0);
5218 /* We don't care about these pipes anymore, so close them. */
5219 CloseHandle(hChildStdoutRdDup);
5220 CloseHandle(hChildStderrRdDup);
5221 break;
5222 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005223 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005224 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005225
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005226 case POPEN_2:
5227 case POPEN_4:
5228 {
5229 char *m1, *m2;
5230 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005231
Tim Peters7dca21e2002-08-19 00:42:29 +00005232 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005233 m1 = "r";
5234 m2 = "w";
5235 } else {
5236 m1 = "rb";
5237 m2 = "wb";
5238 }
5239
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, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005242 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005243 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005244 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005245 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00005246 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005247 PyFile_SetBufSize(p2, 0);
5248
5249 if (n != 4)
5250 CloseHandle(hChildStderrRdDup);
5251
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005252 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00005253 Py_XDECREF(p1);
5254 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00005255 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005256 break;
5257 }
Tim Peters5aa91602002-01-30 05:46:57 +00005258
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005259 case POPEN_3:
5260 {
5261 char *m1, *m2;
5262 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005263
Tim Peters7dca21e2002-08-19 00:42:29 +00005264 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005265 m1 = "r";
5266 m2 = "w";
5267 } else {
5268 m1 = "rb";
5269 m2 = "wb";
5270 }
5271
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005272 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005273 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005274 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005275 f2 = _fdopen(fd2, m1);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005276 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005277 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005278 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00005279 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5280 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005281 PyFile_SetBufSize(p1, 0);
5282 PyFile_SetBufSize(p2, 0);
5283 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005284 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00005285 Py_XDECREF(p1);
5286 Py_XDECREF(p2);
5287 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00005288 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005289 break;
5290 }
5291 }
5292
5293 if (n == POPEN_4) {
5294 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005295 hChildStdinRd,
5296 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005297 hChildStdoutWr,
5298 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005299 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005300 }
5301 else {
5302 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005303 hChildStdinRd,
5304 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005305 hChildStderrWr,
5306 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005307 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005308 }
5309
Mark Hammondb37a3732000-08-14 04:47:33 +00005310 /*
5311 * Insert the files we've created into the process dictionary
5312 * all referencing the list with the process handle and the
5313 * initial number of files (see description below in _PyPclose).
5314 * Since if _PyPclose later tried to wait on a process when all
5315 * handles weren't closed, it could create a deadlock with the
5316 * child, we spend some energy here to try to ensure that we
5317 * either insert all file handles into the dictionary or none
5318 * at all. It's a little clumsy with the various popen modes
5319 * and variable number of files involved.
5320 */
5321 if (!_PyPopenProcs) {
5322 _PyPopenProcs = PyDict_New();
5323 }
5324
5325 if (_PyPopenProcs) {
5326 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5327 int ins_rc[3];
5328
5329 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5330 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
5331
5332 procObj = PyList_New(2);
5333 hProcessObj = PyLong_FromVoidPtr(hProcess);
5334 intObj = PyInt_FromLong(file_count);
5335
5336 if (procObj && hProcessObj && intObj) {
5337 PyList_SetItem(procObj,0,hProcessObj);
5338 PyList_SetItem(procObj,1,intObj);
5339
5340 fileObj[0] = PyLong_FromVoidPtr(f1);
5341 if (fileObj[0]) {
5342 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5343 fileObj[0],
5344 procObj);
5345 }
5346 if (file_count >= 2) {
5347 fileObj[1] = PyLong_FromVoidPtr(f2);
5348 if (fileObj[1]) {
5349 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5350 fileObj[1],
5351 procObj);
5352 }
5353 }
5354 if (file_count >= 3) {
5355 fileObj[2] = PyLong_FromVoidPtr(f3);
5356 if (fileObj[2]) {
5357 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5358 fileObj[2],
5359 procObj);
5360 }
5361 }
5362
5363 if (ins_rc[0] < 0 || !fileObj[0] ||
5364 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5365 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5366 /* Something failed - remove any dictionary
5367 * entries that did make it.
5368 */
5369 if (!ins_rc[0] && fileObj[0]) {
5370 PyDict_DelItem(_PyPopenProcs,
5371 fileObj[0]);
5372 }
5373 if (!ins_rc[1] && fileObj[1]) {
5374 PyDict_DelItem(_PyPopenProcs,
5375 fileObj[1]);
5376 }
5377 if (!ins_rc[2] && fileObj[2]) {
5378 PyDict_DelItem(_PyPopenProcs,
5379 fileObj[2]);
5380 }
5381 }
5382 }
Tim Peters5aa91602002-01-30 05:46:57 +00005383
Mark Hammondb37a3732000-08-14 04:47:33 +00005384 /*
5385 * Clean up our localized references for the dictionary keys
5386 * and value since PyDict_SetItem will Py_INCREF any copies
5387 * that got placed in the dictionary.
5388 */
5389 Py_XDECREF(procObj);
5390 Py_XDECREF(fileObj[0]);
5391 Py_XDECREF(fileObj[1]);
5392 Py_XDECREF(fileObj[2]);
5393 }
5394
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005395 /* Child is launched. Close the parents copy of those pipe
5396 * handles that only the child should have open. You need to
5397 * make sure that no handles to the write end of the output pipe
5398 * are maintained in this process or else the pipe will not close
5399 * when the child process exits and the ReadFile will hang. */
5400
5401 if (!CloseHandle(hChildStdinRd))
5402 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005403
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005404 if (!CloseHandle(hChildStdoutWr))
5405 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005406
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005407 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5408 return win32_error("CloseHandle", NULL);
5409
5410 return f;
5411}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005412
5413/*
5414 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5415 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005416 *
5417 * This function uses the _PyPopenProcs dictionary in order to map the
5418 * input file pointer to information about the process that was
5419 * originally created by the popen* call that created the file pointer.
5420 * The dictionary uses the file pointer as a key (with one entry
5421 * inserted for each file returned by the original popen* call) and a
5422 * single list object as the value for all files from a single call.
5423 * The list object contains the Win32 process handle at [0], and a file
5424 * count at [1], which is initialized to the total number of file
5425 * handles using that list.
5426 *
5427 * This function closes whichever handle it is passed, and decrements
5428 * the file count in the dictionary for the process handle pointed to
5429 * by this file. On the last close (when the file count reaches zero),
5430 * this function will wait for the child process and then return its
5431 * exit code as the result of the close() operation. This permits the
5432 * files to be closed in any order - it is always the close() of the
5433 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005434 *
5435 * NOTE: This function is currently called with the GIL released.
5436 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005437 */
Tim Peters736aa322000-09-01 06:51:24 +00005438
Fredrik Lundh56055a42000-07-23 19:47:12 +00005439static int _PyPclose(FILE *file)
5440{
Fredrik Lundh20318932000-07-26 17:29:12 +00005441 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005442 DWORD exit_code;
5443 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00005444 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5445 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005446#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005447 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005448#endif
5449
Fredrik Lundh20318932000-07-26 17:29:12 +00005450 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00005451 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00005452 */
5453 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005454#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005455 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005456#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005457 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005458 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5459 (procObj = PyDict_GetItem(_PyPopenProcs,
5460 fileObj)) != NULL &&
5461 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5462 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5463
5464 hProcess = PyLong_AsVoidPtr(hProcessObj);
5465 file_count = PyInt_AsLong(intObj);
5466
5467 if (file_count > 1) {
5468 /* Still other files referencing process */
5469 file_count--;
5470 PyList_SetItem(procObj,1,
5471 PyInt_FromLong(file_count));
5472 } else {
5473 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00005474 if (result != EOF &&
5475 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5476 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00005477 /* Possible truncation here in 16-bit environments, but
5478 * real exit codes are just the lower byte in any event.
5479 */
5480 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005481 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00005482 /* Indicate failure - this will cause the file object
5483 * to raise an I/O error and translate the last Win32
5484 * error code from errno. We do have a problem with
5485 * last errors that overlap the normal errno table,
5486 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005487 */
Fredrik Lundh20318932000-07-26 17:29:12 +00005488 if (result != EOF) {
5489 /* If the error wasn't from the fclose(), then
5490 * set errno for the file object error handling.
5491 */
5492 errno = GetLastError();
5493 }
5494 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005495 }
5496
5497 /* Free up the native handle at this point */
5498 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00005499 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005500
Mark Hammondb37a3732000-08-14 04:47:33 +00005501 /* Remove this file pointer from dictionary */
5502 PyDict_DelItem(_PyPopenProcs, fileObj);
5503
5504 if (PyDict_Size(_PyPopenProcs) == 0) {
5505 Py_DECREF(_PyPopenProcs);
5506 _PyPopenProcs = NULL;
5507 }
5508
5509 } /* if object retrieval ok */
5510
5511 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005512 } /* if _PyPopenProcs */
5513
Tim Peters736aa322000-09-01 06:51:24 +00005514#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005515 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005516#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005517 return result;
5518}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005519
5520#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005521static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005522posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005523{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005524 char *name;
5525 char *mode = "r";
5526 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00005527 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005528 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005529 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00005530 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00005531 /* Strip mode of binary or text modifiers */
5532 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5533 mode = "r";
5534 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5535 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00005536 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005537 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005538 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00005539 if (fp == NULL)
5540 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005541 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005542 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005543 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005544 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005545}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005546
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005547#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005548#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005549
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005550
Guido van Rossumb6775db1994-08-01 11:34:53 +00005551#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005552PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005553"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005554Set the current process's user id.");
5555
Barry Warsaw53699e91996-12-10 23:23:01 +00005556static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005557posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005558{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005559 long uid_arg;
5560 uid_t uid;
5561 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005562 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005563 uid = uid_arg;
5564 if (uid != uid_arg) {
5565 PyErr_SetString(PyExc_OverflowError, "user id too big");
5566 return NULL;
5567 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005568 if (setuid(uid) < 0)
5569 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005570 Py_INCREF(Py_None);
5571 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005572}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005573#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005574
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005575
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005576#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005577PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005578"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005579Set the current process's effective user id.");
5580
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005581static PyObject *
5582posix_seteuid (PyObject *self, PyObject *args)
5583{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005584 long euid_arg;
5585 uid_t euid;
5586 if (!PyArg_ParseTuple(args, "l", &euid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005587 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005588 euid = euid_arg;
5589 if (euid != euid_arg) {
5590 PyErr_SetString(PyExc_OverflowError, "user id too big");
5591 return NULL;
5592 }
5593 if (seteuid(euid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005594 return posix_error();
5595 } else {
5596 Py_INCREF(Py_None);
5597 return Py_None;
5598 }
5599}
5600#endif /* HAVE_SETEUID */
5601
5602#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005603PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005604"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005605Set the current process's effective group id.");
5606
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005607static PyObject *
5608posix_setegid (PyObject *self, PyObject *args)
5609{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005610 long egid_arg;
5611 gid_t egid;
5612 if (!PyArg_ParseTuple(args, "l", &egid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005613 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005614 egid = egid_arg;
5615 if (egid != egid_arg) {
5616 PyErr_SetString(PyExc_OverflowError, "group id too big");
5617 return NULL;
5618 }
5619 if (setegid(egid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005620 return posix_error();
5621 } else {
5622 Py_INCREF(Py_None);
5623 return Py_None;
5624 }
5625}
5626#endif /* HAVE_SETEGID */
5627
5628#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005629PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005630"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005631Set the current process's real and effective user ids.");
5632
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005633static PyObject *
5634posix_setreuid (PyObject *self, PyObject *args)
5635{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005636 long ruid_arg, euid_arg;
5637 uid_t ruid, euid;
5638 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005639 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005640 ruid = ruid_arg;
5641 euid = euid_arg;
5642 if (euid != euid_arg || ruid != ruid_arg) {
5643 PyErr_SetString(PyExc_OverflowError, "user id too big");
5644 return NULL;
5645 }
5646 if (setreuid(ruid, euid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005647 return posix_error();
5648 } else {
5649 Py_INCREF(Py_None);
5650 return Py_None;
5651 }
5652}
5653#endif /* HAVE_SETREUID */
5654
5655#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005656PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005657"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005658Set the current process's real and effective group ids.");
5659
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005660static PyObject *
5661posix_setregid (PyObject *self, PyObject *args)
5662{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005663 long rgid_arg, egid_arg;
5664 gid_t rgid, egid;
5665 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005666 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005667 rgid = rgid_arg;
5668 egid = egid_arg;
5669 if (egid != egid_arg || rgid != rgid_arg) {
5670 PyErr_SetString(PyExc_OverflowError, "group id too big");
5671 return NULL;
5672 }
5673 if (setregid(rgid, egid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005674 return posix_error();
5675 } else {
5676 Py_INCREF(Py_None);
5677 return Py_None;
5678 }
5679}
5680#endif /* HAVE_SETREGID */
5681
Guido van Rossumb6775db1994-08-01 11:34:53 +00005682#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005683PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005684"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005685Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005686
Barry Warsaw53699e91996-12-10 23:23:01 +00005687static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005688posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005689{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005690 long gid_arg;
5691 gid_t gid;
5692 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005693 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005694 gid = gid_arg;
5695 if (gid != gid_arg) {
5696 PyErr_SetString(PyExc_OverflowError, "group id too big");
5697 return NULL;
5698 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005699 if (setgid(gid) < 0)
5700 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005701 Py_INCREF(Py_None);
5702 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005703}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005704#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005705
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005706#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005707PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005708"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005709Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005710
5711static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005712posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005713{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005714 int i, len;
5715 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005716
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005717 if (!PySequence_Check(groups)) {
5718 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5719 return NULL;
5720 }
5721 len = PySequence_Size(groups);
5722 if (len > MAX_GROUPS) {
5723 PyErr_SetString(PyExc_ValueError, "too many groups");
5724 return NULL;
5725 }
5726 for(i = 0; i < len; i++) {
5727 PyObject *elem;
5728 elem = PySequence_GetItem(groups, i);
5729 if (!elem)
5730 return NULL;
5731 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005732 if (!PyLong_Check(elem)) {
5733 PyErr_SetString(PyExc_TypeError,
5734 "groups must be integers");
5735 Py_DECREF(elem);
5736 return NULL;
5737 } else {
5738 unsigned long x = PyLong_AsUnsignedLong(elem);
5739 if (PyErr_Occurred()) {
5740 PyErr_SetString(PyExc_TypeError,
5741 "group id too big");
5742 Py_DECREF(elem);
5743 return NULL;
5744 }
5745 grouplist[i] = x;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005746 /* read back to see if it fits in gid_t */
Georg Brandla13c2442005-11-22 19:30:31 +00005747 if (grouplist[i] != x) {
5748 PyErr_SetString(PyExc_TypeError,
5749 "group id too big");
5750 Py_DECREF(elem);
5751 return NULL;
5752 }
5753 }
5754 } else {
5755 long x = PyInt_AsLong(elem);
5756 grouplist[i] = x;
5757 if (grouplist[i] != x) {
5758 PyErr_SetString(PyExc_TypeError,
5759 "group id too big");
5760 Py_DECREF(elem);
5761 return NULL;
5762 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005763 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005764 Py_DECREF(elem);
5765 }
5766
5767 if (setgroups(len, grouplist) < 0)
5768 return posix_error();
5769 Py_INCREF(Py_None);
5770 return Py_None;
5771}
5772#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005773
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005774#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005775static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00005776wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00005777{
5778 PyObject *result;
5779 static PyObject *struct_rusage;
5780
5781 if (pid == -1)
5782 return posix_error();
5783
5784 if (struct_rusage == NULL) {
Christian Heimes000a0742008-01-03 22:16:32 +00005785 PyObject *m = PyImport_ImportModuleNoBlock("resource");
Neal Norwitz05a45592006-03-20 06:30:08 +00005786 if (m == NULL)
5787 return NULL;
5788 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5789 Py_DECREF(m);
5790 if (struct_rusage == NULL)
5791 return NULL;
5792 }
5793
5794 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5795 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5796 if (!result)
5797 return NULL;
5798
5799#ifndef doubletime
5800#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5801#endif
5802
5803 PyStructSequence_SET_ITEM(result, 0,
5804 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5805 PyStructSequence_SET_ITEM(result, 1,
5806 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5807#define SET_INT(result, index, value)\
5808 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5809 SET_INT(result, 2, ru->ru_maxrss);
5810 SET_INT(result, 3, ru->ru_ixrss);
5811 SET_INT(result, 4, ru->ru_idrss);
5812 SET_INT(result, 5, ru->ru_isrss);
5813 SET_INT(result, 6, ru->ru_minflt);
5814 SET_INT(result, 7, ru->ru_majflt);
5815 SET_INT(result, 8, ru->ru_nswap);
5816 SET_INT(result, 9, ru->ru_inblock);
5817 SET_INT(result, 10, ru->ru_oublock);
5818 SET_INT(result, 11, ru->ru_msgsnd);
5819 SET_INT(result, 12, ru->ru_msgrcv);
5820 SET_INT(result, 13, ru->ru_nsignals);
5821 SET_INT(result, 14, ru->ru_nvcsw);
5822 SET_INT(result, 15, ru->ru_nivcsw);
5823#undef SET_INT
5824
5825 if (PyErr_Occurred()) {
5826 Py_DECREF(result);
5827 return NULL;
5828 }
5829
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005830 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005831}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005832#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005833
5834#ifdef HAVE_WAIT3
5835PyDoc_STRVAR(posix_wait3__doc__,
5836"wait3(options) -> (pid, status, rusage)\n\n\
5837Wait for completion of a child process.");
5838
5839static PyObject *
5840posix_wait3(PyObject *self, PyObject *args)
5841{
Christian Heimesd491d712008-02-01 18:49:26 +00005842 pid_t pid;
5843 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005844 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005845 WAIT_TYPE status;
5846 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005847
5848 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5849 return NULL;
5850
5851 Py_BEGIN_ALLOW_THREADS
5852 pid = wait3(&status, options, &ru);
5853 Py_END_ALLOW_THREADS
5854
Neal Norwitzd5a37542006-03-20 06:48:34 +00005855 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005856}
5857#endif /* HAVE_WAIT3 */
5858
5859#ifdef HAVE_WAIT4
5860PyDoc_STRVAR(posix_wait4__doc__,
5861"wait4(pid, options) -> (pid, status, rusage)\n\n\
5862Wait for completion of a given child process.");
5863
5864static PyObject *
5865posix_wait4(PyObject *self, PyObject *args)
5866{
Christian Heimesd491d712008-02-01 18:49:26 +00005867 pid_t pid;
5868 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005869 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005870 WAIT_TYPE status;
5871 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005872
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005873 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
Neal Norwitz05a45592006-03-20 06:30:08 +00005874 return NULL;
5875
5876 Py_BEGIN_ALLOW_THREADS
5877 pid = wait4(pid, &status, options, &ru);
5878 Py_END_ALLOW_THREADS
5879
Neal Norwitzd5a37542006-03-20 06:48:34 +00005880 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005881}
5882#endif /* HAVE_WAIT4 */
5883
Guido van Rossumb6775db1994-08-01 11:34:53 +00005884#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005885PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005886"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005887Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005888
Barry Warsaw53699e91996-12-10 23:23:01 +00005889static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005890posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005891{
Christian Heimesd491d712008-02-01 18:49:26 +00005892 pid_t pid;
5893 int options;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005894 WAIT_TYPE status;
5895 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005896
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005897 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005898 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005899 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005900 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005901 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005902 if (pid == -1)
5903 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005904
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005905 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005906}
5907
Tim Petersab034fa2002-02-01 11:27:43 +00005908#elif defined(HAVE_CWAIT)
5909
5910/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005911PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005912"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005913"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005914
5915static PyObject *
5916posix_waitpid(PyObject *self, PyObject *args)
5917{
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005918 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005919 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005920
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005921 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
Tim Petersab034fa2002-02-01 11:27:43 +00005922 return NULL;
5923 Py_BEGIN_ALLOW_THREADS
5924 pid = _cwait(&status, pid, options);
5925 Py_END_ALLOW_THREADS
5926 if (pid == -1)
5927 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005928
5929 /* shift the status left a byte so this is more like the POSIX waitpid */
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005930 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005931}
5932#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005933
Guido van Rossumad0ee831995-03-01 10:34:45 +00005934#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005935PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005936"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005937Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005938
Barry Warsaw53699e91996-12-10 23:23:01 +00005939static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005940posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005941{
Christian Heimesd491d712008-02-01 18:49:26 +00005942 pid_t pid;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005943 WAIT_TYPE status;
5944 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005945
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005946 Py_BEGIN_ALLOW_THREADS
5947 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005948 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005949 if (pid == -1)
5950 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005951
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005952 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005953}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005954#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005955
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005956
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005957PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005958"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005959Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005960
Barry Warsaw53699e91996-12-10 23:23:01 +00005961static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005962posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005963{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005964#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005965 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005966#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005967#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005968 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005969#else
5970 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5971#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005972#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005973}
5974
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005975
Guido van Rossumb6775db1994-08-01 11:34:53 +00005976#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005977PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005978"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005979Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005980
Barry Warsaw53699e91996-12-10 23:23:01 +00005981static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005982posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005983{
Ronald Oussoren10168f22006-10-22 10:45:18 +00005984 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005985 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005986 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005987 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00005988#ifdef Py_USING_UNICODE
5989 int arg_is_unicode = 0;
5990#endif
5991
5992 if (!PyArg_ParseTuple(args, "et:readlink",
5993 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005994 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00005995#ifdef Py_USING_UNICODE
5996 v = PySequence_GetItem(args, 0);
Neal Norwitz91a57212007-08-12 17:11:13 +00005997 if (v == NULL) {
5998 PyMem_Free(path);
5999 return NULL;
6000 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006001
6002 if (PyUnicode_Check(v)) {
6003 arg_is_unicode = 1;
6004 }
6005 Py_DECREF(v);
6006#endif
6007
Barry Warsaw53699e91996-12-10 23:23:01 +00006008 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00006009 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00006010 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006011 if (n < 0)
Neal Norwitz91a57212007-08-12 17:11:13 +00006012 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006013
Neal Norwitz91a57212007-08-12 17:11:13 +00006014 PyMem_Free(path);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006015 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006016#ifdef Py_USING_UNICODE
6017 if (arg_is_unicode) {
6018 PyObject *w;
6019
6020 w = PyUnicode_FromEncodedObject(v,
6021 Py_FileSystemDefaultEncoding,
6022 "strict");
6023 if (w != NULL) {
6024 Py_DECREF(v);
6025 v = w;
6026 }
6027 else {
6028 /* fall back to the original byte string, as
6029 discussed in patch #683592 */
6030 PyErr_Clear();
6031 }
6032 }
6033#endif
6034 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006035}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006036#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006037
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006038
Guido van Rossumb6775db1994-08-01 11:34:53 +00006039#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006040PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006041"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006042Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006043
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006044static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006045posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006046{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00006047 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006048}
6049#endif /* HAVE_SYMLINK */
6050
6051
6052#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006053#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6054static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006055system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006056{
6057 ULONG value = 0;
6058
6059 Py_BEGIN_ALLOW_THREADS
6060 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6061 Py_END_ALLOW_THREADS
6062
6063 return value;
6064}
6065
6066static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006067posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006068{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006069 /* Currently Only Uptime is Provided -- Others Later */
6070 return Py_BuildValue("ddddd",
6071 (double)0 /* t.tms_utime / HZ */,
6072 (double)0 /* t.tms_stime / HZ */,
6073 (double)0 /* t.tms_cutime / HZ */,
6074 (double)0 /* t.tms_cstime / HZ */,
6075 (double)system_uptime() / 1000);
6076}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006077#else /* not OS2 */
Martin v. Löwis03824e42008-12-29 18:17:34 +00006078#define NEED_TICKS_PER_SECOND
6079static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006080static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006081posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006082{
6083 struct tms t;
6084 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00006085 errno = 0;
6086 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00006087 if (c == (clock_t) -1)
6088 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006089 return Py_BuildValue("ddddd",
Martin v. Löwis03824e42008-12-29 18:17:34 +00006090 (double)t.tms_utime / ticks_per_second,
6091 (double)t.tms_stime / ticks_per_second,
6092 (double)t.tms_cutime / ticks_per_second,
6093 (double)t.tms_cstime / ticks_per_second,
6094 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006095}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006096#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006097#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006098
6099
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006100#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006101#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006102static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006103posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006104{
6105 FILETIME create, exit, kernel, user;
6106 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006107 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006108 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6109 /* The fields of a FILETIME structure are the hi and lo part
6110 of a 64-bit value expressed in 100 nanosecond units.
6111 1e7 is one second in such units; 1e-7 the inverse.
6112 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6113 */
Barry Warsaw53699e91996-12-10 23:23:01 +00006114 return Py_BuildValue(
6115 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006116 (double)(user.dwHighDateTime*429.4967296 +
6117 user.dwLowDateTime*1e-7),
Georg Brandl0a40ffb2008-02-13 07:20:22 +00006118 (double)(kernel.dwHighDateTime*429.4967296 +
6119 kernel.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00006120 (double)0,
6121 (double)0,
6122 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006123}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006124#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006125
6126#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006127PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006128"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006129Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006130#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006131
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006132
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006133#ifdef HAVE_GETSID
6134PyDoc_STRVAR(posix_getsid__doc__,
6135"getsid(pid) -> sid\n\n\
6136Call the system call getsid().");
6137
6138static PyObject *
6139posix_getsid(PyObject *self, PyObject *args)
6140{
Christian Heimesd491d712008-02-01 18:49:26 +00006141 pid_t pid;
6142 int sid;
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00006143 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006144 return NULL;
6145 sid = getsid(pid);
6146 if (sid < 0)
6147 return posix_error();
6148 return PyInt_FromLong((long)sid);
6149}
6150#endif /* HAVE_GETSID */
6151
6152
Guido van Rossumb6775db1994-08-01 11:34:53 +00006153#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006154PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006155"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006156Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006157
Barry Warsaw53699e91996-12-10 23:23:01 +00006158static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006159posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006160{
Guido van Rossum687dd131993-05-17 08:34:16 +00006161 if (setsid() < 0)
6162 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006163 Py_INCREF(Py_None);
6164 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006165}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006166#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006167
Guido van Rossumb6775db1994-08-01 11:34:53 +00006168#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006169PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006170"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006171Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006172
Barry Warsaw53699e91996-12-10 23:23:01 +00006173static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006174posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006175{
Christian Heimesd491d712008-02-01 18:49:26 +00006176 pid_t pid;
6177 int pgrp;
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00006178 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00006179 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006180 if (setpgid(pid, pgrp) < 0)
6181 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006182 Py_INCREF(Py_None);
6183 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006184}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006185#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006186
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006187
Guido van Rossumb6775db1994-08-01 11:34:53 +00006188#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006189PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006190"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006191Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006192
Barry Warsaw53699e91996-12-10 23:23:01 +00006193static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006194posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006195{
Christian Heimese6a80742008-02-03 19:51:13 +00006196 int fd;
6197 pid_t pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006198 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006199 return NULL;
6200 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006201 if (pgid < 0)
6202 return posix_error();
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00006203 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006204}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006205#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006206
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006207
Guido van Rossumb6775db1994-08-01 11:34:53 +00006208#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006209PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006210"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006211Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006212
Barry Warsaw53699e91996-12-10 23:23:01 +00006213static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006214posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006215{
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00006216 int fd;
6217 pid_t pgid;
6218 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006219 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006220 if (tcsetpgrp(fd, pgid) < 0)
6221 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00006222 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00006223 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006224}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006225#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006226
Guido van Rossum687dd131993-05-17 08:34:16 +00006227/* Functions acting on file descriptors */
6228
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006229PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006230"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006231Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006232
Barry Warsaw53699e91996-12-10 23:23:01 +00006233static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006234posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006235{
Mark Hammondef8b6542001-05-13 08:04:26 +00006236 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006237 int flag;
6238 int mode = 0777;
6239 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006240
6241#ifdef MS_WINDOWS
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00006242 PyUnicodeObject *po;
6243 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6244 Py_BEGIN_ALLOW_THREADS
6245 /* PyUnicode_AS_UNICODE OK without thread
6246 lock as it is a simple dereference. */
6247 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6248 Py_END_ALLOW_THREADS
6249 if (fd < 0)
6250 return posix_error();
6251 return PyInt_FromLong((long)fd);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006252 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00006253 /* Drop the argument parsing error as narrow strings
6254 are also valid. */
6255 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006256#endif
6257
Tim Peters5aa91602002-01-30 05:46:57 +00006258 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00006259 Py_FileSystemDefaultEncoding, &file,
6260 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00006261 return NULL;
6262
Barry Warsaw53699e91996-12-10 23:23:01 +00006263 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006264 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00006265 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006266 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00006267 return posix_error_with_allocated_filename(file);
6268 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00006269 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006270}
6271
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006272
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006273PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006274"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006275Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006276
Barry Warsaw53699e91996-12-10 23:23:01 +00006277static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006278posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006279{
6280 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006281 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006282 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006283 if (!_PyVerify_fd(fd))
6284 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006285 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006286 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006287 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006288 if (res < 0)
6289 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006290 Py_INCREF(Py_None);
6291 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006292}
6293
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006294
Georg Brandl309501a2008-01-19 20:22:13 +00006295PyDoc_STRVAR(posix_closerange__doc__,
6296"closerange(fd_low, fd_high)\n\n\
6297Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6298
6299static PyObject *
6300posix_closerange(PyObject *self, PyObject *args)
6301{
6302 int fd_from, fd_to, i;
6303 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6304 return NULL;
6305 Py_BEGIN_ALLOW_THREADS
6306 for (i = fd_from; i < fd_to; i++)
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006307 if (_PyVerify_fd(i))
6308 close(i);
Georg Brandl309501a2008-01-19 20:22:13 +00006309 Py_END_ALLOW_THREADS
6310 Py_RETURN_NONE;
6311}
6312
6313
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006314PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006315"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006316Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006317
Barry Warsaw53699e91996-12-10 23:23:01 +00006318static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006319posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006320{
6321 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006322 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006323 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006324 if (!_PyVerify_fd(fd))
6325 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006326 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006327 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006328 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006329 if (fd < 0)
6330 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006331 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006332}
6333
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006334
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006335PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006336"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006337Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006338
Barry Warsaw53699e91996-12-10 23:23:01 +00006339static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006340posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006341{
6342 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006343 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00006344 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006345 if (!_PyVerify_fd_dup2(fd, fd2))
6346 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006347 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006348 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00006349 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006350 if (res < 0)
6351 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006352 Py_INCREF(Py_None);
6353 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006354}
6355
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006356
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006357PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006358"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006359Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006360
Barry Warsaw53699e91996-12-10 23:23:01 +00006361static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006362posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006363{
6364 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006365#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006366 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006367#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00006368 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006369#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006370 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006371 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00006372 return NULL;
6373#ifdef SEEK_SET
6374 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6375 switch (how) {
6376 case 0: how = SEEK_SET; break;
6377 case 1: how = SEEK_CUR; break;
6378 case 2: how = SEEK_END; break;
6379 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006380#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006381
6382#if !defined(HAVE_LARGEFILE_SUPPORT)
6383 pos = PyInt_AsLong(posobj);
6384#else
6385 pos = PyLong_Check(posobj) ?
6386 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
6387#endif
6388 if (PyErr_Occurred())
6389 return NULL;
6390
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006391 if (!_PyVerify_fd(fd))
6392 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006393 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006394#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00006395 res = _lseeki64(fd, pos, how);
6396#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006397 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006398#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006399 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006400 if (res < 0)
6401 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006402
6403#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00006404 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006405#else
6406 return PyLong_FromLongLong(res);
6407#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006408}
6409
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006410
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006411PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006412"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006413Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006414
Barry Warsaw53699e91996-12-10 23:23:01 +00006415static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006416posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006417{
Guido van Rossum8bac5461996-06-11 18:38:48 +00006418 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00006419 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006420 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00006421 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00006422 if (size < 0) {
6423 errno = EINVAL;
6424 return posix_error();
6425 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006426 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006427 if (buffer == NULL)
6428 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006429 if (!_PyVerify_fd(fd))
6430 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006431 Py_BEGIN_ALLOW_THREADS
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006432 n = read(fd, PyString_AsString(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00006433 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00006434 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006435 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00006436 return posix_error();
6437 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00006438 if (n != size)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006439 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00006440 return buffer;
6441}
6442
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006443
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006444PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006445"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006446Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006447
Barry Warsaw53699e91996-12-10 23:23:01 +00006448static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006449posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006450{
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006451 Py_buffer pbuf;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006452 int fd;
6453 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006454
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006455 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
Guido van Rossum687dd131993-05-17 08:34:16 +00006456 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006457 if (!_PyVerify_fd(fd))
6458 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006459 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006460 size = write(fd, pbuf.buf, (size_t)pbuf.len);
Barry Warsaw53699e91996-12-10 23:23:01 +00006461 Py_END_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006462 PyBuffer_Release(&pbuf);
Guido van Rossum687dd131993-05-17 08:34:16 +00006463 if (size < 0)
6464 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006465 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006466}
6467
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006468
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006469PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006470"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006471Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006472
Barry Warsaw53699e91996-12-10 23:23:01 +00006473static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006474posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006475{
6476 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00006477 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00006478 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006479 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006480 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006481#ifdef __VMS
6482 /* on OpenVMS we must ensure that all bytes are written to the file */
6483 fsync(fd);
6484#endif
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006485 if (!_PyVerify_fd(fd))
6486 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006487 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00006488 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00006489 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00006490 if (res != 0) {
6491#ifdef MS_WINDOWS
6492 return win32_error("fstat", NULL);
6493#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006494 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006495#endif
6496 }
Tim Peters5aa91602002-01-30 05:46:57 +00006497
Martin v. Löwis14694662006-02-03 12:54:16 +00006498 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006499}
6500
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006501
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006502PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006503"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006504Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006505
Barry Warsaw53699e91996-12-10 23:23:01 +00006506static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006507posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006508{
Guido van Rossum687dd131993-05-17 08:34:16 +00006509 int fd;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006510 char *orgmode = "r";
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006511 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00006512 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00006513 PyObject *f;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006514 char *mode;
6515 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00006516 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006517
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006518 /* Sanitize mode. See fileobject.c */
6519 mode = PyMem_MALLOC(strlen(orgmode)+3);
6520 if (!mode) {
6521 PyErr_NoMemory();
6522 return NULL;
6523 }
6524 strcpy(mode, orgmode);
6525 if (_PyFile_SanitizeMode(mode)) {
6526 PyMem_FREE(mode);
Thomas Heller1f043e22002-11-07 16:00:59 +00006527 return NULL;
6528 }
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006529 if (!_PyVerify_fd(fd))
6530 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006531 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006532#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Georg Brandl54a188a2006-03-31 20:00:11 +00006533 if (mode[0] == 'a') {
6534 /* try to make sure the O_APPEND flag is set */
6535 int flags;
6536 flags = fcntl(fd, F_GETFL);
6537 if (flags != -1)
6538 fcntl(fd, F_SETFL, flags | O_APPEND);
6539 fp = fdopen(fd, mode);
Thomas Wouters2a9a6b02006-03-31 22:38:19 +00006540 if (fp == NULL && flags != -1)
Georg Brandl54a188a2006-03-31 20:00:11 +00006541 /* restore old mode if fdopen failed */
6542 fcntl(fd, F_SETFL, flags);
6543 } else {
6544 fp = fdopen(fd, mode);
6545 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006546#else
6547 fp = fdopen(fd, mode);
6548#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006549 Py_END_ALLOW_THREADS
Neal Norwitzd83eb312007-05-02 04:47:55 +00006550 PyMem_FREE(mode);
Guido van Rossum687dd131993-05-17 08:34:16 +00006551 if (fp == NULL)
6552 return posix_error();
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006553 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006554 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00006555 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006556 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006557}
6558
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006559PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006560"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006561Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006562connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006563
6564static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006565posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006566{
6567 int fd;
6568 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6569 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006570 if (!_PyVerify_fd(fd))
6571 return PyBool_FromLong(0);
Fred Drake106c1a02002-04-23 15:58:02 +00006572 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006573}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006574
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006575#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006576PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006577"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006578Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006579
Barry Warsaw53699e91996-12-10 23:23:01 +00006580static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006581posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006582{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006583#if defined(PYOS_OS2)
6584 HFILE read, write;
6585 APIRET rc;
6586
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006587 Py_BEGIN_ALLOW_THREADS
6588 rc = DosCreatePipe( &read, &write, 4096);
6589 Py_END_ALLOW_THREADS
6590 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006591 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006592
6593 return Py_BuildValue("(ii)", read, write);
6594#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006595#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00006596 int fds[2];
6597 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00006598 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006599 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00006600 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006601 if (res != 0)
6602 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006603 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006604#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00006605 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006606 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00006607 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00006608 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006609 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00006610 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00006611 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006612 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00006613 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6614 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006615 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006616#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006617#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006618}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006619#endif /* HAVE_PIPE */
6620
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006621
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006622#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006623PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006624"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006625Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006626
Barry Warsaw53699e91996-12-10 23:23:01 +00006627static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006628posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006629{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006630 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006631 int mode = 0666;
6632 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006633 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006634 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006635 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006636 res = mkfifo(filename, mode);
6637 Py_END_ALLOW_THREADS
6638 if (res < 0)
6639 return posix_error();
6640 Py_INCREF(Py_None);
6641 return Py_None;
6642}
6643#endif
6644
6645
Neal Norwitz11690112002-07-30 01:08:28 +00006646#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006647PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006648"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006649Create a filesystem node (file, device special file or named pipe)\n\
6650named filename. mode specifies both the permissions to use and the\n\
6651type of node to be created, being combined (bitwise OR) with one of\n\
6652S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006653device defines the newly created device special file (probably using\n\
6654os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006655
6656
6657static PyObject *
6658posix_mknod(PyObject *self, PyObject *args)
6659{
6660 char *filename;
6661 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006662 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006663 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00006664 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006665 return NULL;
6666 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006667 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00006668 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006669 if (res < 0)
6670 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006671 Py_INCREF(Py_None);
6672 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006673}
6674#endif
6675
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006676#ifdef HAVE_DEVICE_MACROS
6677PyDoc_STRVAR(posix_major__doc__,
6678"major(device) -> major number\n\
6679Extracts a device major number from a raw device number.");
6680
6681static PyObject *
6682posix_major(PyObject *self, PyObject *args)
6683{
6684 int device;
6685 if (!PyArg_ParseTuple(args, "i:major", &device))
6686 return NULL;
6687 return PyInt_FromLong((long)major(device));
6688}
6689
6690PyDoc_STRVAR(posix_minor__doc__,
6691"minor(device) -> minor number\n\
6692Extracts a device minor number from a raw device number.");
6693
6694static PyObject *
6695posix_minor(PyObject *self, PyObject *args)
6696{
6697 int device;
6698 if (!PyArg_ParseTuple(args, "i:minor", &device))
6699 return NULL;
6700 return PyInt_FromLong((long)minor(device));
6701}
6702
6703PyDoc_STRVAR(posix_makedev__doc__,
6704"makedev(major, minor) -> device number\n\
6705Composes a raw device number from the major and minor device numbers.");
6706
6707static PyObject *
6708posix_makedev(PyObject *self, PyObject *args)
6709{
6710 int major, minor;
6711 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6712 return NULL;
6713 return PyInt_FromLong((long)makedev(major, minor));
6714}
6715#endif /* device macros */
6716
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006717
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006718#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006719PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006720"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006721Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006722
Barry Warsaw53699e91996-12-10 23:23:01 +00006723static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006724posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006725{
6726 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006727 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006728 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006729 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006730
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006731 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006732 return NULL;
6733
6734#if !defined(HAVE_LARGEFILE_SUPPORT)
6735 length = PyInt_AsLong(lenobj);
6736#else
6737 length = PyLong_Check(lenobj) ?
6738 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6739#endif
6740 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006741 return NULL;
6742
Barry Warsaw53699e91996-12-10 23:23:01 +00006743 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006744 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006745 Py_END_ALLOW_THREADS
Benjamin Peterson943a6dd2009-01-19 15:51:27 +00006746 if (res < 0)
6747 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006748 Py_INCREF(Py_None);
6749 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006750}
6751#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006752
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006753#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006754PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006755"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006756Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006757
Fred Drake762e2061999-08-26 17:23:54 +00006758/* Save putenv() parameters as values here, so we can collect them when they
6759 * get re-set with another call for the same key. */
6760static PyObject *posix_putenv_garbage;
6761
Tim Peters5aa91602002-01-30 05:46:57 +00006762static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006763posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006764{
6765 char *s1, *s2;
Anthony Baxter64182fe2006-04-11 12:14:09 +00006766 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006767 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006768 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006769
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006770 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006771 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006772
6773#if defined(PYOS_OS2)
6774 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6775 APIRET rc;
6776
Guido van Rossumd48f2521997-12-05 22:19:34 +00006777 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6778 if (rc != NO_ERROR)
6779 return os2_error(rc);
6780
6781 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6782 APIRET rc;
6783
Guido van Rossumd48f2521997-12-05 22:19:34 +00006784 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6785 if (rc != NO_ERROR)
6786 return os2_error(rc);
6787 } else {
6788#endif
6789
Fred Drake762e2061999-08-26 17:23:54 +00006790 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006791 len = strlen(s1) + strlen(s2) + 2;
6792 /* len includes space for a trailing \0; the size arg to
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006793 PyString_FromStringAndSize does not count that */
6794 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006795 if (newstr == NULL)
6796 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006797 newenv = PyString_AS_STRING(newstr);
Anthony Baxter64182fe2006-04-11 12:14:09 +00006798 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6799 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006800 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006801 posix_error();
6802 return NULL;
6803 }
Fred Drake762e2061999-08-26 17:23:54 +00006804 /* Install the first arg and newstr in posix_putenv_garbage;
6805 * this will cause previous value to be collected. This has to
6806 * happen after the real putenv() call because the old value
6807 * was still accessible until then. */
6808 if (PyDict_SetItem(posix_putenv_garbage,
6809 PyTuple_GET_ITEM(args, 0), newstr)) {
6810 /* really not much we can do; just leak */
6811 PyErr_Clear();
6812 }
6813 else {
6814 Py_DECREF(newstr);
6815 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006816
6817#if defined(PYOS_OS2)
6818 }
6819#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006820 Py_INCREF(Py_None);
6821 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006822}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006823#endif /* putenv */
6824
Guido van Rossumc524d952001-10-19 01:31:59 +00006825#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006826PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006827"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006828Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006829
6830static PyObject *
6831posix_unsetenv(PyObject *self, PyObject *args)
6832{
6833 char *s1;
6834
6835 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6836 return NULL;
6837
6838 unsetenv(s1);
6839
6840 /* Remove the key from posix_putenv_garbage;
6841 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006842 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006843 * old value was still accessible until then.
6844 */
6845 if (PyDict_DelItem(posix_putenv_garbage,
6846 PyTuple_GET_ITEM(args, 0))) {
6847 /* really not much we can do; just leak */
6848 PyErr_Clear();
6849 }
6850
6851 Py_INCREF(Py_None);
6852 return Py_None;
6853}
6854#endif /* unsetenv */
6855
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006856PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006857"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006858Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006859
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006860static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006861posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006862{
6863 int code;
6864 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006865 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006866 return NULL;
6867 message = strerror(code);
6868 if (message == NULL) {
6869 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006870 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006871 return NULL;
6872 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006873 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006874}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006875
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006876
Guido van Rossumc9641791998-08-04 15:26:23 +00006877#ifdef HAVE_SYS_WAIT_H
6878
Fred Drake106c1a02002-04-23 15:58:02 +00006879#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006880PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006881"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006882Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006883
6884static PyObject *
6885posix_WCOREDUMP(PyObject *self, PyObject *args)
6886{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006887 WAIT_TYPE status;
6888 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006889
Neal Norwitzd5a37542006-03-20 06:48:34 +00006890 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006891 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006892
6893 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006894}
6895#endif /* WCOREDUMP */
6896
6897#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006898PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006899"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006900Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006901job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006902
6903static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006904posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006905{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006906 WAIT_TYPE status;
6907 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006908
Neal Norwitzd5a37542006-03-20 06:48:34 +00006909 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006910 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006911
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006912 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006913}
6914#endif /* WIFCONTINUED */
6915
Guido van Rossumc9641791998-08-04 15:26:23 +00006916#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006917PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006918"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006919Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006920
6921static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006922posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006923{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006924 WAIT_TYPE status;
6925 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006926
Neal Norwitzd5a37542006-03-20 06:48:34 +00006927 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006928 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006929
Fred Drake106c1a02002-04-23 15:58:02 +00006930 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006931}
6932#endif /* WIFSTOPPED */
6933
6934#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006935PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006936"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006937Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006938
6939static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006940posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006941{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006942 WAIT_TYPE status;
6943 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006944
Neal Norwitzd5a37542006-03-20 06:48:34 +00006945 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006946 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006947
Fred Drake106c1a02002-04-23 15:58:02 +00006948 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006949}
6950#endif /* WIFSIGNALED */
6951
6952#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006953PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006954"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006955Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006956system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006957
6958static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006959posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006960{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006961 WAIT_TYPE status;
6962 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006963
Neal Norwitzd5a37542006-03-20 06:48:34 +00006964 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006965 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006966
Fred Drake106c1a02002-04-23 15:58:02 +00006967 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006968}
6969#endif /* WIFEXITED */
6970
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006971#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006972PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006973"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006974Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006975
6976static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006977posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006978{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006979 WAIT_TYPE status;
6980 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006981
Neal Norwitzd5a37542006-03-20 06:48:34 +00006982 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006983 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006984
Guido van Rossumc9641791998-08-04 15:26:23 +00006985 return Py_BuildValue("i", WEXITSTATUS(status));
6986}
6987#endif /* WEXITSTATUS */
6988
6989#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006990PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006991"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006992Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006993value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006994
6995static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006996posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006997{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006998 WAIT_TYPE status;
6999 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007000
Neal Norwitzd5a37542006-03-20 06:48:34 +00007001 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007002 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007003
Guido van Rossumc9641791998-08-04 15:26:23 +00007004 return Py_BuildValue("i", WTERMSIG(status));
7005}
7006#endif /* WTERMSIG */
7007
7008#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007009PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007010"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007011Return the signal that stopped the process that provided\n\
7012the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007013
7014static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007015posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007016{
Neal Norwitzd5a37542006-03-20 06:48:34 +00007017 WAIT_TYPE status;
7018 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007019
Neal Norwitzd5a37542006-03-20 06:48:34 +00007020 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007021 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007022
Guido van Rossumc9641791998-08-04 15:26:23 +00007023 return Py_BuildValue("i", WSTOPSIG(status));
7024}
7025#endif /* WSTOPSIG */
7026
7027#endif /* HAVE_SYS_WAIT_H */
7028
7029
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007030#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00007031#ifdef _SCO_DS
7032/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7033 needed definitions in sys/statvfs.h */
7034#define _SVID3
7035#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007036#include <sys/statvfs.h>
7037
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007038static PyObject*
7039_pystatvfs_fromstructstatvfs(struct statvfs st) {
7040 PyObject *v = PyStructSequence_New(&StatVFSResultType);
7041 if (v == NULL)
7042 return NULL;
7043
7044#if !defined(HAVE_LARGEFILE_SUPPORT)
7045 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7046 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7047 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7048 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7049 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7050 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7051 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7052 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
7053 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7054 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
7055#else
7056 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7057 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00007058 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007059 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00007060 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007061 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007062 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007063 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00007064 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007065 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00007066 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007067 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00007068 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007069 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007070 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7071 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
7072#endif
7073
7074 return v;
7075}
7076
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007077PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007078"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007079Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007080
7081static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007082posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007083{
7084 int fd, res;
7085 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007086
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007087 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00007088 return NULL;
7089 Py_BEGIN_ALLOW_THREADS
7090 res = fstatvfs(fd, &st);
7091 Py_END_ALLOW_THREADS
7092 if (res != 0)
7093 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007094
7095 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007096}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007097#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007098
7099
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007100#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007101#include <sys/statvfs.h>
7102
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007103PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007104"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007105Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007106
7107static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007108posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007109{
7110 char *path;
7111 int res;
7112 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007113 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00007114 return NULL;
7115 Py_BEGIN_ALLOW_THREADS
7116 res = statvfs(path, &st);
7117 Py_END_ALLOW_THREADS
7118 if (res != 0)
7119 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007120
7121 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007122}
7123#endif /* HAVE_STATVFS */
7124
7125
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007126#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007127PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007128"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007129Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007130The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007131or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007132
7133static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007134posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007135{
7136 PyObject *result = NULL;
7137 char *dir = NULL;
7138 char *pfx = NULL;
7139 char *name;
7140
7141 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
7142 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007143
7144 if (PyErr_Warn(PyExc_RuntimeWarning,
7145 "tempnam is a potential security risk to your program") < 0)
7146 return NULL;
7147
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007148#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007149 name = _tempnam(dir, pfx);
7150#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007151 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007152#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007153 if (name == NULL)
7154 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007155 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007156 free(name);
7157 return result;
7158}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007159#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007160
7161
7162#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007163PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007164"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007165Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007166
7167static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007168posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007169{
7170 FILE *fp;
7171
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007172 fp = tmpfile();
7173 if (fp == NULL)
7174 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007175 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007176}
7177#endif
7178
7179
7180#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007181PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007182"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007183Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007184
7185static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007186posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007187{
7188 char buffer[L_tmpnam];
7189 char *name;
7190
Skip Montanaro95618b52001-08-18 18:52:10 +00007191 if (PyErr_Warn(PyExc_RuntimeWarning,
7192 "tmpnam is a potential security risk to your program") < 0)
7193 return NULL;
7194
Greg Wardb48bc172000-03-01 21:51:56 +00007195#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007196 name = tmpnam_r(buffer);
7197#else
7198 name = tmpnam(buffer);
7199#endif
7200 if (name == NULL) {
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007201 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007202#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007203 "unexpected NULL from tmpnam_r"
7204#else
7205 "unexpected NULL from tmpnam"
7206#endif
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007207 );
7208 PyErr_SetObject(PyExc_OSError, err);
7209 Py_XDECREF(err);
7210 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007211 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007212 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007213}
7214#endif
7215
7216
Fred Drakec9680921999-12-13 16:37:25 +00007217/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7218 * It maps strings representing configuration variable names to
7219 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007220 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007221 * rarely-used constants. There are three separate tables that use
7222 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007223 *
7224 * This code is always included, even if none of the interfaces that
7225 * need it are included. The #if hackery needed to avoid it would be
7226 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007227 */
7228struct constdef {
7229 char *name;
7230 long value;
7231};
7232
Fred Drake12c6e2d1999-12-14 21:25:03 +00007233static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007234conv_confname(PyObject *arg, int *valuep, struct constdef *table,
7235 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007236{
7237 if (PyInt_Check(arg)) {
7238 *valuep = PyInt_AS_LONG(arg);
7239 return 1;
7240 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007241 if (PyString_Check(arg)) {
Fred Drake12c6e2d1999-12-14 21:25:03 +00007242 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00007243 size_t lo = 0;
7244 size_t mid;
7245 size_t hi = tablesize;
7246 int cmp;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007247 char *confname = PyString_AS_STRING(arg);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007248 while (lo < hi) {
7249 mid = (lo + hi) / 2;
7250 cmp = strcmp(confname, table[mid].name);
7251 if (cmp < 0)
7252 hi = mid;
7253 else if (cmp > 0)
7254 lo = mid + 1;
7255 else {
7256 *valuep = table[mid].value;
7257 return 1;
7258 }
7259 }
7260 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
7261 }
7262 else
7263 PyErr_SetString(PyExc_TypeError,
7264 "configuration names must be strings or integers");
7265 return 0;
7266}
7267
7268
7269#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7270static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007271#ifdef _PC_ABI_AIO_XFER_MAX
7272 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
7273#endif
7274#ifdef _PC_ABI_ASYNC_IO
7275 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
7276#endif
Fred Drakec9680921999-12-13 16:37:25 +00007277#ifdef _PC_ASYNC_IO
7278 {"PC_ASYNC_IO", _PC_ASYNC_IO},
7279#endif
7280#ifdef _PC_CHOWN_RESTRICTED
7281 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
7282#endif
7283#ifdef _PC_FILESIZEBITS
7284 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
7285#endif
7286#ifdef _PC_LAST
7287 {"PC_LAST", _PC_LAST},
7288#endif
7289#ifdef _PC_LINK_MAX
7290 {"PC_LINK_MAX", _PC_LINK_MAX},
7291#endif
7292#ifdef _PC_MAX_CANON
7293 {"PC_MAX_CANON", _PC_MAX_CANON},
7294#endif
7295#ifdef _PC_MAX_INPUT
7296 {"PC_MAX_INPUT", _PC_MAX_INPUT},
7297#endif
7298#ifdef _PC_NAME_MAX
7299 {"PC_NAME_MAX", _PC_NAME_MAX},
7300#endif
7301#ifdef _PC_NO_TRUNC
7302 {"PC_NO_TRUNC", _PC_NO_TRUNC},
7303#endif
7304#ifdef _PC_PATH_MAX
7305 {"PC_PATH_MAX", _PC_PATH_MAX},
7306#endif
7307#ifdef _PC_PIPE_BUF
7308 {"PC_PIPE_BUF", _PC_PIPE_BUF},
7309#endif
7310#ifdef _PC_PRIO_IO
7311 {"PC_PRIO_IO", _PC_PRIO_IO},
7312#endif
7313#ifdef _PC_SOCK_MAXBUF
7314 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
7315#endif
7316#ifdef _PC_SYNC_IO
7317 {"PC_SYNC_IO", _PC_SYNC_IO},
7318#endif
7319#ifdef _PC_VDISABLE
7320 {"PC_VDISABLE", _PC_VDISABLE},
7321#endif
7322};
7323
Fred Drakec9680921999-12-13 16:37:25 +00007324static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007325conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007326{
7327 return conv_confname(arg, valuep, posix_constants_pathconf,
7328 sizeof(posix_constants_pathconf)
7329 / sizeof(struct constdef));
7330}
7331#endif
7332
7333#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007334PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007335"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007336Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007337If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007338
7339static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007340posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007341{
7342 PyObject *result = NULL;
7343 int name, fd;
7344
Fred Drake12c6e2d1999-12-14 21:25:03 +00007345 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7346 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00007347 long limit;
7348
7349 errno = 0;
7350 limit = fpathconf(fd, name);
7351 if (limit == -1 && errno != 0)
7352 posix_error();
7353 else
7354 result = PyInt_FromLong(limit);
7355 }
7356 return result;
7357}
7358#endif
7359
7360
7361#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007362PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007363"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007364Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007365If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007366
7367static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007368posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007369{
7370 PyObject *result = NULL;
7371 int name;
7372 char *path;
7373
7374 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7375 conv_path_confname, &name)) {
7376 long limit;
7377
7378 errno = 0;
7379 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007380 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00007381 if (errno == EINVAL)
7382 /* could be a path or name problem */
7383 posix_error();
7384 else
7385 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007386 }
Fred Drakec9680921999-12-13 16:37:25 +00007387 else
7388 result = PyInt_FromLong(limit);
7389 }
7390 return result;
7391}
7392#endif
7393
7394#ifdef HAVE_CONFSTR
7395static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007396#ifdef _CS_ARCHITECTURE
7397 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
7398#endif
7399#ifdef _CS_HOSTNAME
7400 {"CS_HOSTNAME", _CS_HOSTNAME},
7401#endif
7402#ifdef _CS_HW_PROVIDER
7403 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
7404#endif
7405#ifdef _CS_HW_SERIAL
7406 {"CS_HW_SERIAL", _CS_HW_SERIAL},
7407#endif
7408#ifdef _CS_INITTAB_NAME
7409 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
7410#endif
Fred Drakec9680921999-12-13 16:37:25 +00007411#ifdef _CS_LFS64_CFLAGS
7412 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
7413#endif
7414#ifdef _CS_LFS64_LDFLAGS
7415 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
7416#endif
7417#ifdef _CS_LFS64_LIBS
7418 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
7419#endif
7420#ifdef _CS_LFS64_LINTFLAGS
7421 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
7422#endif
7423#ifdef _CS_LFS_CFLAGS
7424 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
7425#endif
7426#ifdef _CS_LFS_LDFLAGS
7427 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
7428#endif
7429#ifdef _CS_LFS_LIBS
7430 {"CS_LFS_LIBS", _CS_LFS_LIBS},
7431#endif
7432#ifdef _CS_LFS_LINTFLAGS
7433 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
7434#endif
Fred Draked86ed291999-12-15 15:34:33 +00007435#ifdef _CS_MACHINE
7436 {"CS_MACHINE", _CS_MACHINE},
7437#endif
Fred Drakec9680921999-12-13 16:37:25 +00007438#ifdef _CS_PATH
7439 {"CS_PATH", _CS_PATH},
7440#endif
Fred Draked86ed291999-12-15 15:34:33 +00007441#ifdef _CS_RELEASE
7442 {"CS_RELEASE", _CS_RELEASE},
7443#endif
7444#ifdef _CS_SRPC_DOMAIN
7445 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
7446#endif
7447#ifdef _CS_SYSNAME
7448 {"CS_SYSNAME", _CS_SYSNAME},
7449#endif
7450#ifdef _CS_VERSION
7451 {"CS_VERSION", _CS_VERSION},
7452#endif
Fred Drakec9680921999-12-13 16:37:25 +00007453#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
7454 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
7455#endif
7456#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
7457 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
7458#endif
7459#ifdef _CS_XBS5_ILP32_OFF32_LIBS
7460 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
7461#endif
7462#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
7463 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
7464#endif
7465#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
7466 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
7467#endif
7468#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
7469 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
7470#endif
7471#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
7472 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
7473#endif
7474#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
7475 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
7476#endif
7477#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7478 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
7479#endif
7480#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7481 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7482#endif
7483#ifdef _CS_XBS5_LP64_OFF64_LIBS
7484 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7485#endif
7486#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7487 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7488#endif
7489#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7490 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7491#endif
7492#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7493 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7494#endif
7495#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7496 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7497#endif
7498#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7499 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7500#endif
Fred Draked86ed291999-12-15 15:34:33 +00007501#ifdef _MIPS_CS_AVAIL_PROCESSORS
7502 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7503#endif
7504#ifdef _MIPS_CS_BASE
7505 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7506#endif
7507#ifdef _MIPS_CS_HOSTID
7508 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7509#endif
7510#ifdef _MIPS_CS_HW_NAME
7511 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7512#endif
7513#ifdef _MIPS_CS_NUM_PROCESSORS
7514 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7515#endif
7516#ifdef _MIPS_CS_OSREL_MAJ
7517 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7518#endif
7519#ifdef _MIPS_CS_OSREL_MIN
7520 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7521#endif
7522#ifdef _MIPS_CS_OSREL_PATCH
7523 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7524#endif
7525#ifdef _MIPS_CS_OS_NAME
7526 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7527#endif
7528#ifdef _MIPS_CS_OS_PROVIDER
7529 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7530#endif
7531#ifdef _MIPS_CS_PROCESSORS
7532 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7533#endif
7534#ifdef _MIPS_CS_SERIAL
7535 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7536#endif
7537#ifdef _MIPS_CS_VENDOR
7538 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7539#endif
Fred Drakec9680921999-12-13 16:37:25 +00007540};
7541
7542static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007543conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007544{
7545 return conv_confname(arg, valuep, posix_constants_confstr,
7546 sizeof(posix_constants_confstr)
7547 / sizeof(struct constdef));
7548}
7549
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007550PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007551"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007552Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007553
7554static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007555posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007556{
7557 PyObject *result = NULL;
7558 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007559 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007560
7561 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Skip Montanarodd527fc2006-04-18 00:49:49 +00007562 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007563
Fred Drakec9680921999-12-13 16:37:25 +00007564 errno = 0;
Skip Montanarodd527fc2006-04-18 00:49:49 +00007565 len = confstr(name, buffer, sizeof(buffer));
Skip Montanaro94785ef2006-04-20 01:29:48 +00007566 if (len == 0) {
7567 if (errno) {
7568 posix_error();
7569 }
7570 else {
7571 result = Py_None;
7572 Py_INCREF(Py_None);
7573 }
Fred Drakec9680921999-12-13 16:37:25 +00007574 }
7575 else {
Neal Norwitz0d21b1e2006-04-20 06:44:42 +00007576 if ((unsigned int)len >= sizeof(buffer)) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007577 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007578 if (result != NULL)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007579 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00007580 }
7581 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007582 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007583 }
7584 }
7585 return result;
7586}
7587#endif
7588
7589
7590#ifdef HAVE_SYSCONF
7591static struct constdef posix_constants_sysconf[] = {
7592#ifdef _SC_2_CHAR_TERM
7593 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7594#endif
7595#ifdef _SC_2_C_BIND
7596 {"SC_2_C_BIND", _SC_2_C_BIND},
7597#endif
7598#ifdef _SC_2_C_DEV
7599 {"SC_2_C_DEV", _SC_2_C_DEV},
7600#endif
7601#ifdef _SC_2_C_VERSION
7602 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7603#endif
7604#ifdef _SC_2_FORT_DEV
7605 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7606#endif
7607#ifdef _SC_2_FORT_RUN
7608 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7609#endif
7610#ifdef _SC_2_LOCALEDEF
7611 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7612#endif
7613#ifdef _SC_2_SW_DEV
7614 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7615#endif
7616#ifdef _SC_2_UPE
7617 {"SC_2_UPE", _SC_2_UPE},
7618#endif
7619#ifdef _SC_2_VERSION
7620 {"SC_2_VERSION", _SC_2_VERSION},
7621#endif
Fred Draked86ed291999-12-15 15:34:33 +00007622#ifdef _SC_ABI_ASYNCHRONOUS_IO
7623 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7624#endif
7625#ifdef _SC_ACL
7626 {"SC_ACL", _SC_ACL},
7627#endif
Fred Drakec9680921999-12-13 16:37:25 +00007628#ifdef _SC_AIO_LISTIO_MAX
7629 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7630#endif
Fred Drakec9680921999-12-13 16:37:25 +00007631#ifdef _SC_AIO_MAX
7632 {"SC_AIO_MAX", _SC_AIO_MAX},
7633#endif
7634#ifdef _SC_AIO_PRIO_DELTA_MAX
7635 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7636#endif
7637#ifdef _SC_ARG_MAX
7638 {"SC_ARG_MAX", _SC_ARG_MAX},
7639#endif
7640#ifdef _SC_ASYNCHRONOUS_IO
7641 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7642#endif
7643#ifdef _SC_ATEXIT_MAX
7644 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7645#endif
Fred Draked86ed291999-12-15 15:34:33 +00007646#ifdef _SC_AUDIT
7647 {"SC_AUDIT", _SC_AUDIT},
7648#endif
Fred Drakec9680921999-12-13 16:37:25 +00007649#ifdef _SC_AVPHYS_PAGES
7650 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7651#endif
7652#ifdef _SC_BC_BASE_MAX
7653 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7654#endif
7655#ifdef _SC_BC_DIM_MAX
7656 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7657#endif
7658#ifdef _SC_BC_SCALE_MAX
7659 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7660#endif
7661#ifdef _SC_BC_STRING_MAX
7662 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7663#endif
Fred Draked86ed291999-12-15 15:34:33 +00007664#ifdef _SC_CAP
7665 {"SC_CAP", _SC_CAP},
7666#endif
Fred Drakec9680921999-12-13 16:37:25 +00007667#ifdef _SC_CHARCLASS_NAME_MAX
7668 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7669#endif
7670#ifdef _SC_CHAR_BIT
7671 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7672#endif
7673#ifdef _SC_CHAR_MAX
7674 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7675#endif
7676#ifdef _SC_CHAR_MIN
7677 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7678#endif
7679#ifdef _SC_CHILD_MAX
7680 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7681#endif
7682#ifdef _SC_CLK_TCK
7683 {"SC_CLK_TCK", _SC_CLK_TCK},
7684#endif
7685#ifdef _SC_COHER_BLKSZ
7686 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7687#endif
7688#ifdef _SC_COLL_WEIGHTS_MAX
7689 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7690#endif
7691#ifdef _SC_DCACHE_ASSOC
7692 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7693#endif
7694#ifdef _SC_DCACHE_BLKSZ
7695 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7696#endif
7697#ifdef _SC_DCACHE_LINESZ
7698 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7699#endif
7700#ifdef _SC_DCACHE_SZ
7701 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7702#endif
7703#ifdef _SC_DCACHE_TBLKSZ
7704 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7705#endif
7706#ifdef _SC_DELAYTIMER_MAX
7707 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7708#endif
7709#ifdef _SC_EQUIV_CLASS_MAX
7710 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7711#endif
7712#ifdef _SC_EXPR_NEST_MAX
7713 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7714#endif
7715#ifdef _SC_FSYNC
7716 {"SC_FSYNC", _SC_FSYNC},
7717#endif
7718#ifdef _SC_GETGR_R_SIZE_MAX
7719 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7720#endif
7721#ifdef _SC_GETPW_R_SIZE_MAX
7722 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7723#endif
7724#ifdef _SC_ICACHE_ASSOC
7725 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7726#endif
7727#ifdef _SC_ICACHE_BLKSZ
7728 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7729#endif
7730#ifdef _SC_ICACHE_LINESZ
7731 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7732#endif
7733#ifdef _SC_ICACHE_SZ
7734 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7735#endif
Fred Draked86ed291999-12-15 15:34:33 +00007736#ifdef _SC_INF
7737 {"SC_INF", _SC_INF},
7738#endif
Fred Drakec9680921999-12-13 16:37:25 +00007739#ifdef _SC_INT_MAX
7740 {"SC_INT_MAX", _SC_INT_MAX},
7741#endif
7742#ifdef _SC_INT_MIN
7743 {"SC_INT_MIN", _SC_INT_MIN},
7744#endif
7745#ifdef _SC_IOV_MAX
7746 {"SC_IOV_MAX", _SC_IOV_MAX},
7747#endif
Fred Draked86ed291999-12-15 15:34:33 +00007748#ifdef _SC_IP_SECOPTS
7749 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7750#endif
Fred Drakec9680921999-12-13 16:37:25 +00007751#ifdef _SC_JOB_CONTROL
7752 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7753#endif
Fred Draked86ed291999-12-15 15:34:33 +00007754#ifdef _SC_KERN_POINTERS
7755 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7756#endif
7757#ifdef _SC_KERN_SIM
7758 {"SC_KERN_SIM", _SC_KERN_SIM},
7759#endif
Fred Drakec9680921999-12-13 16:37:25 +00007760#ifdef _SC_LINE_MAX
7761 {"SC_LINE_MAX", _SC_LINE_MAX},
7762#endif
7763#ifdef _SC_LOGIN_NAME_MAX
7764 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7765#endif
7766#ifdef _SC_LOGNAME_MAX
7767 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7768#endif
7769#ifdef _SC_LONG_BIT
7770 {"SC_LONG_BIT", _SC_LONG_BIT},
7771#endif
Fred Draked86ed291999-12-15 15:34:33 +00007772#ifdef _SC_MAC
7773 {"SC_MAC", _SC_MAC},
7774#endif
Fred Drakec9680921999-12-13 16:37:25 +00007775#ifdef _SC_MAPPED_FILES
7776 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7777#endif
7778#ifdef _SC_MAXPID
7779 {"SC_MAXPID", _SC_MAXPID},
7780#endif
7781#ifdef _SC_MB_LEN_MAX
7782 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7783#endif
7784#ifdef _SC_MEMLOCK
7785 {"SC_MEMLOCK", _SC_MEMLOCK},
7786#endif
7787#ifdef _SC_MEMLOCK_RANGE
7788 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7789#endif
7790#ifdef _SC_MEMORY_PROTECTION
7791 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7792#endif
7793#ifdef _SC_MESSAGE_PASSING
7794 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7795#endif
Fred Draked86ed291999-12-15 15:34:33 +00007796#ifdef _SC_MMAP_FIXED_ALIGNMENT
7797 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7798#endif
Fred Drakec9680921999-12-13 16:37:25 +00007799#ifdef _SC_MQ_OPEN_MAX
7800 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7801#endif
7802#ifdef _SC_MQ_PRIO_MAX
7803 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7804#endif
Fred Draked86ed291999-12-15 15:34:33 +00007805#ifdef _SC_NACLS_MAX
7806 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7807#endif
Fred Drakec9680921999-12-13 16:37:25 +00007808#ifdef _SC_NGROUPS_MAX
7809 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7810#endif
7811#ifdef _SC_NL_ARGMAX
7812 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7813#endif
7814#ifdef _SC_NL_LANGMAX
7815 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7816#endif
7817#ifdef _SC_NL_MSGMAX
7818 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7819#endif
7820#ifdef _SC_NL_NMAX
7821 {"SC_NL_NMAX", _SC_NL_NMAX},
7822#endif
7823#ifdef _SC_NL_SETMAX
7824 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7825#endif
7826#ifdef _SC_NL_TEXTMAX
7827 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7828#endif
7829#ifdef _SC_NPROCESSORS_CONF
7830 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7831#endif
7832#ifdef _SC_NPROCESSORS_ONLN
7833 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7834#endif
Fred Draked86ed291999-12-15 15:34:33 +00007835#ifdef _SC_NPROC_CONF
7836 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7837#endif
7838#ifdef _SC_NPROC_ONLN
7839 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7840#endif
Fred Drakec9680921999-12-13 16:37:25 +00007841#ifdef _SC_NZERO
7842 {"SC_NZERO", _SC_NZERO},
7843#endif
7844#ifdef _SC_OPEN_MAX
7845 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7846#endif
7847#ifdef _SC_PAGESIZE
7848 {"SC_PAGESIZE", _SC_PAGESIZE},
7849#endif
7850#ifdef _SC_PAGE_SIZE
7851 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7852#endif
7853#ifdef _SC_PASS_MAX
7854 {"SC_PASS_MAX", _SC_PASS_MAX},
7855#endif
7856#ifdef _SC_PHYS_PAGES
7857 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7858#endif
7859#ifdef _SC_PII
7860 {"SC_PII", _SC_PII},
7861#endif
7862#ifdef _SC_PII_INTERNET
7863 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7864#endif
7865#ifdef _SC_PII_INTERNET_DGRAM
7866 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7867#endif
7868#ifdef _SC_PII_INTERNET_STREAM
7869 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7870#endif
7871#ifdef _SC_PII_OSI
7872 {"SC_PII_OSI", _SC_PII_OSI},
7873#endif
7874#ifdef _SC_PII_OSI_CLTS
7875 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7876#endif
7877#ifdef _SC_PII_OSI_COTS
7878 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7879#endif
7880#ifdef _SC_PII_OSI_M
7881 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7882#endif
7883#ifdef _SC_PII_SOCKET
7884 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7885#endif
7886#ifdef _SC_PII_XTI
7887 {"SC_PII_XTI", _SC_PII_XTI},
7888#endif
7889#ifdef _SC_POLL
7890 {"SC_POLL", _SC_POLL},
7891#endif
7892#ifdef _SC_PRIORITIZED_IO
7893 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7894#endif
7895#ifdef _SC_PRIORITY_SCHEDULING
7896 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7897#endif
7898#ifdef _SC_REALTIME_SIGNALS
7899 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7900#endif
7901#ifdef _SC_RE_DUP_MAX
7902 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7903#endif
7904#ifdef _SC_RTSIG_MAX
7905 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7906#endif
7907#ifdef _SC_SAVED_IDS
7908 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7909#endif
7910#ifdef _SC_SCHAR_MAX
7911 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7912#endif
7913#ifdef _SC_SCHAR_MIN
7914 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7915#endif
7916#ifdef _SC_SELECT
7917 {"SC_SELECT", _SC_SELECT},
7918#endif
7919#ifdef _SC_SEMAPHORES
7920 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7921#endif
7922#ifdef _SC_SEM_NSEMS_MAX
7923 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7924#endif
7925#ifdef _SC_SEM_VALUE_MAX
7926 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7927#endif
7928#ifdef _SC_SHARED_MEMORY_OBJECTS
7929 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7930#endif
7931#ifdef _SC_SHRT_MAX
7932 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7933#endif
7934#ifdef _SC_SHRT_MIN
7935 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7936#endif
7937#ifdef _SC_SIGQUEUE_MAX
7938 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7939#endif
7940#ifdef _SC_SIGRT_MAX
7941 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7942#endif
7943#ifdef _SC_SIGRT_MIN
7944 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7945#endif
Fred Draked86ed291999-12-15 15:34:33 +00007946#ifdef _SC_SOFTPOWER
7947 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7948#endif
Fred Drakec9680921999-12-13 16:37:25 +00007949#ifdef _SC_SPLIT_CACHE
7950 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7951#endif
7952#ifdef _SC_SSIZE_MAX
7953 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7954#endif
7955#ifdef _SC_STACK_PROT
7956 {"SC_STACK_PROT", _SC_STACK_PROT},
7957#endif
7958#ifdef _SC_STREAM_MAX
7959 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7960#endif
7961#ifdef _SC_SYNCHRONIZED_IO
7962 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7963#endif
7964#ifdef _SC_THREADS
7965 {"SC_THREADS", _SC_THREADS},
7966#endif
7967#ifdef _SC_THREAD_ATTR_STACKADDR
7968 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7969#endif
7970#ifdef _SC_THREAD_ATTR_STACKSIZE
7971 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7972#endif
7973#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7974 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7975#endif
7976#ifdef _SC_THREAD_KEYS_MAX
7977 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7978#endif
7979#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7980 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7981#endif
7982#ifdef _SC_THREAD_PRIO_INHERIT
7983 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7984#endif
7985#ifdef _SC_THREAD_PRIO_PROTECT
7986 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7987#endif
7988#ifdef _SC_THREAD_PROCESS_SHARED
7989 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7990#endif
7991#ifdef _SC_THREAD_SAFE_FUNCTIONS
7992 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7993#endif
7994#ifdef _SC_THREAD_STACK_MIN
7995 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7996#endif
7997#ifdef _SC_THREAD_THREADS_MAX
7998 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7999#endif
8000#ifdef _SC_TIMERS
8001 {"SC_TIMERS", _SC_TIMERS},
8002#endif
8003#ifdef _SC_TIMER_MAX
8004 {"SC_TIMER_MAX", _SC_TIMER_MAX},
8005#endif
8006#ifdef _SC_TTY_NAME_MAX
8007 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
8008#endif
8009#ifdef _SC_TZNAME_MAX
8010 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
8011#endif
8012#ifdef _SC_T_IOV_MAX
8013 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
8014#endif
8015#ifdef _SC_UCHAR_MAX
8016 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
8017#endif
8018#ifdef _SC_UINT_MAX
8019 {"SC_UINT_MAX", _SC_UINT_MAX},
8020#endif
8021#ifdef _SC_UIO_MAXIOV
8022 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
8023#endif
8024#ifdef _SC_ULONG_MAX
8025 {"SC_ULONG_MAX", _SC_ULONG_MAX},
8026#endif
8027#ifdef _SC_USHRT_MAX
8028 {"SC_USHRT_MAX", _SC_USHRT_MAX},
8029#endif
8030#ifdef _SC_VERSION
8031 {"SC_VERSION", _SC_VERSION},
8032#endif
8033#ifdef _SC_WORD_BIT
8034 {"SC_WORD_BIT", _SC_WORD_BIT},
8035#endif
8036#ifdef _SC_XBS5_ILP32_OFF32
8037 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
8038#endif
8039#ifdef _SC_XBS5_ILP32_OFFBIG
8040 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
8041#endif
8042#ifdef _SC_XBS5_LP64_OFF64
8043 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
8044#endif
8045#ifdef _SC_XBS5_LPBIG_OFFBIG
8046 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
8047#endif
8048#ifdef _SC_XOPEN_CRYPT
8049 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
8050#endif
8051#ifdef _SC_XOPEN_ENH_I18N
8052 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
8053#endif
8054#ifdef _SC_XOPEN_LEGACY
8055 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
8056#endif
8057#ifdef _SC_XOPEN_REALTIME
8058 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
8059#endif
8060#ifdef _SC_XOPEN_REALTIME_THREADS
8061 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
8062#endif
8063#ifdef _SC_XOPEN_SHM
8064 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
8065#endif
8066#ifdef _SC_XOPEN_UNIX
8067 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
8068#endif
8069#ifdef _SC_XOPEN_VERSION
8070 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
8071#endif
8072#ifdef _SC_XOPEN_XCU_VERSION
8073 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
8074#endif
8075#ifdef _SC_XOPEN_XPG2
8076 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
8077#endif
8078#ifdef _SC_XOPEN_XPG3
8079 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
8080#endif
8081#ifdef _SC_XOPEN_XPG4
8082 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
8083#endif
8084};
8085
8086static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008087conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008088{
8089 return conv_confname(arg, valuep, posix_constants_sysconf,
8090 sizeof(posix_constants_sysconf)
8091 / sizeof(struct constdef));
8092}
8093
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008094PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008095"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008096Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008097
8098static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008099posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008100{
8101 PyObject *result = NULL;
8102 int name;
8103
8104 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
8105 int value;
8106
8107 errno = 0;
8108 value = sysconf(name);
8109 if (value == -1 && errno != 0)
8110 posix_error();
8111 else
8112 result = PyInt_FromLong(value);
8113 }
8114 return result;
8115}
8116#endif
8117
8118
Fred Drakebec628d1999-12-15 18:31:10 +00008119/* This code is used to ensure that the tables of configuration value names
8120 * are in sorted order as required by conv_confname(), and also to build the
8121 * the exported dictionaries that are used to publish information about the
8122 * names available on the host platform.
8123 *
8124 * Sorting the table at runtime ensures that the table is properly ordered
8125 * when used, even for platforms we're not able to test on. It also makes
8126 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008127 */
Fred Drakebec628d1999-12-15 18:31:10 +00008128
8129static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008130cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008131{
8132 const struct constdef *c1 =
8133 (const struct constdef *) v1;
8134 const struct constdef *c2 =
8135 (const struct constdef *) v2;
8136
8137 return strcmp(c1->name, c2->name);
8138}
8139
8140static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008141setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008142 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008143{
Fred Drakebec628d1999-12-15 18:31:10 +00008144 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008145 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008146
8147 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8148 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008149 if (d == NULL)
8150 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008151
Barry Warsaw3155db32000-04-13 15:20:40 +00008152 for (i=0; i < tablesize; ++i) {
8153 PyObject *o = PyInt_FromLong(table[i].value);
8154 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8155 Py_XDECREF(o);
8156 Py_DECREF(d);
8157 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008158 }
Barry Warsaw3155db32000-04-13 15:20:40 +00008159 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008160 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008161 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008162}
8163
Fred Drakebec628d1999-12-15 18:31:10 +00008164/* Return -1 on failure, 0 on success. */
8165static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008166setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008167{
8168#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008169 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008170 sizeof(posix_constants_pathconf)
8171 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008172 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008173 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008174#endif
8175#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008176 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008177 sizeof(posix_constants_confstr)
8178 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008179 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008180 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008181#endif
8182#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008183 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008184 sizeof(posix_constants_sysconf)
8185 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008186 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008187 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008188#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008189 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008190}
Fred Draked86ed291999-12-15 15:34:33 +00008191
8192
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008193PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008194"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008195Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008196in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008197
8198static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008199posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008200{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008201 abort();
8202 /*NOTREACHED*/
8203 Py_FatalError("abort() called from Python code didn't abort!");
8204 return NULL;
8205}
Fred Drakebec628d1999-12-15 18:31:10 +00008206
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008207#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008208PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008209"startfile(filepath [, operation]) - Start a file with its associated\n\
8210application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008211\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008212When \"operation\" is not specified or \"open\", this acts like\n\
8213double-clicking the file in Explorer, or giving the file name as an\n\
8214argument to the DOS \"start\" command: the file is opened with whatever\n\
8215application (if any) its extension is associated.\n\
8216When another \"operation\" is given, it specifies what should be done with\n\
8217the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008218\n\
8219startfile returns as soon as the associated application is launched.\n\
8220There is no option to wait for the application to close, and no way\n\
8221to retrieve the application's exit status.\n\
8222\n\
8223The filepath is relative to the current directory. If you want to use\n\
8224an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008225the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008226
8227static PyObject *
8228win32_startfile(PyObject *self, PyObject *args)
8229{
8230 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00008231 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008232 HINSTANCE rc;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008233
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008234 PyObject *unipath, *woperation = NULL;
8235 if (!PyArg_ParseTuple(args, "U|s:startfile",
8236 &unipath, &operation)) {
8237 PyErr_Clear();
8238 goto normal;
8239 }
8240
8241 if (operation) {
8242 woperation = PyUnicode_DecodeASCII(operation,
8243 strlen(operation), NULL);
8244 if (!woperation) {
Georg Brandlad89dc82006-04-03 12:26:26 +00008245 PyErr_Clear();
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008246 operation = NULL;
Georg Brandlad89dc82006-04-03 12:26:26 +00008247 goto normal;
8248 }
Georg Brandlad89dc82006-04-03 12:26:26 +00008249 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008250
8251 Py_BEGIN_ALLOW_THREADS
8252 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
8253 PyUnicode_AS_UNICODE(unipath),
8254 NULL, NULL, SW_SHOWNORMAL);
8255 Py_END_ALLOW_THREADS
8256
8257 Py_XDECREF(woperation);
8258 if (rc <= (HINSTANCE)32) {
8259 PyObject *errval = win32_error_unicode("startfile",
8260 PyUnicode_AS_UNICODE(unipath));
8261 return errval;
8262 }
8263 Py_INCREF(Py_None);
8264 return Py_None;
Georg Brandlad89dc82006-04-03 12:26:26 +00008265
8266normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00008267 if (!PyArg_ParseTuple(args, "et|s:startfile",
8268 Py_FileSystemDefaultEncoding, &filepath,
8269 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00008270 return NULL;
8271 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00008272 rc = ShellExecute((HWND)0, operation, filepath,
8273 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008274 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00008275 if (rc <= (HINSTANCE)32) {
8276 PyObject *errval = win32_error("startfile", filepath);
8277 PyMem_Free(filepath);
8278 return errval;
8279 }
8280 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008281 Py_INCREF(Py_None);
8282 return Py_None;
8283}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008284#endif /* MS_WINDOWS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008285
Martin v. Löwis438b5342002-12-27 10:16:42 +00008286#ifdef HAVE_GETLOADAVG
8287PyDoc_STRVAR(posix_getloadavg__doc__,
8288"getloadavg() -> (float, float, float)\n\n\
8289Return the number of processes in the system run queue averaged over\n\
8290the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8291was unobtainable");
8292
8293static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008294posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008295{
8296 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008297 if (getloadavg(loadavg, 3)!=3) {
8298 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8299 return NULL;
8300 } else
8301 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
8302}
8303#endif
8304
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008305#ifdef MS_WINDOWS
8306
8307PyDoc_STRVAR(win32_urandom__doc__,
8308"urandom(n) -> str\n\n\
8309Return a string of n random bytes suitable for cryptographic use.");
8310
8311typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8312 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8313 DWORD dwFlags );
8314typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8315 BYTE *pbBuffer );
8316
8317static CRYPTGENRANDOM pCryptGenRandom = NULL;
Martin v. Löwisaf699dd2007-09-04 09:51:57 +00008318/* This handle is never explicitly released. Instead, the operating
8319 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008320static HCRYPTPROV hCryptProv = 0;
8321
Tim Peters4ad82172004-08-30 17:02:04 +00008322static PyObject*
8323win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008324{
Tim Petersd3115382004-08-30 17:36:46 +00008325 int howMany;
8326 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008327
Tim Peters4ad82172004-08-30 17:02:04 +00008328 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00008329 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00008330 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00008331 if (howMany < 0)
8332 return PyErr_Format(PyExc_ValueError,
8333 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008334
Tim Peters4ad82172004-08-30 17:02:04 +00008335 if (hCryptProv == 0) {
8336 HINSTANCE hAdvAPI32 = NULL;
8337 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008338
Tim Peters4ad82172004-08-30 17:02:04 +00008339 /* Obtain handle to the DLL containing CryptoAPI
8340 This should not fail */
8341 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8342 if(hAdvAPI32 == NULL)
8343 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008344
Tim Peters4ad82172004-08-30 17:02:04 +00008345 /* Obtain pointers to the CryptoAPI functions
8346 This will fail on some early versions of Win95 */
8347 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8348 hAdvAPI32,
8349 "CryptAcquireContextA");
8350 if (pCryptAcquireContext == NULL)
8351 return PyErr_Format(PyExc_NotImplementedError,
8352 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008353
Tim Peters4ad82172004-08-30 17:02:04 +00008354 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8355 hAdvAPI32, "CryptGenRandom");
Georg Brandl74bb7832006-09-06 06:03:59 +00008356 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00008357 return PyErr_Format(PyExc_NotImplementedError,
8358 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008359
Tim Peters4ad82172004-08-30 17:02:04 +00008360 /* Acquire context */
8361 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8362 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8363 return win32_error("CryptAcquireContext", NULL);
8364 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008365
Tim Peters4ad82172004-08-30 17:02:04 +00008366 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008367 result = PyString_FromStringAndSize(NULL, howMany);
Tim Petersd3115382004-08-30 17:36:46 +00008368 if (result != NULL) {
8369 /* Get random data */
Amaury Forgeot d'Arc74bd40d2008-07-21 21:06:46 +00008370 memset(PyString_AS_STRING(result), 0, howMany); /* zero seed */
Tim Petersd3115382004-08-30 17:36:46 +00008371 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008372 PyString_AS_STRING(result))) {
Tim Petersd3115382004-08-30 17:36:46 +00008373 Py_DECREF(result);
8374 return win32_error("CryptGenRandom", NULL);
8375 }
Tim Peters4ad82172004-08-30 17:02:04 +00008376 }
Tim Petersd3115382004-08-30 17:36:46 +00008377 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008378}
8379#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008380
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008381#ifdef __VMS
8382/* Use openssl random routine */
8383#include <openssl/rand.h>
8384PyDoc_STRVAR(vms_urandom__doc__,
8385"urandom(n) -> str\n\n\
8386Return a string of n random bytes suitable for cryptographic use.");
8387
8388static PyObject*
8389vms_urandom(PyObject *self, PyObject *args)
8390{
8391 int howMany;
8392 PyObject* result;
8393
8394 /* Read arguments */
8395 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8396 return NULL;
8397 if (howMany < 0)
8398 return PyErr_Format(PyExc_ValueError,
8399 "negative argument not allowed");
8400
8401 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008402 result = PyString_FromStringAndSize(NULL, howMany);
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008403 if (result != NULL) {
8404 /* Get random data */
8405 if (RAND_pseudo_bytes((unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008406 PyString_AS_STRING(result),
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008407 howMany) < 0) {
8408 Py_DECREF(result);
8409 return PyErr_Format(PyExc_ValueError,
8410 "RAND_pseudo_bytes");
8411 }
8412 }
8413 return result;
8414}
8415#endif
8416
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008417static PyMethodDef posix_methods[] = {
8418 {"access", posix_access, METH_VARARGS, posix_access__doc__},
8419#ifdef HAVE_TTYNAME
8420 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
8421#endif
8422 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008423#ifdef HAVE_CHFLAGS
8424 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
8425#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008426 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008427#ifdef HAVE_FCHMOD
8428 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
8429#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008430#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008431 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008432#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008433#ifdef HAVE_LCHMOD
8434 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
8435#endif /* HAVE_LCHMOD */
8436#ifdef HAVE_FCHOWN
8437 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
8438#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008439#ifdef HAVE_LCHFLAGS
8440 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
8441#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008442#ifdef HAVE_LCHOWN
8443 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
8444#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008445#ifdef HAVE_CHROOT
8446 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
8447#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008448#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00008449 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008450#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008451#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00008452 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008453#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00008454 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008455#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008456#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008457#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008458 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008459#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008460 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8461 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8462 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008463#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008464 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008465#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008466#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008467 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008468#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008469 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8470 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8471 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008472 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008473#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008474 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008475#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008476#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008477 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008478#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008479 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008480#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00008481 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008482#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008483 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8484 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8485 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008486#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00008487 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008488#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008489 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008490#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008491 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8492 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008493#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008494#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008495 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8496 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008497#if defined(PYOS_OS2)
8498 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8499 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8500#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008501#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008502#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00008503 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008504#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008505#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00008506 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008507#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008508#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00008509 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008510#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008511#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00008512 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008513#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008514#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008515 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008516#endif /* HAVE_GETEGID */
8517#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008518 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008519#endif /* HAVE_GETEUID */
8520#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008521 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008522#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008523#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00008524 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008525#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008526 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008527#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008528 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008529#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008530#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00008531 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008532#endif /* HAVE_GETPPID */
8533#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008534 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008535#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008536#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00008537 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008538#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008539#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008540 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008541#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008542#ifdef HAVE_KILLPG
8543 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8544#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008545#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008546 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008547#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008548#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008549 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008550#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008551 {"popen2", win32_popen2, METH_VARARGS},
8552 {"popen3", win32_popen3, METH_VARARGS},
8553 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00008554 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008555#else
8556#if defined(PYOS_OS2) && defined(PYCC_GCC)
8557 {"popen2", os2emx_popen2, METH_VARARGS},
8558 {"popen3", os2emx_popen3, METH_VARARGS},
8559 {"popen4", os2emx_popen4, METH_VARARGS},
8560#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008561#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008562#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008563#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008564 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008565#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008566#ifdef HAVE_SETEUID
8567 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8568#endif /* HAVE_SETEUID */
8569#ifdef HAVE_SETEGID
8570 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8571#endif /* HAVE_SETEGID */
8572#ifdef HAVE_SETREUID
8573 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8574#endif /* HAVE_SETREUID */
8575#ifdef HAVE_SETREGID
8576 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8577#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008578#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008579 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008580#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008581#ifdef HAVE_SETGROUPS
Georg Brandl96a8c392006-05-29 21:04:52 +00008582 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008583#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008584#ifdef HAVE_GETPGID
8585 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8586#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008587#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008588 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008589#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008590#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00008591 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008592#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008593#ifdef HAVE_WAIT3
8594 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8595#endif /* HAVE_WAIT3 */
8596#ifdef HAVE_WAIT4
8597 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8598#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008599#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008600 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008601#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008602#ifdef HAVE_GETSID
8603 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8604#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008605#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00008606 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008607#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008608#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008609 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008610#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008611#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008612 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008613#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008614#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008615 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008616#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008617 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8618 {"close", posix_close, METH_VARARGS, posix_close__doc__},
Georg Brandl309501a2008-01-19 20:22:13 +00008619 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008620 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8621 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8622 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8623 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8624 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8625 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8626 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00008627 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008628#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00008629 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008630#endif
8631#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008632 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008633#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008634#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008635 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8636#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008637#ifdef HAVE_DEVICE_MACROS
8638 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8639 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8640 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8641#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008642#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008643 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008644#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008645#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008646 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008647#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008648#ifdef HAVE_UNSETENV
8649 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8650#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008651 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008652#ifdef HAVE_FCHDIR
8653 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8654#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008655#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008656 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008657#endif
8658#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008659 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008660#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008661#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008662#ifdef WCOREDUMP
8663 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8664#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008665#ifdef WIFCONTINUED
8666 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8667#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008668#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008669 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008670#endif /* WIFSTOPPED */
8671#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008672 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008673#endif /* WIFSIGNALED */
8674#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008675 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008676#endif /* WIFEXITED */
8677#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008678 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008679#endif /* WEXITSTATUS */
8680#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008681 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008682#endif /* WTERMSIG */
8683#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008684 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008685#endif /* WSTOPSIG */
8686#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008687#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008688 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008689#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008690#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008691 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008692#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008693#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00008694 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008695#endif
8696#ifdef HAVE_TEMPNAM
8697 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8698#endif
8699#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00008700 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008701#endif
Fred Drakec9680921999-12-13 16:37:25 +00008702#ifdef HAVE_CONFSTR
8703 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8704#endif
8705#ifdef HAVE_SYSCONF
8706 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8707#endif
8708#ifdef HAVE_FPATHCONF
8709 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8710#endif
8711#ifdef HAVE_PATHCONF
8712 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8713#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008714 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008715#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00008716 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8717#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008718#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00008719 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008720#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008721 #ifdef MS_WINDOWS
8722 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8723 #endif
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008724 #ifdef __VMS
8725 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8726 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008727 {NULL, NULL} /* Sentinel */
8728};
8729
8730
Barry Warsaw4a342091996-12-19 23:50:02 +00008731static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008732ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008733{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008734 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008735}
8736
Guido van Rossumd48f2521997-12-05 22:19:34 +00008737#if defined(PYOS_OS2)
8738/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008739static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008740{
8741 APIRET rc;
8742 ULONG values[QSV_MAX+1];
8743 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008744 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008745
8746 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008747 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008748 Py_END_ALLOW_THREADS
8749
8750 if (rc != NO_ERROR) {
8751 os2_error(rc);
8752 return -1;
8753 }
8754
Fred Drake4d1e64b2002-04-15 19:40:07 +00008755 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8756 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8757 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8758 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8759 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8760 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8761 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008762
8763 switch (values[QSV_VERSION_MINOR]) {
8764 case 0: ver = "2.00"; break;
8765 case 10: ver = "2.10"; break;
8766 case 11: ver = "2.11"; break;
8767 case 30: ver = "3.00"; break;
8768 case 40: ver = "4.00"; break;
8769 case 50: ver = "5.00"; break;
8770 default:
Tim Peters885d4572001-11-28 20:27:42 +00008771 PyOS_snprintf(tmp, sizeof(tmp),
8772 "%d-%d", values[QSV_VERSION_MAJOR],
8773 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008774 ver = &tmp[0];
8775 }
8776
8777 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008778 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008779 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008780
8781 /* Add Indicator of Which Drive was Used to Boot the System */
8782 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8783 tmp[1] = ':';
8784 tmp[2] = '\0';
8785
Fred Drake4d1e64b2002-04-15 19:40:07 +00008786 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008787}
8788#endif
8789
Barry Warsaw4a342091996-12-19 23:50:02 +00008790static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008791all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008792{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008793#ifdef F_OK
8794 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008795#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008796#ifdef R_OK
8797 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008798#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008799#ifdef W_OK
8800 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008801#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008802#ifdef X_OK
8803 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008804#endif
Fred Drakec9680921999-12-13 16:37:25 +00008805#ifdef NGROUPS_MAX
8806 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8807#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008808#ifdef TMP_MAX
8809 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8810#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008811#ifdef WCONTINUED
8812 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8813#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008814#ifdef WNOHANG
8815 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008816#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008817#ifdef WUNTRACED
8818 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8819#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008820#ifdef O_RDONLY
8821 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8822#endif
8823#ifdef O_WRONLY
8824 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8825#endif
8826#ifdef O_RDWR
8827 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8828#endif
8829#ifdef O_NDELAY
8830 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8831#endif
8832#ifdef O_NONBLOCK
8833 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8834#endif
8835#ifdef O_APPEND
8836 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8837#endif
8838#ifdef O_DSYNC
8839 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8840#endif
8841#ifdef O_RSYNC
8842 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8843#endif
8844#ifdef O_SYNC
8845 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8846#endif
8847#ifdef O_NOCTTY
8848 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8849#endif
8850#ifdef O_CREAT
8851 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8852#endif
8853#ifdef O_EXCL
8854 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8855#endif
8856#ifdef O_TRUNC
8857 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8858#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008859#ifdef O_BINARY
8860 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8861#endif
8862#ifdef O_TEXT
8863 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8864#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008865#ifdef O_LARGEFILE
8866 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8867#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008868#ifdef O_SHLOCK
8869 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8870#endif
8871#ifdef O_EXLOCK
8872 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8873#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008874
Tim Peters5aa91602002-01-30 05:46:57 +00008875/* MS Windows */
8876#ifdef O_NOINHERIT
8877 /* Don't inherit in child processes. */
8878 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8879#endif
8880#ifdef _O_SHORT_LIVED
8881 /* Optimize for short life (keep in memory). */
8882 /* MS forgot to define this one with a non-underscore form too. */
8883 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8884#endif
8885#ifdef O_TEMPORARY
8886 /* Automatically delete when last handle is closed. */
8887 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8888#endif
8889#ifdef O_RANDOM
8890 /* Optimize for random access. */
8891 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8892#endif
8893#ifdef O_SEQUENTIAL
8894 /* Optimize for sequential access. */
8895 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8896#endif
8897
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008898/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00008899#ifdef O_ASYNC
8900 /* Send a SIGIO signal whenever input or output
8901 becomes available on file descriptor */
8902 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
8903#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008904#ifdef O_DIRECT
8905 /* Direct disk access. */
8906 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8907#endif
8908#ifdef O_DIRECTORY
8909 /* Must be a directory. */
8910 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8911#endif
8912#ifdef O_NOFOLLOW
8913 /* Do not follow links. */
8914 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8915#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00008916#ifdef O_NOATIME
8917 /* Do not update the access time. */
8918 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
8919#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008920
Barry Warsaw5676bd12003-01-07 20:57:09 +00008921 /* These come from sysexits.h */
8922#ifdef EX_OK
8923 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008924#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008925#ifdef EX_USAGE
8926 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008927#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008928#ifdef EX_DATAERR
8929 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008930#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008931#ifdef EX_NOINPUT
8932 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008933#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008934#ifdef EX_NOUSER
8935 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008936#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008937#ifdef EX_NOHOST
8938 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008939#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008940#ifdef EX_UNAVAILABLE
8941 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008942#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008943#ifdef EX_SOFTWARE
8944 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008945#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008946#ifdef EX_OSERR
8947 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008948#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008949#ifdef EX_OSFILE
8950 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008951#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008952#ifdef EX_CANTCREAT
8953 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008954#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008955#ifdef EX_IOERR
8956 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008957#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008958#ifdef EX_TEMPFAIL
8959 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008960#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008961#ifdef EX_PROTOCOL
8962 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008963#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008964#ifdef EX_NOPERM
8965 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008966#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008967#ifdef EX_CONFIG
8968 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008969#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008970#ifdef EX_NOTFOUND
8971 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008972#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008973
Guido van Rossum246bc171999-02-01 23:54:31 +00008974#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008975#if defined(PYOS_OS2) && defined(PYCC_GCC)
8976 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8977 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8978 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8979 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8980 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8981 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8982 if (ins(d, "P_PM", (long)P_PM)) return -1;
8983 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8984 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8985 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8986 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8987 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8988 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8989 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8990 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8991 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8992 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8993 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8994 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8995 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8996#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008997 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8998 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8999 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
9000 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
9001 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00009002#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009003#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00009004
Guido van Rossumd48f2521997-12-05 22:19:34 +00009005#if defined(PYOS_OS2)
9006 if (insertvalues(d)) return -1;
9007#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009008 return 0;
9009}
9010
9011
Tim Peters5aa91602002-01-30 05:46:57 +00009012#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009013#define INITFUNC initnt
9014#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009015
9016#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009017#define INITFUNC initos2
9018#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009019
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009020#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009021#define INITFUNC initposix
9022#define MODNAME "posix"
9023#endif
9024
Mark Hammondfe51c6d2002-08-02 02:27:13 +00009025PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009026INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00009027{
Fred Drake4d1e64b2002-04-15 19:40:07 +00009028 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00009029
Fred Drake4d1e64b2002-04-15 19:40:07 +00009030 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009031 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00009032 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00009033 if (m == NULL)
9034 return;
Tim Peters5aa91602002-01-30 05:46:57 +00009035
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009036 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009037 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00009038 Py_XINCREF(v);
9039 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009040 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00009041 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00009042
Fred Drake4d1e64b2002-04-15 19:40:07 +00009043 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00009044 return;
9045
Fred Drake4d1e64b2002-04-15 19:40:07 +00009046 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00009047 return;
9048
Fred Drake4d1e64b2002-04-15 19:40:07 +00009049 Py_INCREF(PyExc_OSError);
9050 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00009051
Guido van Rossumb3d39562000-01-31 18:41:26 +00009052#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00009053 if (posix_putenv_garbage == NULL)
9054 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00009055#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009056
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009057 if (!initialized) {
9058 stat_result_desc.name = MODNAME ".stat_result";
9059 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9060 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9061 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9062 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9063 structseq_new = StatResultType.tp_new;
9064 StatResultType.tp_new = statresult_new;
9065
9066 statvfs_result_desc.name = MODNAME ".statvfs_result";
9067 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009068#ifdef NEED_TICKS_PER_SECOND
9069# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
9070 ticks_per_second = sysconf(_SC_CLK_TCK);
9071# elif defined(HZ)
9072 ticks_per_second = HZ;
9073# else
9074 ticks_per_second = 60; /* magic fallback value; may be bogus */
9075# endif
9076#endif
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009077 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009078 Py_INCREF((PyObject*) &StatResultType);
9079 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00009080 Py_INCREF((PyObject*) &StatVFSResultType);
9081 PyModule_AddObject(m, "statvfs_result",
9082 (PyObject*) &StatVFSResultType);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009083 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009084
9085#ifdef __APPLE__
9086 /*
9087 * Step 2 of weak-linking support on Mac OS X.
9088 *
9089 * The code below removes functions that are not available on the
9090 * currently active platform.
9091 *
9092 * This block allow one to use a python binary that was build on
9093 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9094 * OSX 10.4.
9095 */
9096#ifdef HAVE_FSTATVFS
9097 if (fstatvfs == NULL) {
9098 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9099 return;
9100 }
9101 }
9102#endif /* HAVE_FSTATVFS */
9103
9104#ifdef HAVE_STATVFS
9105 if (statvfs == NULL) {
9106 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9107 return;
9108 }
9109 }
9110#endif /* HAVE_STATVFS */
9111
9112# ifdef HAVE_LCHOWN
9113 if (lchown == NULL) {
9114 if (PyObject_DelAttrString(m, "lchown") == -1) {
9115 return;
9116 }
9117 }
9118#endif /* HAVE_LCHOWN */
9119
9120
9121#endif /* __APPLE__ */
9122
Guido van Rossumb6775db1994-08-01 11:34:53 +00009123}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009124
9125#ifdef __cplusplus
9126}
9127#endif
9128
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009129