blob: 19c809d1855c4f3f649d70a89ce44d7f222d9de8 [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öwis14694662006-02-03 12:54:16 +0000962static int
963win32_stat(const char* path, struct win32_stat *result)
964{
965 WIN32_FILE_ATTRIBUTE_DATA info;
966 int code;
967 char *dot;
Hirokazu Yamamotobcff47a2009-06-29 11:27:03 +0000968 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000969 if (GetLastError() != ERROR_SHARING_VIOLATION) {
970 /* Protocol violation: we explicitly clear errno, instead of
971 setting it to a POSIX error. Callers should use GetLastError. */
972 errno = 0;
973 return -1;
974 } else {
975 /* Could not get attributes on open file. Fall back to
976 reading the directory. */
977 if (!attributes_from_dir(path, &info)) {
978 /* Very strange. This should not fail now */
979 errno = 0;
980 return -1;
981 }
982 }
Martin v. Löwis14694662006-02-03 12:54:16 +0000983 }
984 code = attribute_data_to_stat(&info, result);
985 if (code != 0)
986 return code;
987 /* Set S_IFEXEC if it is an .exe, .bat, ... */
988 dot = strrchr(path, '.');
989 if (dot) {
990 if (stricmp(dot, ".bat") == 0 ||
991 stricmp(dot, ".cmd") == 0 ||
992 stricmp(dot, ".exe") == 0 ||
993 stricmp(dot, ".com") == 0)
994 result->st_mode |= 0111;
995 }
996 return code;
997}
998
999static int
1000win32_wstat(const wchar_t* path, struct win32_stat *result)
1001{
1002 int code;
1003 const wchar_t *dot;
1004 WIN32_FILE_ATTRIBUTE_DATA info;
Hirokazu Yamamotobcff47a2009-06-29 11:27:03 +00001005 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001006 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1007 /* Protocol violation: we explicitly clear errno, instead of
1008 setting it to a POSIX error. Callers should use GetLastError. */
1009 errno = 0;
1010 return -1;
1011 } else {
1012 /* Could not get attributes on open file. Fall back to
1013 reading the directory. */
1014 if (!attributes_from_dir_w(path, &info)) {
1015 /* Very strange. This should not fail now */
1016 errno = 0;
1017 return -1;
1018 }
1019 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001020 }
1021 code = attribute_data_to_stat(&info, result);
1022 if (code < 0)
1023 return code;
1024 /* Set IFEXEC if it is an .exe, .bat, ... */
1025 dot = wcsrchr(path, '.');
1026 if (dot) {
1027 if (_wcsicmp(dot, L".bat") == 0 ||
1028 _wcsicmp(dot, L".cmd") == 0 ||
1029 _wcsicmp(dot, L".exe") == 0 ||
1030 _wcsicmp(dot, L".com") == 0)
1031 result->st_mode |= 0111;
1032 }
1033 return code;
1034}
1035
1036static int
1037win32_fstat(int file_number, struct win32_stat *result)
1038{
1039 BY_HANDLE_FILE_INFORMATION info;
1040 HANDLE h;
1041 int type;
1042
1043 h = (HANDLE)_get_osfhandle(file_number);
1044
1045 /* Protocol violation: we explicitly clear errno, instead of
1046 setting it to a POSIX error. Callers should use GetLastError. */
1047 errno = 0;
1048
1049 if (h == INVALID_HANDLE_VALUE) {
1050 /* This is really a C library error (invalid file handle).
1051 We set the Win32 error to the closes one matching. */
1052 SetLastError(ERROR_INVALID_HANDLE);
1053 return -1;
1054 }
1055 memset(result, 0, sizeof(*result));
1056
1057 type = GetFileType(h);
1058 if (type == FILE_TYPE_UNKNOWN) {
1059 DWORD error = GetLastError();
1060 if (error != 0) {
1061 return -1;
1062 }
1063 /* else: valid but unknown file */
1064 }
1065
1066 if (type != FILE_TYPE_DISK) {
1067 if (type == FILE_TYPE_CHAR)
1068 result->st_mode = _S_IFCHR;
1069 else if (type == FILE_TYPE_PIPE)
1070 result->st_mode = _S_IFIFO;
1071 return 0;
1072 }
1073
1074 if (!GetFileInformationByHandle(h, &info)) {
1075 return -1;
1076 }
1077
1078 /* similar to stat() */
1079 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1080 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1081 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1082 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1083 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1084 /* specific to fstat() */
1085 result->st_nlink = info.nNumberOfLinks;
1086 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1087 return 0;
1088}
1089
1090#endif /* MS_WINDOWS */
1091
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001092PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001093"stat_result: Result from stat or lstat.\n\n\
1094This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001095 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001096or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1097\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001098Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1099or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001100\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001101See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001102
1103static PyStructSequence_Field stat_result_fields[] = {
1104 {"st_mode", "protection bits"},
1105 {"st_ino", "inode"},
1106 {"st_dev", "device"},
1107 {"st_nlink", "number of hard links"},
1108 {"st_uid", "user ID of owner"},
1109 {"st_gid", "group ID of owner"},
1110 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001111 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1112 {NULL, "integer time of last access"},
1113 {NULL, "integer time of last modification"},
1114 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001115 {"st_atime", "time of last access"},
1116 {"st_mtime", "time of last modification"},
1117 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001118#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001119 {"st_blksize", "blocksize for filesystem I/O"},
1120#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001121#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001122 {"st_blocks", "number of blocks allocated"},
1123#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001124#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001125 {"st_rdev", "device type (if inode device)"},
1126#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001127#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1128 {"st_flags", "user defined flags for file"},
1129#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001130#ifdef HAVE_STRUCT_STAT_ST_GEN
1131 {"st_gen", "generation number"},
1132#endif
1133#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1134 {"st_birthtime", "time of creation"},
1135#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001136 {0}
1137};
1138
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001139#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001140#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001141#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001142#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001143#endif
1144
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001145#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001146#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1147#else
1148#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1149#endif
1150
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001151#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001152#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1153#else
1154#define ST_RDEV_IDX ST_BLOCKS_IDX
1155#endif
1156
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001157#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1158#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1159#else
1160#define ST_FLAGS_IDX ST_RDEV_IDX
1161#endif
1162
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001163#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001164#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001165#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001166#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001167#endif
1168
1169#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1170#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1171#else
1172#define ST_BIRTHTIME_IDX ST_GEN_IDX
1173#endif
1174
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001175static PyStructSequence_Desc stat_result_desc = {
1176 "stat_result", /* name */
1177 stat_result__doc__, /* doc */
1178 stat_result_fields,
1179 10
1180};
1181
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001182PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001183"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1184This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001185 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001186or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001187\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001188See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001189
1190static PyStructSequence_Field statvfs_result_fields[] = {
1191 {"f_bsize", },
1192 {"f_frsize", },
1193 {"f_blocks", },
1194 {"f_bfree", },
1195 {"f_bavail", },
1196 {"f_files", },
1197 {"f_ffree", },
1198 {"f_favail", },
1199 {"f_flag", },
1200 {"f_namemax",},
1201 {0}
1202};
1203
1204static PyStructSequence_Desc statvfs_result_desc = {
1205 "statvfs_result", /* name */
1206 statvfs_result__doc__, /* doc */
1207 statvfs_result_fields,
1208 10
1209};
1210
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001211static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001212static PyTypeObject StatResultType;
1213static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001214static newfunc structseq_new;
1215
1216static PyObject *
1217statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1218{
1219 PyStructSequence *result;
1220 int i;
1221
1222 result = (PyStructSequence*)structseq_new(type, args, kwds);
1223 if (!result)
1224 return NULL;
1225 /* If we have been initialized from a tuple,
1226 st_?time might be set to None. Initialize it
1227 from the int slots. */
1228 for (i = 7; i <= 9; i++) {
1229 if (result->ob_item[i+3] == Py_None) {
1230 Py_DECREF(Py_None);
1231 Py_INCREF(result->ob_item[i]);
1232 result->ob_item[i+3] = result->ob_item[i];
1233 }
1234 }
1235 return (PyObject*)result;
1236}
1237
1238
1239
1240/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001241static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001242
1243PyDoc_STRVAR(stat_float_times__doc__,
1244"stat_float_times([newval]) -> oldval\n\n\
1245Determine whether os.[lf]stat represents time stamps as float objects.\n\
1246If newval is True, future calls to stat() return floats, if it is False,\n\
1247future calls return ints. \n\
1248If newval is omitted, return the current setting.\n");
1249
1250static PyObject*
1251stat_float_times(PyObject* self, PyObject *args)
1252{
1253 int newval = -1;
1254 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1255 return NULL;
1256 if (newval == -1)
1257 /* Return old value */
1258 return PyBool_FromLong(_stat_float_times);
1259 _stat_float_times = newval;
1260 Py_INCREF(Py_None);
1261 return Py_None;
1262}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001263
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001264static void
1265fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1266{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001267 PyObject *fval,*ival;
1268#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001269 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001270#else
1271 ival = PyInt_FromLong((long)sec);
1272#endif
Neal Norwitze0a81af2006-08-12 01:50:38 +00001273 if (!ival)
1274 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001275 if (_stat_float_times) {
1276 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1277 } else {
1278 fval = ival;
1279 Py_INCREF(fval);
1280 }
1281 PyStructSequence_SET_ITEM(v, index, ival);
1282 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001283}
1284
Tim Peters5aa91602002-01-30 05:46:57 +00001285/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001286 (used by posix_stat() and posix_fstat()) */
1287static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001288_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001289{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001290 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001291 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001292 if (v == NULL)
1293 return NULL;
1294
Martin v. Löwis14694662006-02-03 12:54:16 +00001295 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001296#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001297 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001298 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001299#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001300 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001301#endif
1302#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001303 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001304 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001305#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001306 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001307#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001308 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1309 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1310 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001311#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001312 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001313 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001314#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001315 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001316#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001317
Martin v. Löwis14694662006-02-03 12:54:16 +00001318#if defined(HAVE_STAT_TV_NSEC)
1319 ansec = st->st_atim.tv_nsec;
1320 mnsec = st->st_mtim.tv_nsec;
1321 cnsec = st->st_ctim.tv_nsec;
1322#elif defined(HAVE_STAT_TV_NSEC2)
1323 ansec = st->st_atimespec.tv_nsec;
1324 mnsec = st->st_mtimespec.tv_nsec;
1325 cnsec = st->st_ctimespec.tv_nsec;
1326#elif defined(HAVE_STAT_NSEC)
1327 ansec = st->st_atime_nsec;
1328 mnsec = st->st_mtime_nsec;
1329 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001330#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001331 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001332#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001333 fill_time(v, 7, st->st_atime, ansec);
1334 fill_time(v, 8, st->st_mtime, mnsec);
1335 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001336
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001337#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001338 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001339 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001340#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001341#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001342 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001343 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001344#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001345#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001346 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001347 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001348#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001349#ifdef HAVE_STRUCT_STAT_ST_GEN
1350 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001351 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001352#endif
1353#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1354 {
1355 PyObject *val;
1356 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001357 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001358#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001359 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001360#else
1361 bnsec = 0;
1362#endif
1363 if (_stat_float_times) {
1364 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1365 } else {
1366 val = PyInt_FromLong((long)bsec);
1367 }
1368 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1369 val);
1370 }
1371#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001372#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1373 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001374 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001375#endif
Fred Drake699f3522000-06-29 21:12:41 +00001376
1377 if (PyErr_Occurred()) {
1378 Py_DECREF(v);
1379 return NULL;
1380 }
1381
1382 return v;
1383}
1384
Martin v. Löwisd8948722004-06-02 09:57:56 +00001385#ifdef MS_WINDOWS
1386
1387/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1388 where / can be used in place of \ and the trailing slash is optional.
1389 Both SERVER and SHARE must have at least one character.
1390*/
1391
1392#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1393#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001394#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001395#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001396#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001397
Tim Peters4ad82172004-08-30 17:02:04 +00001398static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001399IsUNCRootA(char *path, int pathlen)
1400{
1401 #define ISSLASH ISSLASHA
1402
1403 int i, share;
1404
1405 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1406 /* minimum UNCRoot is \\x\y */
1407 return FALSE;
1408 for (i = 2; i < pathlen ; i++)
1409 if (ISSLASH(path[i])) break;
1410 if (i == 2 || i == pathlen)
1411 /* do not allow \\\SHARE or \\SERVER */
1412 return FALSE;
1413 share = i+1;
1414 for (i = share; i < pathlen; i++)
1415 if (ISSLASH(path[i])) break;
1416 return (i != share && (i == pathlen || i == pathlen-1));
1417
1418 #undef ISSLASH
1419}
1420
Tim Peters4ad82172004-08-30 17:02:04 +00001421static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001422IsUNCRootW(Py_UNICODE *path, int pathlen)
1423{
1424 #define ISSLASH ISSLASHW
1425
1426 int i, share;
1427
1428 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1429 /* minimum UNCRoot is \\x\y */
1430 return FALSE;
1431 for (i = 2; i < pathlen ; i++)
1432 if (ISSLASH(path[i])) break;
1433 if (i == 2 || i == pathlen)
1434 /* do not allow \\\SHARE or \\SERVER */
1435 return FALSE;
1436 share = i+1;
1437 for (i = share; i < pathlen; i++)
1438 if (ISSLASH(path[i])) break;
1439 return (i != share && (i == pathlen || i == pathlen-1));
1440
1441 #undef ISSLASH
1442}
Martin v. Löwisd8948722004-06-02 09:57:56 +00001443#endif /* MS_WINDOWS */
1444
Barry Warsaw53699e91996-12-10 23:23:01 +00001445static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001446posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001447 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001448#ifdef __VMS
1449 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1450#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001451 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001452#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001453 char *wformat,
1454 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001455{
Fred Drake699f3522000-06-29 21:12:41 +00001456 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001457 char *path = NULL; /* pass this to stat; do not free() it */
1458 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001459 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001460 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001461
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001462#ifdef MS_WINDOWS
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001463 PyUnicodeObject *po;
1464 if (PyArg_ParseTuple(args, wformat, &po)) {
1465 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001466
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001467 Py_BEGIN_ALLOW_THREADS
1468 /* PyUnicode_AS_UNICODE result OK without
1469 thread lock as it is a simple dereference. */
1470 res = wstatfunc(wpath, &st);
1471 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001472
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001473 if (res != 0)
1474 return win32_error_unicode("stat", wpath);
1475 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001476 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001477 /* Drop the argument parsing error as narrow strings
1478 are also valid. */
1479 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001480#endif
1481
Tim Peters5aa91602002-01-30 05:46:57 +00001482 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001483 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001484 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001485 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001486
Barry Warsaw53699e91996-12-10 23:23:01 +00001487 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001488 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001489 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001490
1491 if (res != 0) {
1492#ifdef MS_WINDOWS
1493 result = win32_error("stat", pathfree);
1494#else
1495 result = posix_error_with_filename(pathfree);
1496#endif
1497 }
1498 else
1499 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001500
Tim Peters500bd032001-12-19 19:05:01 +00001501 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001502 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001503}
1504
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001505/* POSIX methods */
1506
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001507PyDoc_STRVAR(posix_access__doc__,
Georg Brandl7a284472007-01-27 19:38:50 +00001508"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001509Use the real uid/gid to test for access to a path. Note that most\n\
1510operations will use the effective uid/gid, therefore this routine can\n\
1511be used in a suid/sgid environment to test if the invoking user has the\n\
1512specified access to the path. The mode argument can be F_OK to test\n\
1513existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001514
1515static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001516posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001517{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001518 char *path;
1519 int mode;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001520
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001521#ifdef MS_WINDOWS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001522 DWORD attr;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001523 PyUnicodeObject *po;
1524 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1525 Py_BEGIN_ALLOW_THREADS
1526 /* PyUnicode_AS_UNICODE OK without thread lock as
1527 it is a simple dereference. */
1528 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1529 Py_END_ALLOW_THREADS
1530 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001531 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001532 /* Drop the argument parsing error as narrow strings
1533 are also valid. */
1534 PyErr_Clear();
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001535 if (!PyArg_ParseTuple(args, "eti:access",
1536 Py_FileSystemDefaultEncoding, &path, &mode))
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001537 return NULL;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001538 Py_BEGIN_ALLOW_THREADS
1539 attr = GetFileAttributesA(path);
1540 Py_END_ALLOW_THREADS
1541 PyMem_Free(path);
1542finish:
1543 if (attr == 0xFFFFFFFF)
1544 /* File does not exist, or cannot read attributes */
1545 return PyBool_FromLong(0);
1546 /* Access is possible if either write access wasn't requested, or
Martin v. Löwis7b3cc062007-12-03 23:09:04 +00001547 the file isn't read-only, or if it's a directory, as there are
1548 no read-only directories on Windows. */
1549 return PyBool_FromLong(!(mode & 2)
1550 || !(attr & FILE_ATTRIBUTE_READONLY)
1551 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001552#else /* MS_WINDOWS */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001553 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001554 if (!PyArg_ParseTuple(args, "eti:access",
1555 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001556 return NULL;
1557 Py_BEGIN_ALLOW_THREADS
1558 res = access(path, mode);
1559 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001560 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001561 return PyBool_FromLong(res == 0);
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001562#endif /* MS_WINDOWS */
Guido van Rossum94f6f721999-01-06 18:42:14 +00001563}
1564
Guido van Rossumd371ff11999-01-25 16:12:23 +00001565#ifndef F_OK
1566#define F_OK 0
1567#endif
1568#ifndef R_OK
1569#define R_OK 4
1570#endif
1571#ifndef W_OK
1572#define W_OK 2
1573#endif
1574#ifndef X_OK
1575#define X_OK 1
1576#endif
1577
1578#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001579PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001580"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001581Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001582
1583static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001584posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001585{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001586 int id;
1587 char *ret;
1588
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001589 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001590 return NULL;
1591
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001592#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001593 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001594 if (id == 0) {
1595 ret = ttyname();
1596 }
1597 else {
1598 ret = NULL;
1599 }
1600#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001601 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001602#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001603 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001604 return posix_error();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001605 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001606}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001607#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001608
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001609#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001610PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001611"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001612Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001613
1614static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001615posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001616{
1617 char *ret;
1618 char buffer[L_ctermid];
1619
Greg Wardb48bc172000-03-01 21:51:56 +00001620#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001621 ret = ctermid_r(buffer);
1622#else
1623 ret = ctermid(buffer);
1624#endif
1625 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001626 return posix_error();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001627 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001628}
1629#endif
1630
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001631PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001632"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001633Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001634
Barry Warsaw53699e91996-12-10 23:23:01 +00001635static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001636posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001637{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001638#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001639 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001640#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001641 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001642#elif defined(__VMS)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001643 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001644#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001645 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001646#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001647}
1648
Fred Drake4d1e64b2002-04-15 19:40:07 +00001649#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001650PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001651"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001652Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001653opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001654
1655static PyObject *
1656posix_fchdir(PyObject *self, PyObject *fdobj)
1657{
1658 return posix_fildes(fdobj, fchdir);
1659}
1660#endif /* HAVE_FCHDIR */
1661
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001662
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001663PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001664"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001665Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001666
Barry Warsaw53699e91996-12-10 23:23:01 +00001667static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001668posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001669{
Mark Hammondef8b6542001-05-13 08:04:26 +00001670 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001671 int i;
1672 int res;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001673#ifdef MS_WINDOWS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001674 DWORD attr;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001675 PyUnicodeObject *po;
1676 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1677 Py_BEGIN_ALLOW_THREADS
1678 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1679 if (attr != 0xFFFFFFFF) {
1680 if (i & _S_IWRITE)
1681 attr &= ~FILE_ATTRIBUTE_READONLY;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001682 else
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001683 attr |= FILE_ATTRIBUTE_READONLY;
1684 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
Mark Hammond817c9292003-12-03 01:22:38 +00001685 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001686 else
1687 res = 0;
1688 Py_END_ALLOW_THREADS
1689 if (!res)
1690 return win32_error_unicode("chmod",
1691 PyUnicode_AS_UNICODE(po));
1692 Py_INCREF(Py_None);
1693 return Py_None;
Mark Hammond817c9292003-12-03 01:22:38 +00001694 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001695 /* Drop the argument parsing error as narrow strings
1696 are also valid. */
1697 PyErr_Clear();
1698
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001699 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1700 &path, &i))
1701 return NULL;
1702 Py_BEGIN_ALLOW_THREADS
1703 attr = GetFileAttributesA(path);
1704 if (attr != 0xFFFFFFFF) {
1705 if (i & _S_IWRITE)
1706 attr &= ~FILE_ATTRIBUTE_READONLY;
1707 else
1708 attr |= FILE_ATTRIBUTE_READONLY;
1709 res = SetFileAttributesA(path, attr);
1710 }
1711 else
1712 res = 0;
1713 Py_END_ALLOW_THREADS
1714 if (!res) {
1715 win32_error("chmod", path);
1716 PyMem_Free(path);
1717 return NULL;
1718 }
Martin v. Löwis9f485bc2006-05-08 05:25:56 +00001719 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001720 Py_INCREF(Py_None);
1721 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001722#else /* MS_WINDOWS */
Mark Hammond817c9292003-12-03 01:22:38 +00001723 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001724 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001725 return NULL;
1726 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001727 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001728 Py_END_ALLOW_THREADS
1729 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001730 return posix_error_with_allocated_filename(path);
1731 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001732 Py_INCREF(Py_None);
1733 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001734#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001735}
1736
Christian Heimes36281872007-11-30 21:11:28 +00001737#ifdef HAVE_FCHMOD
1738PyDoc_STRVAR(posix_fchmod__doc__,
1739"fchmod(fd, mode)\n\n\
1740Change the access permissions of the file given by file\n\
1741descriptor fd.");
1742
1743static PyObject *
1744posix_fchmod(PyObject *self, PyObject *args)
1745{
1746 int fd, mode, res;
1747 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1748 return NULL;
1749 Py_BEGIN_ALLOW_THREADS
1750 res = fchmod(fd, mode);
1751 Py_END_ALLOW_THREADS
1752 if (res < 0)
1753 return posix_error();
1754 Py_RETURN_NONE;
1755}
1756#endif /* HAVE_FCHMOD */
1757
1758#ifdef HAVE_LCHMOD
1759PyDoc_STRVAR(posix_lchmod__doc__,
1760"lchmod(path, mode)\n\n\
1761Change the access permissions of a file. If path is a symlink, this\n\
1762affects the link itself rather than the target.");
1763
1764static PyObject *
1765posix_lchmod(PyObject *self, PyObject *args)
1766{
1767 char *path = NULL;
1768 int i;
1769 int res;
1770 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1771 &path, &i))
1772 return NULL;
1773 Py_BEGIN_ALLOW_THREADS
1774 res = lchmod(path, i);
1775 Py_END_ALLOW_THREADS
1776 if (res < 0)
1777 return posix_error_with_allocated_filename(path);
1778 PyMem_Free(path);
1779 Py_RETURN_NONE;
1780}
1781#endif /* HAVE_LCHMOD */
1782
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001783
Martin v. Löwis382abef2007-02-19 10:55:19 +00001784#ifdef HAVE_CHFLAGS
1785PyDoc_STRVAR(posix_chflags__doc__,
1786"chflags(path, flags)\n\n\
1787Set file flags.");
1788
1789static PyObject *
1790posix_chflags(PyObject *self, PyObject *args)
1791{
1792 char *path;
1793 unsigned long flags;
1794 int res;
1795 if (!PyArg_ParseTuple(args, "etk:chflags",
1796 Py_FileSystemDefaultEncoding, &path, &flags))
1797 return NULL;
1798 Py_BEGIN_ALLOW_THREADS
1799 res = chflags(path, flags);
1800 Py_END_ALLOW_THREADS
1801 if (res < 0)
1802 return posix_error_with_allocated_filename(path);
1803 PyMem_Free(path);
1804 Py_INCREF(Py_None);
1805 return Py_None;
1806}
1807#endif /* HAVE_CHFLAGS */
1808
1809#ifdef HAVE_LCHFLAGS
1810PyDoc_STRVAR(posix_lchflags__doc__,
1811"lchflags(path, flags)\n\n\
1812Set file flags.\n\
1813This function will not follow symbolic links.");
1814
1815static PyObject *
1816posix_lchflags(PyObject *self, PyObject *args)
1817{
1818 char *path;
1819 unsigned long flags;
1820 int res;
1821 if (!PyArg_ParseTuple(args, "etk:lchflags",
1822 Py_FileSystemDefaultEncoding, &path, &flags))
1823 return NULL;
1824 Py_BEGIN_ALLOW_THREADS
1825 res = lchflags(path, flags);
1826 Py_END_ALLOW_THREADS
1827 if (res < 0)
1828 return posix_error_with_allocated_filename(path);
1829 PyMem_Free(path);
1830 Py_INCREF(Py_None);
1831 return Py_None;
1832}
1833#endif /* HAVE_LCHFLAGS */
1834
Martin v. Löwis244edc82001-10-04 22:44:26 +00001835#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001836PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001837"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001838Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001839
1840static PyObject *
1841posix_chroot(PyObject *self, PyObject *args)
1842{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001843 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001844}
1845#endif
1846
Guido van Rossum21142a01999-01-08 21:05:37 +00001847#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001848PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001849"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001850force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001851
1852static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001853posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001854{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001855 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001856}
1857#endif /* HAVE_FSYNC */
1858
1859#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001860
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001861#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001862extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1863#endif
1864
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001865PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001866"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001867force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001868 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001869
1870static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001871posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001872{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001873 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001874}
1875#endif /* HAVE_FDATASYNC */
1876
1877
Fredrik Lundh10723342000-07-10 16:38:09 +00001878#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001879PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001880"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001881Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001882
Barry Warsaw53699e91996-12-10 23:23:01 +00001883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001884posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001885{
Mark Hammondef8b6542001-05-13 08:04:26 +00001886 char *path = NULL;
Gregory P. Smithf48da8f2008-03-18 19:05:32 +00001887 long uid, gid;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001888 int res;
Gregory P. Smithf48da8f2008-03-18 19:05:32 +00001889 if (!PyArg_ParseTuple(args, "etll:chown",
Tim Peters5aa91602002-01-30 05:46:57 +00001890 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001891 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001892 return NULL;
1893 Py_BEGIN_ALLOW_THREADS
1894 res = chown(path, (uid_t) uid, (gid_t) gid);
1895 Py_END_ALLOW_THREADS
1896 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001897 return posix_error_with_allocated_filename(path);
1898 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001899 Py_INCREF(Py_None);
1900 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001901}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001902#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001903
Christian Heimes36281872007-11-30 21:11:28 +00001904#ifdef HAVE_FCHOWN
1905PyDoc_STRVAR(posix_fchown__doc__,
1906"fchown(fd, uid, gid)\n\n\
1907Change the owner and group id of the file given by file descriptor\n\
1908fd to the numeric uid and gid.");
1909
1910static PyObject *
1911posix_fchown(PyObject *self, PyObject *args)
1912{
1913 int fd, uid, gid;
1914 int res;
1915 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
1916 return NULL;
1917 Py_BEGIN_ALLOW_THREADS
1918 res = fchown(fd, (uid_t) uid, (gid_t) gid);
1919 Py_END_ALLOW_THREADS
1920 if (res < 0)
1921 return posix_error();
1922 Py_RETURN_NONE;
1923}
1924#endif /* HAVE_FCHOWN */
1925
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001926#ifdef HAVE_LCHOWN
1927PyDoc_STRVAR(posix_lchown__doc__,
1928"lchown(path, uid, gid)\n\n\
1929Change the owner and group id of path to the numeric uid and gid.\n\
1930This function will not follow symbolic links.");
1931
1932static PyObject *
1933posix_lchown(PyObject *self, PyObject *args)
1934{
1935 char *path = NULL;
1936 int uid, gid;
1937 int res;
1938 if (!PyArg_ParseTuple(args, "etii:lchown",
1939 Py_FileSystemDefaultEncoding, &path,
1940 &uid, &gid))
1941 return NULL;
1942 Py_BEGIN_ALLOW_THREADS
1943 res = lchown(path, (uid_t) uid, (gid_t) gid);
1944 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001945 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001946 return posix_error_with_allocated_filename(path);
1947 PyMem_Free(path);
1948 Py_INCREF(Py_None);
1949 return Py_None;
1950}
1951#endif /* HAVE_LCHOWN */
1952
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001953
Guido van Rossum36bc6801995-06-14 22:54:23 +00001954#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001955PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001956"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001957Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001958
Barry Warsaw53699e91996-12-10 23:23:01 +00001959static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001960posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001961{
Facundo Batista5596b0c2008-06-22 13:36:20 +00001962 int bufsize_incr = 1024;
1963 int bufsize = 0;
1964 char *tmpbuf = NULL;
1965 char *res = NULL;
1966 PyObject *dynamic_return;
Neal Norwitze241ce82003-02-17 18:17:05 +00001967
Barry Warsaw53699e91996-12-10 23:23:01 +00001968 Py_BEGIN_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00001969 do {
1970 bufsize = bufsize + bufsize_incr;
1971 tmpbuf = malloc(bufsize);
1972 if (tmpbuf == NULL) {
1973 break;
1974 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001975#if defined(PYOS_OS2) && defined(PYCC_GCC)
Facundo Batista5596b0c2008-06-22 13:36:20 +00001976 res = _getcwd2(tmpbuf, bufsize);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001977#else
Facundo Batista5596b0c2008-06-22 13:36:20 +00001978 res = getcwd(tmpbuf, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001979#endif
Facundo Batista5596b0c2008-06-22 13:36:20 +00001980
1981 if (res == NULL) {
1982 free(tmpbuf);
1983 }
1984 } while ((res == NULL) && (errno == ERANGE));
Barry Warsaw53699e91996-12-10 23:23:01 +00001985 Py_END_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00001986
Guido van Rossumff4949e1992-08-05 19:58:53 +00001987 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001988 return posix_error();
Facundo Batista5596b0c2008-06-22 13:36:20 +00001989
1990 dynamic_return = PyString_FromString(tmpbuf);
1991 free(tmpbuf);
1992
1993 return dynamic_return;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001994}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001995
Walter Dörwald3b918c32002-11-21 20:18:46 +00001996#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001997PyDoc_STRVAR(posix_getcwdu__doc__,
1998"getcwdu() -> path\n\n\
1999Return a unicode string representing the current working directory.");
2000
2001static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002002posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002003{
2004 char buf[1026];
2005 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002006
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002007#ifdef MS_WINDOWS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002008 DWORD len;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002009 wchar_t wbuf[1026];
2010 wchar_t *wbuf2 = wbuf;
2011 PyObject *resobj;
2012 Py_BEGIN_ALLOW_THREADS
2013 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2014 /* If the buffer is large enough, len does not include the
2015 terminating \0. If the buffer is too small, len includes
2016 the space needed for the terminator. */
2017 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2018 wbuf2 = malloc(len * sizeof(wchar_t));
2019 if (wbuf2)
2020 len = GetCurrentDirectoryW(len, wbuf2);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002021 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002022 Py_END_ALLOW_THREADS
2023 if (!wbuf2) {
2024 PyErr_NoMemory();
2025 return NULL;
2026 }
2027 if (!len) {
2028 if (wbuf2 != wbuf) free(wbuf2);
2029 return win32_error("getcwdu", NULL);
2030 }
2031 resobj = PyUnicode_FromWideChar(wbuf2, len);
2032 if (wbuf2 != wbuf) free(wbuf2);
2033 return resobj;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002034#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002035
2036 Py_BEGIN_ALLOW_THREADS
2037#if defined(PYOS_OS2) && defined(PYCC_GCC)
2038 res = _getcwd2(buf, sizeof buf);
2039#else
2040 res = getcwd(buf, sizeof buf);
2041#endif
2042 Py_END_ALLOW_THREADS
2043 if (res == NULL)
2044 return posix_error();
2045 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
2046}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002047#endif /* Py_USING_UNICODE */
2048#endif /* HAVE_GETCWD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002049
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002050
Guido van Rossumb6775db1994-08-01 11:34:53 +00002051#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002052PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002053"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002054Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002055
Barry Warsaw53699e91996-12-10 23:23:01 +00002056static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002057posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002058{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002059 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002060}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002061#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002062
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002063
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002064PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002065"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002066Return a list containing the names of the entries in the directory.\n\
2067\n\
2068 path: path of directory to list\n\
2069\n\
2070The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002071entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002072
Barry Warsaw53699e91996-12-10 23:23:01 +00002073static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002074posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002075{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002076 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002077 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002078#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002079
Barry Warsaw53699e91996-12-10 23:23:01 +00002080 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002081 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002082 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002083 WIN32_FIND_DATA FileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002084 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00002085 char *bufptr = namebuf;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002086 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002087
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002088 PyObject *po;
2089 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2090 WIN32_FIND_DATAW wFileData;
2091 Py_UNICODE *wnamebuf;
2092 /* Overallocate for \\*.*\0 */
2093 len = PyUnicode_GET_SIZE(po);
2094 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2095 if (!wnamebuf) {
2096 PyErr_NoMemory();
2097 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002098 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002099 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2100 if (len > 0) {
2101 Py_UNICODE wch = wnamebuf[len-1];
2102 if (wch != L'/' && wch != L'\\' && wch != L':')
2103 wnamebuf[len++] = L'\\';
2104 wcscpy(wnamebuf + len, L"*.*");
2105 }
2106 if ((d = PyList_New(0)) == NULL) {
2107 free(wnamebuf);
2108 return NULL;
2109 }
2110 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2111 if (hFindFile == INVALID_HANDLE_VALUE) {
2112 int error = GetLastError();
2113 if (error == ERROR_FILE_NOT_FOUND) {
2114 free(wnamebuf);
2115 return d;
2116 }
2117 Py_DECREF(d);
2118 win32_error_unicode("FindFirstFileW", wnamebuf);
2119 free(wnamebuf);
2120 return NULL;
2121 }
2122 do {
2123 /* Skip over . and .. */
2124 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2125 wcscmp(wFileData.cFileName, L"..") != 0) {
2126 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2127 if (v == NULL) {
2128 Py_DECREF(d);
2129 d = NULL;
2130 break;
2131 }
2132 if (PyList_Append(d, v) != 0) {
2133 Py_DECREF(v);
2134 Py_DECREF(d);
2135 d = NULL;
2136 break;
2137 }
2138 Py_DECREF(v);
2139 }
2140 Py_BEGIN_ALLOW_THREADS
2141 result = FindNextFileW(hFindFile, &wFileData);
2142 Py_END_ALLOW_THREADS
2143 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2144 it got to the end of the directory. */
2145 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2146 Py_DECREF(d);
2147 win32_error_unicode("FindNextFileW", wnamebuf);
2148 FindClose(hFindFile);
2149 free(wnamebuf);
2150 return NULL;
2151 }
2152 } while (result == TRUE);
2153
2154 if (FindClose(hFindFile) == FALSE) {
2155 Py_DECREF(d);
2156 win32_error_unicode("FindClose", wnamebuf);
2157 free(wnamebuf);
2158 return NULL;
2159 }
2160 free(wnamebuf);
2161 return d;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002162 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002163 /* Drop the argument parsing error as narrow strings
2164 are also valid. */
2165 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002166
Tim Peters5aa91602002-01-30 05:46:57 +00002167 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002168 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002169 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002170 if (len > 0) {
2171 char ch = namebuf[len-1];
2172 if (ch != SEP && ch != ALTSEP && ch != ':')
2173 namebuf[len++] = '/';
Hirokazu Yamamoto406d7aa2009-05-04 05:28:39 +00002174 strcpy(namebuf + len, "*.*");
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002175 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002176
Barry Warsaw53699e91996-12-10 23:23:01 +00002177 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002178 return NULL;
2179
2180 hFindFile = FindFirstFile(namebuf, &FileData);
2181 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002182 int error = GetLastError();
2183 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002184 return d;
2185 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002186 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002187 }
2188 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002189 /* Skip over . and .. */
2190 if (strcmp(FileData.cFileName, ".") != 0 &&
2191 strcmp(FileData.cFileName, "..") != 0) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002192 v = PyString_FromString(FileData.cFileName);
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002193 if (v == NULL) {
2194 Py_DECREF(d);
2195 d = NULL;
2196 break;
2197 }
2198 if (PyList_Append(d, v) != 0) {
2199 Py_DECREF(v);
2200 Py_DECREF(d);
2201 d = NULL;
2202 break;
2203 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002204 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002205 }
Georg Brandl622927b2006-03-07 12:48:03 +00002206 Py_BEGIN_ALLOW_THREADS
2207 result = FindNextFile(hFindFile, &FileData);
2208 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00002209 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2210 it got to the end of the directory. */
2211 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2212 Py_DECREF(d);
2213 win32_error("FindNextFile", namebuf);
2214 FindClose(hFindFile);
2215 return NULL;
2216 }
Georg Brandl622927b2006-03-07 12:48:03 +00002217 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002218
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002219 if (FindClose(hFindFile) == FALSE) {
2220 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002221 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002222 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002223
2224 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002225
Tim Peters0bb44a42000-09-15 07:44:49 +00002226#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002227
2228#ifndef MAX_PATH
2229#define MAX_PATH CCHMAXPATH
2230#endif
2231 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002232 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002233 PyObject *d, *v;
2234 char namebuf[MAX_PATH+5];
2235 HDIR hdir = 1;
2236 ULONG srchcnt = 1;
2237 FILEFINDBUF3 ep;
2238 APIRET rc;
2239
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002240 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002241 return NULL;
2242 if (len >= MAX_PATH) {
2243 PyErr_SetString(PyExc_ValueError, "path too long");
2244 return NULL;
2245 }
2246 strcpy(namebuf, name);
2247 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002248 if (*pt == ALTSEP)
2249 *pt = SEP;
2250 if (namebuf[len-1] != SEP)
2251 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002252 strcpy(namebuf + len, "*.*");
2253
2254 if ((d = PyList_New(0)) == NULL)
2255 return NULL;
2256
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002257 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2258 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002259 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002260 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2261 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2262 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002263
2264 if (rc != NO_ERROR) {
2265 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002266 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002267 }
2268
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002269 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002270 do {
2271 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002272 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002273 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002274
2275 strcpy(namebuf, ep.achName);
2276
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002277 /* Leave Case of Name Alone -- In Native Form */
2278 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002279
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002280 v = PyString_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002281 if (v == NULL) {
2282 Py_DECREF(d);
2283 d = NULL;
2284 break;
2285 }
2286 if (PyList_Append(d, v) != 0) {
2287 Py_DECREF(v);
2288 Py_DECREF(d);
2289 d = NULL;
2290 break;
2291 }
2292 Py_DECREF(v);
2293 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2294 }
2295
2296 return d;
2297#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002298
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002299 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002300 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002301 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002302 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002303 int arg_is_unicode = 1;
2304
Georg Brandl05e89b82006-04-11 07:04:06 +00002305 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002306 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2307 arg_is_unicode = 0;
2308 PyErr_Clear();
2309 }
2310 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002311 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002312 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002313 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002314 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002315 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002316 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002317 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002318 return NULL;
2319 }
Georg Brandl622927b2006-03-07 12:48:03 +00002320 for (;;) {
Georg Brandl86cbf812008-07-16 21:31:41 +00002321 errno = 0;
Georg Brandl622927b2006-03-07 12:48:03 +00002322 Py_BEGIN_ALLOW_THREADS
2323 ep = readdir(dirp);
2324 Py_END_ALLOW_THREADS
Georg Brandl86cbf812008-07-16 21:31:41 +00002325 if (ep == NULL) {
2326 if (errno == 0) {
2327 break;
2328 } else {
2329 closedir(dirp);
2330 Py_DECREF(d);
2331 return posix_error_with_allocated_filename(name);
2332 }
2333 }
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002334 if (ep->d_name[0] == '.' &&
2335 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002336 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002337 continue;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002338 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002339 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002340 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002341 d = NULL;
2342 break;
2343 }
Just van Rossum46c97842003-02-25 21:42:15 +00002344#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00002345 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002346 PyObject *w;
2347
2348 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002349 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002350 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002351 if (w != NULL) {
2352 Py_DECREF(v);
2353 v = w;
2354 }
2355 else {
2356 /* fall back to the original byte string, as
2357 discussed in patch #683592 */
2358 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002359 }
Just van Rossum46c97842003-02-25 21:42:15 +00002360 }
2361#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002362 if (PyList_Append(d, v) != 0) {
2363 Py_DECREF(v);
2364 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002365 d = NULL;
2366 break;
2367 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002368 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002369 }
2370 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002371 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002372
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002373 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002374
Tim Peters0bb44a42000-09-15 07:44:49 +00002375#endif /* which OS */
2376} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002377
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002378#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002379/* A helper function for abspath on win32 */
2380static PyObject *
2381posix__getfullpathname(PyObject *self, PyObject *args)
2382{
Mark Dickinson3e4caeb2009-02-21 20:27:01 +00002383 /* assume encoded strings won't more than double no of chars */
Mark Hammondef8b6542001-05-13 08:04:26 +00002384 char inbuf[MAX_PATH*2];
2385 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002386 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002387 char outbuf[MAX_PATH*2];
2388 char *temp;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002389
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002390 PyUnicodeObject *po;
2391 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2392 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2393 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2394 Py_UNICODE *wtemp;
2395 DWORD result;
2396 PyObject *v;
2397 result = GetFullPathNameW(wpath,
2398 sizeof(woutbuf)/sizeof(woutbuf[0]),
2399 woutbuf, &wtemp);
2400 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2401 woutbufp = malloc(result * sizeof(Py_UNICODE));
2402 if (!woutbufp)
2403 return PyErr_NoMemory();
2404 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002405 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002406 if (result)
2407 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2408 else
2409 v = win32_error_unicode("GetFullPathNameW", wpath);
2410 if (woutbufp != woutbuf)
2411 free(woutbufp);
2412 return v;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002413 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002414 /* Drop the argument parsing error as narrow strings
2415 are also valid. */
2416 PyErr_Clear();
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002417
Tim Peters5aa91602002-01-30 05:46:57 +00002418 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2419 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002420 &insize))
2421 return NULL;
2422 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2423 outbuf, &temp))
2424 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002425 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2426 return PyUnicode_Decode(outbuf, strlen(outbuf),
2427 Py_FileSystemDefaultEncoding, NULL);
2428 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002429 return PyString_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002430} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002431#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002432
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002433PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002434"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002435Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002436
Barry Warsaw53699e91996-12-10 23:23:01 +00002437static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002438posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002439{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002440 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002441 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002442 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002443
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002444#ifdef MS_WINDOWS
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002445 PyUnicodeObject *po;
2446 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2447 Py_BEGIN_ALLOW_THREADS
2448 /* PyUnicode_AS_UNICODE OK without thread lock as
2449 it is a simple dereference. */
2450 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2451 Py_END_ALLOW_THREADS
2452 if (!res)
2453 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2454 Py_INCREF(Py_None);
2455 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002456 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002457 /* Drop the argument parsing error as narrow strings
2458 are also valid. */
2459 PyErr_Clear();
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002460 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2461 Py_FileSystemDefaultEncoding, &path, &mode))
2462 return NULL;
2463 Py_BEGIN_ALLOW_THREADS
2464 /* PyUnicode_AS_UNICODE OK without thread lock as
2465 it is a simple dereference. */
2466 res = CreateDirectoryA(path, NULL);
2467 Py_END_ALLOW_THREADS
2468 if (!res) {
2469 win32_error("mkdir", path);
2470 PyMem_Free(path);
2471 return NULL;
2472 }
2473 PyMem_Free(path);
2474 Py_INCREF(Py_None);
2475 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002476#else /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002477
Tim Peters5aa91602002-01-30 05:46:57 +00002478 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002479 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002480 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002481 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002482#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002483 res = mkdir(path);
2484#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002485 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002486#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002487 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002488 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002489 return posix_error_with_allocated_filename(path);
2490 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002491 Py_INCREF(Py_None);
2492 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002493#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002494}
2495
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002496
Neal Norwitz1818ed72006-03-26 00:29:48 +00002497/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2498#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002499#include <sys/resource.h>
2500#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002501
Neal Norwitz1818ed72006-03-26 00:29:48 +00002502
2503#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002504PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002505"nice(inc) -> new_priority\n\n\
2506Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002507
Barry Warsaw53699e91996-12-10 23:23:01 +00002508static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002509posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002510{
2511 int increment, value;
2512
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002513 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002514 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002515
2516 /* There are two flavours of 'nice': one that returns the new
2517 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002518 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2519 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002520
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002521 If we are of the nice family that returns the new priority, we
2522 need to clear errno before the call, and check if errno is filled
2523 before calling posix_error() on a returnvalue of -1, because the
2524 -1 may be the actual new priority! */
2525
2526 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002527 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002528#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002529 if (value == 0)
2530 value = getpriority(PRIO_PROCESS, 0);
2531#endif
2532 if (value == -1 && errno != 0)
2533 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002534 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002535 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002536}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002537#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002538
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002539PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002540"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002541Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002542
Barry Warsaw53699e91996-12-10 23:23:01 +00002543static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002544posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002545{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002546#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002547 PyObject *o1, *o2;
2548 char *p1, *p2;
2549 BOOL result;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002550 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002551 goto error;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002552 if (!convert_to_unicode(&o1))
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002553 goto error;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002554 if (!convert_to_unicode(&o2)) {
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002555 Py_DECREF(o1);
2556 goto error;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002557 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002558 Py_BEGIN_ALLOW_THREADS
2559 result = MoveFileW(PyUnicode_AsUnicode(o1),
2560 PyUnicode_AsUnicode(o2));
2561 Py_END_ALLOW_THREADS
2562 Py_DECREF(o1);
2563 Py_DECREF(o2);
2564 if (!result)
2565 return win32_error("rename", NULL);
2566 Py_INCREF(Py_None);
2567 return Py_None;
2568error:
2569 PyErr_Clear();
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002570 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2571 return NULL;
2572 Py_BEGIN_ALLOW_THREADS
2573 result = MoveFileA(p1, p2);
2574 Py_END_ALLOW_THREADS
2575 if (!result)
2576 return win32_error("rename", NULL);
2577 Py_INCREF(Py_None);
2578 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002579#else
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002580 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002581#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002582}
2583
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002584
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002585PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002586"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002587Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002588
Barry Warsaw53699e91996-12-10 23:23:01 +00002589static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002590posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002591{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002592#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002593 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002594#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002595 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002596#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002597}
2598
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002599
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002600PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002601"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002602Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002603
Barry Warsaw53699e91996-12-10 23:23:01 +00002604static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002605posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002606{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002607#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002608 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002609#else
2610 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2611#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002612}
2613
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002614
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002615#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002616PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002617"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002618Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002619
Barry Warsaw53699e91996-12-10 23:23:01 +00002620static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002621posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002622{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002623 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002624 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002625 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002626 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002627 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002628 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002629 Py_END_ALLOW_THREADS
2630 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002631}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002632#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002633
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002634
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002635PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002636"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002637Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002638
Barry Warsaw53699e91996-12-10 23:23:01 +00002639static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002640posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002641{
2642 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002643 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002644 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002645 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002646 if (i < 0)
2647 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002648 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002649}
2650
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002651
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002652PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002653"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002654Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002655
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002656PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002657"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002658Remove a file (same as unlink(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_unlink(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öwis8e0d4942006-05-04 10:08:42 +00002664 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002665#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002666 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002667#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002668}
2669
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002670
Guido van Rossumb6775db1994-08-01 11:34:53 +00002671#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002672PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002673"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002674Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002675
Barry Warsaw53699e91996-12-10 23:23:01 +00002676static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002677posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002678{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002679 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002680 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002681
Barry Warsaw53699e91996-12-10 23:23:01 +00002682 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002683 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002684 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002685 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002686 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002687 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002688 u.sysname,
2689 u.nodename,
2690 u.release,
2691 u.version,
2692 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002693}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002694#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002695
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002696static int
2697extract_time(PyObject *t, long* sec, long* usec)
2698{
2699 long intval;
2700 if (PyFloat_Check(t)) {
2701 double tval = PyFloat_AsDouble(t);
Christian Heimese93237d2007-12-19 02:37:44 +00002702 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002703 if (!intobj)
2704 return -1;
2705 intval = PyInt_AsLong(intobj);
2706 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002707 if (intval == -1 && PyErr_Occurred())
2708 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002709 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002710 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002711 if (*usec < 0)
2712 /* If rounding gave us a negative number,
2713 truncate. */
2714 *usec = 0;
2715 return 0;
2716 }
2717 intval = PyInt_AsLong(t);
2718 if (intval == -1 && PyErr_Occurred())
2719 return -1;
2720 *sec = intval;
2721 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002722 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002723}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002724
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002725PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002726"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002727utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002728Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002729second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002730
Barry Warsaw53699e91996-12-10 23:23:01 +00002731static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002732posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002733{
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002734#ifdef MS_WINDOWS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002735 PyObject *arg;
2736 PyUnicodeObject *obwpath;
2737 wchar_t *wpath = NULL;
2738 char *apath = NULL;
2739 HANDLE hFile;
2740 long atimesec, mtimesec, ausec, musec;
2741 FILETIME atime, mtime;
2742 PyObject *result = NULL;
2743
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002744 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2745 wpath = PyUnicode_AS_UNICODE(obwpath);
2746 Py_BEGIN_ALLOW_THREADS
2747 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2748 NULL, OPEN_EXISTING,
2749 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2750 Py_END_ALLOW_THREADS
2751 if (hFile == INVALID_HANDLE_VALUE)
2752 return win32_error_unicode("utime", wpath);
2753 } else
2754 /* Drop the argument parsing error as narrow strings
2755 are also valid. */
2756 PyErr_Clear();
2757
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002758 if (!wpath) {
2759 if (!PyArg_ParseTuple(args, "etO:utime",
2760 Py_FileSystemDefaultEncoding, &apath, &arg))
2761 return NULL;
2762 Py_BEGIN_ALLOW_THREADS
2763 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002764 NULL, OPEN_EXISTING,
2765 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002766 Py_END_ALLOW_THREADS
2767 if (hFile == INVALID_HANDLE_VALUE) {
2768 win32_error("utime", apath);
2769 PyMem_Free(apath);
2770 return NULL;
2771 }
2772 PyMem_Free(apath);
2773 }
2774
2775 if (arg == Py_None) {
2776 SYSTEMTIME now;
2777 GetSystemTime(&now);
2778 if (!SystemTimeToFileTime(&now, &mtime) ||
2779 !SystemTimeToFileTime(&now, &atime)) {
2780 win32_error("utime", NULL);
2781 goto done;
2782 }
2783 }
2784 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2785 PyErr_SetString(PyExc_TypeError,
2786 "utime() arg 2 must be a tuple (atime, mtime)");
2787 goto done;
2788 }
2789 else {
2790 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2791 &atimesec, &ausec) == -1)
2792 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002793 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002794 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2795 &mtimesec, &musec) == -1)
2796 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002797 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002798 }
2799 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2800 /* Avoid putting the file name into the error here,
2801 as that may confuse the user into believing that
2802 something is wrong with the file, when it also
2803 could be the time stamp that gives a problem. */
2804 win32_error("utime", NULL);
2805 }
2806 Py_INCREF(Py_None);
2807 result = Py_None;
2808done:
2809 CloseHandle(hFile);
2810 return result;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002811#else /* MS_WINDOWS */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002812
Neal Norwitz2adf2102004-06-09 01:46:02 +00002813 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002814 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002815 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002816 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002817
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002818#if defined(HAVE_UTIMES)
2819 struct timeval buf[2];
2820#define ATIME buf[0].tv_sec
2821#define MTIME buf[1].tv_sec
2822#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002823/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002824 struct utimbuf buf;
2825#define ATIME buf.actime
2826#define MTIME buf.modtime
2827#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002828#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002829 time_t buf[2];
2830#define ATIME buf[0]
2831#define MTIME buf[1]
2832#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002833#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002834
Mark Hammond817c9292003-12-03 01:22:38 +00002835
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002836 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002837 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002838 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002839 if (arg == Py_None) {
2840 /* optional time values not given */
2841 Py_BEGIN_ALLOW_THREADS
2842 res = utime(path, NULL);
2843 Py_END_ALLOW_THREADS
2844 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002845 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002846 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002847 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002848 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002849 return NULL;
2850 }
2851 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002852 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002853 &atime, &ausec) == -1) {
2854 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002855 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002856 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002857 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002858 &mtime, &musec) == -1) {
2859 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002860 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002861 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002862 ATIME = atime;
2863 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002864#ifdef HAVE_UTIMES
2865 buf[0].tv_usec = ausec;
2866 buf[1].tv_usec = musec;
2867 Py_BEGIN_ALLOW_THREADS
2868 res = utimes(path, buf);
2869 Py_END_ALLOW_THREADS
2870#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002871 Py_BEGIN_ALLOW_THREADS
2872 res = utime(path, UTIME_ARG);
2873 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002874#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002875 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002876 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002877 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002878 }
Neal Norwitz96652712004-06-06 20:40:27 +00002879 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002880 Py_INCREF(Py_None);
2881 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002882#undef UTIME_ARG
2883#undef ATIME
2884#undef MTIME
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002885#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002886}
2887
Guido van Rossum85e3b011991-06-03 12:42:10 +00002888
Guido van Rossum3b066191991-06-04 19:40:25 +00002889/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002890
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002891PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002892"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002893Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002894
Barry Warsaw53699e91996-12-10 23:23:01 +00002895static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002896posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002897{
2898 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002899 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002900 return NULL;
2901 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002902 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002903}
2904
Martin v. Löwis114619e2002-10-07 06:44:21 +00002905#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2906static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002907free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002908{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002909 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002910 for (i = 0; i < count; i++)
2911 PyMem_Free(array[i]);
2912 PyMem_DEL(array);
2913}
2914#endif
2915
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002916
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002917#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002918PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002919"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002920Execute an executable path with arguments, replacing current process.\n\
2921\n\
2922 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002923 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002924
Barry Warsaw53699e91996-12-10 23:23:01 +00002925static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002926posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002927{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002928 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002929 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002930 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002931 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002932 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002933
Guido van Rossum89b33251993-10-22 14:26:06 +00002934 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002935 argv is a list or tuple of strings. */
2936
Martin v. Löwis114619e2002-10-07 06:44:21 +00002937 if (!PyArg_ParseTuple(args, "etO:execv",
2938 Py_FileSystemDefaultEncoding,
2939 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002940 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002941 if (PyList_Check(argv)) {
2942 argc = PyList_Size(argv);
2943 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002944 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002945 else if (PyTuple_Check(argv)) {
2946 argc = PyTuple_Size(argv);
2947 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002948 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002949 else {
Fred Drake661ea262000-10-24 19:57:45 +00002950 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002951 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002952 return NULL;
2953 }
2954
Barry Warsaw53699e91996-12-10 23:23:01 +00002955 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002956 if (argvlist == NULL) {
2957 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002958 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002959 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002960 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002961 if (!PyArg_Parse((*getitem)(argv, i), "et",
2962 Py_FileSystemDefaultEncoding,
2963 &argvlist[i])) {
2964 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002965 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002966 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002967 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002968 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002969
Guido van Rossum85e3b011991-06-03 12:42:10 +00002970 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002971 }
2972 argvlist[argc] = NULL;
2973
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002974 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002975
Guido van Rossum85e3b011991-06-03 12:42:10 +00002976 /* If we get here it's definitely an error */
2977
Martin v. Löwis114619e2002-10-07 06:44:21 +00002978 free_string_array(argvlist, argc);
2979 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002980 return posix_error();
2981}
2982
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002983
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002984PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002985"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002986Execute a path with arguments and environment, replacing current process.\n\
2987\n\
2988 path: path of executable file\n\
2989 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002990 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002991
Barry Warsaw53699e91996-12-10 23:23:01 +00002992static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002993posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002994{
2995 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002996 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002997 char **argvlist;
2998 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002999 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003000 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003001 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003002 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003003
3004 /* execve has three arguments: (path, argv, env), where
3005 argv is a list or tuple of strings and env is a dictionary
3006 like posix.environ. */
3007
Martin v. Löwis114619e2002-10-07 06:44:21 +00003008 if (!PyArg_ParseTuple(args, "etOO:execve",
3009 Py_FileSystemDefaultEncoding,
3010 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003011 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003012 if (PyList_Check(argv)) {
3013 argc = PyList_Size(argv);
3014 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003015 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003016 else if (PyTuple_Check(argv)) {
3017 argc = PyTuple_Size(argv);
3018 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003019 }
3020 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003021 PyErr_SetString(PyExc_TypeError,
3022 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003023 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003024 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003025 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003026 PyErr_SetString(PyExc_TypeError,
3027 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003028 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003029 }
3030
Barry Warsaw53699e91996-12-10 23:23:01 +00003031 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003032 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003033 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003034 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003035 }
3036 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003037 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00003038 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00003039 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00003040 &argvlist[i]))
3041 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003042 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003043 goto fail_1;
3044 }
3045 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003046 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003047 argvlist[argc] = NULL;
3048
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003049 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003050 if (i < 0)
3051 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00003052 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003053 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003054 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003055 goto fail_1;
3056 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003057 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003058 keys = PyMapping_Keys(env);
3059 vals = PyMapping_Values(env);
3060 if (!keys || !vals)
3061 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003062 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3063 PyErr_SetString(PyExc_TypeError,
3064 "execve(): env.keys() or env.values() is not a list");
3065 goto fail_2;
3066 }
Tim Peters5aa91602002-01-30 05:46:57 +00003067
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003068 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003069 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003070 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003071
3072 key = PyList_GetItem(keys, pos);
3073 val = PyList_GetItem(vals, pos);
3074 if (!key || !val)
3075 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003076
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003077 if (!PyArg_Parse(
3078 key,
3079 "s;execve() arg 3 contains a non-string key",
3080 &k) ||
3081 !PyArg_Parse(
3082 val,
3083 "s;execve() arg 3 contains a non-string value",
3084 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003085 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003086 goto fail_2;
3087 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003088
3089#if defined(PYOS_OS2)
3090 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3091 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3092#endif
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003093 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003094 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003095 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003096 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003097 goto fail_2;
3098 }
Tim Petersc8996f52001-12-03 20:41:00 +00003099 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003100 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003101#if defined(PYOS_OS2)
3102 }
3103#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003104 }
3105 envlist[envc] = 0;
3106
3107 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003108
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003109 /* If we get here it's definitely an error */
3110
3111 (void) posix_error();
3112
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003113 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003114 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003115 PyMem_DEL(envlist[envc]);
3116 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003117 fail_1:
3118 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003119 Py_XDECREF(vals);
3120 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003121 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003122 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003123 return NULL;
3124}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003125#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003126
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003127
Guido van Rossuma1065681999-01-25 23:20:23 +00003128#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003129PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003130"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003131Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003132\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003133 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003134 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003135 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003136
3137static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003138posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003139{
3140 char *path;
3141 PyObject *argv;
3142 char **argvlist;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003143 int mode, i;
3144 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003145 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003146 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003147
3148 /* spawnv has three arguments: (mode, path, argv), where
3149 argv is a list or tuple of strings. */
3150
Martin v. Löwis114619e2002-10-07 06:44:21 +00003151 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3152 Py_FileSystemDefaultEncoding,
3153 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003154 return NULL;
3155 if (PyList_Check(argv)) {
3156 argc = PyList_Size(argv);
3157 getitem = PyList_GetItem;
3158 }
3159 else if (PyTuple_Check(argv)) {
3160 argc = PyTuple_Size(argv);
3161 getitem = PyTuple_GetItem;
3162 }
3163 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003164 PyErr_SetString(PyExc_TypeError,
3165 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003166 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003167 return NULL;
3168 }
3169
3170 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003171 if (argvlist == NULL) {
3172 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003173 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003174 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003175 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003176 if (!PyArg_Parse((*getitem)(argv, i), "et",
3177 Py_FileSystemDefaultEncoding,
3178 &argvlist[i])) {
3179 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003180 PyErr_SetString(
3181 PyExc_TypeError,
3182 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003183 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00003184 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003185 }
3186 }
3187 argvlist[argc] = NULL;
3188
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003189#if defined(PYOS_OS2) && defined(PYCC_GCC)
3190 Py_BEGIN_ALLOW_THREADS
3191 spawnval = spawnv(mode, path, argvlist);
3192 Py_END_ALLOW_THREADS
3193#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003194 if (mode == _OLD_P_OVERLAY)
3195 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003196
Tim Peters25059d32001-12-07 20:35:43 +00003197 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003198 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003199 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003200#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003201
Martin v. Löwis114619e2002-10-07 06:44:21 +00003202 free_string_array(argvlist, argc);
3203 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003204
Fred Drake699f3522000-06-29 21:12:41 +00003205 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003206 return posix_error();
3207 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003208#if SIZEOF_LONG == SIZEOF_VOID_P
3209 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003210#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003211 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003212#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003213}
3214
3215
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003216PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003217"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003218Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003219\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003220 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003221 path: path of executable file\n\
3222 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003223 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003224
3225static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003226posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003227{
3228 char *path;
3229 PyObject *argv, *env;
3230 char **argvlist;
3231 char **envlist;
3232 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003233 int mode, pos, envc;
3234 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003235 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003236 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003237 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003238
3239 /* spawnve has four arguments: (mode, path, argv, env), where
3240 argv is a list or tuple of strings and env is a dictionary
3241 like posix.environ. */
3242
Martin v. Löwis114619e2002-10-07 06:44:21 +00003243 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3244 Py_FileSystemDefaultEncoding,
3245 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003246 return NULL;
3247 if (PyList_Check(argv)) {
3248 argc = PyList_Size(argv);
3249 getitem = PyList_GetItem;
3250 }
3251 else if (PyTuple_Check(argv)) {
3252 argc = PyTuple_Size(argv);
3253 getitem = PyTuple_GetItem;
3254 }
3255 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003256 PyErr_SetString(PyExc_TypeError,
3257 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003258 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003259 }
3260 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003261 PyErr_SetString(PyExc_TypeError,
3262 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003263 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003264 }
3265
3266 argvlist = PyMem_NEW(char *, argc+1);
3267 if (argvlist == NULL) {
3268 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003269 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003270 }
3271 for (i = 0; i < argc; i++) {
3272 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003273 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00003274 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00003275 &argvlist[i]))
3276 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003277 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003278 goto fail_1;
3279 }
3280 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003281 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003282 argvlist[argc] = NULL;
3283
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003284 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003285 if (i < 0)
3286 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003287 envlist = PyMem_NEW(char *, i + 1);
3288 if (envlist == NULL) {
3289 PyErr_NoMemory();
3290 goto fail_1;
3291 }
3292 envc = 0;
3293 keys = PyMapping_Keys(env);
3294 vals = PyMapping_Values(env);
3295 if (!keys || !vals)
3296 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003297 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3298 PyErr_SetString(PyExc_TypeError,
3299 "spawnve(): env.keys() or env.values() is not a list");
3300 goto fail_2;
3301 }
Tim Peters5aa91602002-01-30 05:46:57 +00003302
Guido van Rossuma1065681999-01-25 23:20:23 +00003303 for (pos = 0; pos < i; pos++) {
3304 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003305 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003306
3307 key = PyList_GetItem(keys, pos);
3308 val = PyList_GetItem(vals, pos);
3309 if (!key || !val)
3310 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003311
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003312 if (!PyArg_Parse(
3313 key,
3314 "s;spawnve() arg 3 contains a non-string key",
3315 &k) ||
3316 !PyArg_Parse(
3317 val,
3318 "s;spawnve() arg 3 contains a non-string value",
3319 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003320 {
3321 goto fail_2;
3322 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003323 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003324 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003325 if (p == NULL) {
3326 PyErr_NoMemory();
3327 goto fail_2;
3328 }
Tim Petersc8996f52001-12-03 20:41:00 +00003329 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003330 envlist[envc++] = p;
3331 }
3332 envlist[envc] = 0;
3333
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003334#if defined(PYOS_OS2) && defined(PYCC_GCC)
3335 Py_BEGIN_ALLOW_THREADS
3336 spawnval = spawnve(mode, path, argvlist, envlist);
3337 Py_END_ALLOW_THREADS
3338#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003339 if (mode == _OLD_P_OVERLAY)
3340 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003341
3342 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003343 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003344 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003345#endif
Tim Peters25059d32001-12-07 20:35:43 +00003346
Fred Drake699f3522000-06-29 21:12:41 +00003347 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003348 (void) posix_error();
3349 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003350#if SIZEOF_LONG == SIZEOF_VOID_P
3351 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003352#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003353 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003354#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003355
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003356 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003357 while (--envc >= 0)
3358 PyMem_DEL(envlist[envc]);
3359 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003360 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003361 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003362 Py_XDECREF(vals);
3363 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003364 fail_0:
3365 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003366 return res;
3367}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003368
3369/* OS/2 supports spawnvp & spawnvpe natively */
3370#if defined(PYOS_OS2)
3371PyDoc_STRVAR(posix_spawnvp__doc__,
3372"spawnvp(mode, file, args)\n\n\
3373Execute the program 'file' in a new process, using the environment\n\
3374search path to find the file.\n\
3375\n\
3376 mode: mode of process creation\n\
3377 file: executable file name\n\
3378 args: tuple or list of strings");
3379
3380static PyObject *
3381posix_spawnvp(PyObject *self, PyObject *args)
3382{
3383 char *path;
3384 PyObject *argv;
3385 char **argvlist;
3386 int mode, i, argc;
3387 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003388 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003389
3390 /* spawnvp has three arguments: (mode, path, argv), where
3391 argv is a list or tuple of strings. */
3392
3393 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3394 Py_FileSystemDefaultEncoding,
3395 &path, &argv))
3396 return NULL;
3397 if (PyList_Check(argv)) {
3398 argc = PyList_Size(argv);
3399 getitem = PyList_GetItem;
3400 }
3401 else if (PyTuple_Check(argv)) {
3402 argc = PyTuple_Size(argv);
3403 getitem = PyTuple_GetItem;
3404 }
3405 else {
3406 PyErr_SetString(PyExc_TypeError,
3407 "spawnvp() arg 2 must be a tuple or list");
3408 PyMem_Free(path);
3409 return NULL;
3410 }
3411
3412 argvlist = PyMem_NEW(char *, argc+1);
3413 if (argvlist == NULL) {
3414 PyMem_Free(path);
3415 return PyErr_NoMemory();
3416 }
3417 for (i = 0; i < argc; i++) {
3418 if (!PyArg_Parse((*getitem)(argv, i), "et",
3419 Py_FileSystemDefaultEncoding,
3420 &argvlist[i])) {
3421 free_string_array(argvlist, i);
3422 PyErr_SetString(
3423 PyExc_TypeError,
3424 "spawnvp() arg 2 must contain only strings");
3425 PyMem_Free(path);
3426 return NULL;
3427 }
3428 }
3429 argvlist[argc] = NULL;
3430
3431 Py_BEGIN_ALLOW_THREADS
3432#if defined(PYCC_GCC)
3433 spawnval = spawnvp(mode, path, argvlist);
3434#else
3435 spawnval = _spawnvp(mode, path, argvlist);
3436#endif
3437 Py_END_ALLOW_THREADS
3438
3439 free_string_array(argvlist, argc);
3440 PyMem_Free(path);
3441
3442 if (spawnval == -1)
3443 return posix_error();
3444 else
3445 return Py_BuildValue("l", (long) spawnval);
3446}
3447
3448
3449PyDoc_STRVAR(posix_spawnvpe__doc__,
3450"spawnvpe(mode, file, args, env)\n\n\
3451Execute the program 'file' in a new process, using the environment\n\
3452search path to find the file.\n\
3453\n\
3454 mode: mode of process creation\n\
3455 file: executable file name\n\
3456 args: tuple or list of arguments\n\
3457 env: dictionary of strings mapping to strings");
3458
3459static PyObject *
3460posix_spawnvpe(PyObject *self, PyObject *args)
3461{
3462 char *path;
3463 PyObject *argv, *env;
3464 char **argvlist;
3465 char **envlist;
3466 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3467 int mode, i, pos, argc, envc;
3468 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003469 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003470 int lastarg = 0;
3471
3472 /* spawnvpe has four arguments: (mode, path, argv, env), where
3473 argv is a list or tuple of strings and env is a dictionary
3474 like posix.environ. */
3475
3476 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3477 Py_FileSystemDefaultEncoding,
3478 &path, &argv, &env))
3479 return NULL;
3480 if (PyList_Check(argv)) {
3481 argc = PyList_Size(argv);
3482 getitem = PyList_GetItem;
3483 }
3484 else if (PyTuple_Check(argv)) {
3485 argc = PyTuple_Size(argv);
3486 getitem = PyTuple_GetItem;
3487 }
3488 else {
3489 PyErr_SetString(PyExc_TypeError,
3490 "spawnvpe() arg 2 must be a tuple or list");
3491 goto fail_0;
3492 }
3493 if (!PyMapping_Check(env)) {
3494 PyErr_SetString(PyExc_TypeError,
3495 "spawnvpe() arg 3 must be a mapping object");
3496 goto fail_0;
3497 }
3498
3499 argvlist = PyMem_NEW(char *, argc+1);
3500 if (argvlist == NULL) {
3501 PyErr_NoMemory();
3502 goto fail_0;
3503 }
3504 for (i = 0; i < argc; i++) {
3505 if (!PyArg_Parse((*getitem)(argv, i),
3506 "et;spawnvpe() arg 2 must contain only strings",
3507 Py_FileSystemDefaultEncoding,
3508 &argvlist[i]))
3509 {
3510 lastarg = i;
3511 goto fail_1;
3512 }
3513 }
3514 lastarg = argc;
3515 argvlist[argc] = NULL;
3516
3517 i = PyMapping_Size(env);
3518 if (i < 0)
3519 goto fail_1;
3520 envlist = PyMem_NEW(char *, i + 1);
3521 if (envlist == NULL) {
3522 PyErr_NoMemory();
3523 goto fail_1;
3524 }
3525 envc = 0;
3526 keys = PyMapping_Keys(env);
3527 vals = PyMapping_Values(env);
3528 if (!keys || !vals)
3529 goto fail_2;
3530 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3531 PyErr_SetString(PyExc_TypeError,
3532 "spawnvpe(): env.keys() or env.values() is not a list");
3533 goto fail_2;
3534 }
3535
3536 for (pos = 0; pos < i; pos++) {
3537 char *p, *k, *v;
3538 size_t len;
3539
3540 key = PyList_GetItem(keys, pos);
3541 val = PyList_GetItem(vals, pos);
3542 if (!key || !val)
3543 goto fail_2;
3544
3545 if (!PyArg_Parse(
3546 key,
3547 "s;spawnvpe() arg 3 contains a non-string key",
3548 &k) ||
3549 !PyArg_Parse(
3550 val,
3551 "s;spawnvpe() arg 3 contains a non-string value",
3552 &v))
3553 {
3554 goto fail_2;
3555 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003556 len = PyString_Size(key) + PyString_Size(val) + 2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003557 p = PyMem_NEW(char, len);
3558 if (p == NULL) {
3559 PyErr_NoMemory();
3560 goto fail_2;
3561 }
3562 PyOS_snprintf(p, len, "%s=%s", k, v);
3563 envlist[envc++] = p;
3564 }
3565 envlist[envc] = 0;
3566
3567 Py_BEGIN_ALLOW_THREADS
3568#if defined(PYCC_GCC)
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003569 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003570#else
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003571 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003572#endif
3573 Py_END_ALLOW_THREADS
3574
3575 if (spawnval == -1)
3576 (void) posix_error();
3577 else
3578 res = Py_BuildValue("l", (long) spawnval);
3579
3580 fail_2:
3581 while (--envc >= 0)
3582 PyMem_DEL(envlist[envc]);
3583 PyMem_DEL(envlist);
3584 fail_1:
3585 free_string_array(argvlist, lastarg);
3586 Py_XDECREF(vals);
3587 Py_XDECREF(keys);
3588 fail_0:
3589 PyMem_Free(path);
3590 return res;
3591}
3592#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003593#endif /* HAVE_SPAWNV */
3594
3595
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003596#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003597PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003598"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003599Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3600\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003601Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003602
3603static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003604posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003605{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003606 pid_t pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003607 if (pid == -1)
3608 return posix_error();
Gregory P. Smithfb7a50f2008-07-14 06:06:48 +00003609 if (pid == 0)
3610 PyOS_AfterFork();
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00003611 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003612}
3613#endif
3614
3615
Guido van Rossumad0ee831995-03-01 10:34:45 +00003616#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003617PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003618"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003619Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003620Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003621
Barry Warsaw53699e91996-12-10 23:23:01 +00003622static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003623posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003624{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003625 pid_t pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003626 if (pid == -1)
3627 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003628 if (pid == 0)
3629 PyOS_AfterFork();
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00003630 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003631}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003632#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003633
Neal Norwitzb59798b2003-03-21 01:43:31 +00003634/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003635/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3636#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003637#define DEV_PTY_FILE "/dev/ptc"
3638#define HAVE_DEV_PTMX
3639#else
3640#define DEV_PTY_FILE "/dev/ptmx"
3641#endif
3642
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003643#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003644#ifdef HAVE_PTY_H
3645#include <pty.h>
3646#else
3647#ifdef HAVE_LIBUTIL_H
3648#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003649#endif /* HAVE_LIBUTIL_H */
3650#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003651#ifdef HAVE_STROPTS_H
3652#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003653#endif
3654#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003655
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003656#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003657PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003658"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003659Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003660
3661static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003662posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003663{
3664 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003665#ifndef HAVE_OPENPTY
3666 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003667#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003668#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003669 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003670#ifdef sun
Neal Norwitz84a98e02006-04-10 07:44:23 +00003671 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003672#endif
3673#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003674
Thomas Wouters70c21a12000-07-14 14:28:33 +00003675#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003676 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3677 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003678#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003679 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3680 if (slave_name == NULL)
3681 return posix_error();
3682
3683 slave_fd = open(slave_name, O_RDWR);
3684 if (slave_fd < 0)
3685 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003686#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003687 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003688 if (master_fd < 0)
3689 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003690 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003691 /* change permission of slave */
3692 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003693 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003694 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003695 }
3696 /* unlock slave */
3697 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003698 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003699 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003700 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003701 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003702 slave_name = ptsname(master_fd); /* get name of slave */
3703 if (slave_name == NULL)
3704 return posix_error();
3705 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3706 if (slave_fd < 0)
3707 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003708#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003709 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3710 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003711#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003712 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003713#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003714#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003715#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003716
Fred Drake8cef4cf2000-06-28 16:40:38 +00003717 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003718
Fred Drake8cef4cf2000-06-28 16:40:38 +00003719}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003720#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003721
3722#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003723PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003724"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003725Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3726Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003727To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003728
3729static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003730posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003731{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003732 int master_fd = -1;
3733 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003734
Fred Drake8cef4cf2000-06-28 16:40:38 +00003735 pid = forkpty(&master_fd, NULL, NULL, NULL);
3736 if (pid == -1)
3737 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003738 if (pid == 0)
3739 PyOS_AfterFork();
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00003740 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003741}
3742#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003743
Guido van Rossumad0ee831995-03-01 10:34:45 +00003744#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003745PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003746"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003747Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003748
Barry Warsaw53699e91996-12-10 23:23:01 +00003749static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003750posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003751{
Barry Warsaw53699e91996-12-10 23:23:01 +00003752 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003753}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003754#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003755
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003756
Guido van Rossumad0ee831995-03-01 10:34:45 +00003757#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003758PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003759"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003760Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003761
Barry Warsaw53699e91996-12-10 23:23:01 +00003762static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003763posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003764{
Barry Warsaw53699e91996-12-10 23:23:01 +00003765 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003766}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003767#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003768
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003769
Guido van Rossumad0ee831995-03-01 10:34:45 +00003770#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003771PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003772"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003773Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003774
Barry Warsaw53699e91996-12-10 23:23:01 +00003775static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003776posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003777{
Barry Warsaw53699e91996-12-10 23:23:01 +00003778 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003779}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003780#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003781
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003782
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003783PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003784"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003785Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003786
Barry Warsaw53699e91996-12-10 23:23:01 +00003787static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003788posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003789{
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00003790 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003791}
3792
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003793
Fred Drakec9680921999-12-13 16:37:25 +00003794#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003795PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003796"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003797Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003798
3799static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003800posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003801{
3802 PyObject *result = NULL;
3803
Fred Drakec9680921999-12-13 16:37:25 +00003804#ifdef NGROUPS_MAX
3805#define MAX_GROUPS NGROUPS_MAX
3806#else
3807 /* defined to be 16 on Solaris7, so this should be a small number */
3808#define MAX_GROUPS 64
3809#endif
3810 gid_t grouplist[MAX_GROUPS];
3811 int n;
3812
3813 n = getgroups(MAX_GROUPS, grouplist);
3814 if (n < 0)
3815 posix_error();
3816 else {
3817 result = PyList_New(n);
3818 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003819 int i;
3820 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003821 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003822 if (o == NULL) {
3823 Py_DECREF(result);
3824 result = NULL;
3825 break;
3826 }
3827 PyList_SET_ITEM(result, i, o);
3828 }
3829 }
3830 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003831
Fred Drakec9680921999-12-13 16:37:25 +00003832 return result;
3833}
3834#endif
3835
Martin v. Löwis606edc12002-06-13 21:09:11 +00003836#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003837PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003838"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003839Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003840
3841static PyObject *
3842posix_getpgid(PyObject *self, PyObject *args)
3843{
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00003844 pid_t pid, pgid;
3845 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
Martin v. Löwis606edc12002-06-13 21:09:11 +00003846 return NULL;
3847 pgid = getpgid(pid);
3848 if (pgid < 0)
3849 return posix_error();
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00003850 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00003851}
3852#endif /* HAVE_GETPGID */
3853
3854
Guido van Rossumb6775db1994-08-01 11:34:53 +00003855#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003856PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003857"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003858Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003859
Barry Warsaw53699e91996-12-10 23:23:01 +00003860static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003861posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003862{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003863#ifdef GETPGRP_HAVE_ARG
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00003864 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003865#else /* GETPGRP_HAVE_ARG */
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00003866 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003867#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003868}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003869#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003870
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003871
Guido van Rossumb6775db1994-08-01 11:34:53 +00003872#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003873PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003874"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003875Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003876
Barry Warsaw53699e91996-12-10 23:23:01 +00003877static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003878posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003879{
Guido van Rossum64933891994-10-20 21:56:42 +00003880#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003881 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003882#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003883 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003884#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003885 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003886 Py_INCREF(Py_None);
3887 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003888}
3889
Guido van Rossumb6775db1994-08-01 11:34:53 +00003890#endif /* HAVE_SETPGRP */
3891
Guido van Rossumad0ee831995-03-01 10:34:45 +00003892#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003893PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003894"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003895Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003896
Barry Warsaw53699e91996-12-10 23:23:01 +00003897static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003898posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003899{
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00003900 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003901}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003902#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003903
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003904
Fred Drake12c6e2d1999-12-14 21:25:03 +00003905#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003906PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003907"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003908Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003909
3910static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003911posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003912{
Neal Norwitze241ce82003-02-17 18:17:05 +00003913 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003914 char *name;
3915 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003916
Fred Drakea30680b2000-12-06 21:24:28 +00003917 errno = 0;
3918 name = getlogin();
3919 if (name == NULL) {
3920 if (errno)
3921 posix_error();
3922 else
3923 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003924 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003925 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003926 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003927 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003928 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003929
Fred Drake12c6e2d1999-12-14 21:25:03 +00003930 return result;
3931}
3932#endif
3933
Guido van Rossumad0ee831995-03-01 10:34:45 +00003934#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003935PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003936"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003937Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003938
Barry Warsaw53699e91996-12-10 23:23:01 +00003939static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003940posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003941{
Barry Warsaw53699e91996-12-10 23:23:01 +00003942 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003943}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003944#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003945
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003946
Guido van Rossumad0ee831995-03-01 10:34:45 +00003947#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003948PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003949"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003950Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003951
Barry Warsaw53699e91996-12-10 23:23:01 +00003952static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003953posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003954{
Christian Heimesd491d712008-02-01 18:49:26 +00003955 pid_t pid;
3956 int sig;
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00003957 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003958 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003959#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003960 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3961 APIRET rc;
3962 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003963 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003964
3965 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3966 APIRET rc;
3967 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003968 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003969
3970 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003971 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003972#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003973 if (kill(pid, sig) == -1)
3974 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003975#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003976 Py_INCREF(Py_None);
3977 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003978}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003979#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003980
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003981#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003982PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003983"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003984Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003985
3986static PyObject *
3987posix_killpg(PyObject *self, PyObject *args)
3988{
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00003989 int sig;
3990 pid_t pgid;
3991 /* XXX some man pages make the `pgid` parameter an int, others
3992 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
3993 take the same type. Moreover, pid_t is always at least as wide as
3994 int (else compilation of this module fails), which is safe. */
3995 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003996 return NULL;
3997 if (killpg(pgid, sig) == -1)
3998 return posix_error();
3999 Py_INCREF(Py_None);
4000 return Py_None;
4001}
4002#endif
4003
Guido van Rossumc0125471996-06-28 18:55:32 +00004004#ifdef HAVE_PLOCK
4005
4006#ifdef HAVE_SYS_LOCK_H
4007#include <sys/lock.h>
4008#endif
4009
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004010PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004011"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004012Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004013
Barry Warsaw53699e91996-12-10 23:23:01 +00004014static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004015posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004016{
4017 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004018 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00004019 return NULL;
4020 if (plock(op) == -1)
4021 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004022 Py_INCREF(Py_None);
4023 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004024}
4025#endif
4026
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004027
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004028#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004029PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004030"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004031Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004032
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004033#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004034#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004035static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004036async_system(const char *command)
4037{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004038 char errormsg[256], args[1024];
4039 RESULTCODES rcodes;
4040 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004041
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004042 char *shell = getenv("COMSPEC");
4043 if (!shell)
4044 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004045
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004046 /* avoid overflowing the argument buffer */
4047 if (strlen(shell) + 3 + strlen(command) >= 1024)
4048 return ERROR_NOT_ENOUGH_MEMORY
4049
4050 args[0] = '\0';
4051 strcat(args, shell);
4052 strcat(args, "/c ");
4053 strcat(args, command);
4054
4055 /* execute asynchronously, inheriting the environment */
4056 rc = DosExecPgm(errormsg,
4057 sizeof(errormsg),
4058 EXEC_ASYNC,
4059 args,
4060 NULL,
4061 &rcodes,
4062 shell);
4063 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004064}
4065
Guido van Rossumd48f2521997-12-05 22:19:34 +00004066static FILE *
4067popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004068{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004069 int oldfd, tgtfd;
4070 HFILE pipeh[2];
4071 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004072
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004073 /* mode determines which of stdin or stdout is reconnected to
4074 * the pipe to the child
4075 */
4076 if (strchr(mode, 'r') != NULL) {
4077 tgt_fd = 1; /* stdout */
4078 } else if (strchr(mode, 'w')) {
4079 tgt_fd = 0; /* stdin */
4080 } else {
4081 *err = ERROR_INVALID_ACCESS;
4082 return NULL;
4083 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004084
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00004085 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004086 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4087 *err = rc;
4088 return NULL;
4089 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004090
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004091 /* prevent other threads accessing stdio */
4092 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004093
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004094 /* reconnect stdio and execute child */
4095 oldfd = dup(tgtfd);
4096 close(tgtfd);
4097 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4098 DosClose(pipeh[tgtfd]);
4099 rc = async_system(command);
4100 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004101
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004102 /* restore stdio */
4103 dup2(oldfd, tgtfd);
4104 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004105
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004106 /* allow other threads access to stdio */
4107 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004108
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004109 /* if execution of child was successful return file stream */
4110 if (rc == NO_ERROR)
4111 return fdopen(pipeh[1 - tgtfd], mode);
4112 else {
4113 DosClose(pipeh[1 - tgtfd]);
4114 *err = rc;
4115 return NULL;
4116 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004117}
4118
4119static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004120posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004121{
4122 char *name;
4123 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00004124 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004125 FILE *fp;
4126 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004127 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004128 return NULL;
4129 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00004130 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004131 Py_END_ALLOW_THREADS
4132 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004133 return os2_error(err);
4134
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004135 f = PyFile_FromFile(fp, name, mode, fclose);
4136 if (f != NULL)
4137 PyFile_SetBufSize(f, bufsize);
4138 return f;
4139}
4140
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004141#elif defined(PYCC_GCC)
4142
4143/* standard posix version of popen() support */
4144static PyObject *
4145posix_popen(PyObject *self, PyObject *args)
4146{
4147 char *name;
4148 char *mode = "r";
4149 int bufsize = -1;
4150 FILE *fp;
4151 PyObject *f;
4152 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4153 return NULL;
4154 Py_BEGIN_ALLOW_THREADS
4155 fp = popen(name, mode);
4156 Py_END_ALLOW_THREADS
4157 if (fp == NULL)
4158 return posix_error();
4159 f = PyFile_FromFile(fp, name, mode, pclose);
4160 if (f != NULL)
4161 PyFile_SetBufSize(f, bufsize);
4162 return f;
4163}
4164
4165/* fork() under OS/2 has lots'o'warts
4166 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4167 * most of this code is a ripoff of the win32 code, but using the
4168 * capabilities of EMX's C library routines
4169 */
4170
4171/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4172#define POPEN_1 1
4173#define POPEN_2 2
4174#define POPEN_3 3
4175#define POPEN_4 4
4176
4177static PyObject *_PyPopen(char *, int, int, int);
4178static int _PyPclose(FILE *file);
4179
4180/*
4181 * Internal dictionary mapping popen* file pointers to process handles,
4182 * for use when retrieving the process exit code. See _PyPclose() below
4183 * for more information on this dictionary's use.
4184 */
4185static PyObject *_PyPopenProcs = NULL;
4186
4187/* os2emx version of popen2()
4188 *
4189 * The result of this function is a pipe (file) connected to the
4190 * process's stdin, and a pipe connected to the process's stdout.
4191 */
4192
4193static PyObject *
4194os2emx_popen2(PyObject *self, PyObject *args)
4195{
4196 PyObject *f;
4197 int tm=0;
4198
4199 char *cmdstring;
4200 char *mode = "t";
4201 int bufsize = -1;
4202 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4203 return NULL;
4204
4205 if (*mode == 't')
4206 tm = O_TEXT;
4207 else if (*mode != 'b') {
4208 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4209 return NULL;
4210 } else
4211 tm = O_BINARY;
4212
4213 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
4214
4215 return f;
4216}
4217
4218/*
4219 * Variation on os2emx.popen2
4220 *
4221 * The result of this function is 3 pipes - the process's stdin,
4222 * stdout and stderr
4223 */
4224
4225static PyObject *
4226os2emx_popen3(PyObject *self, PyObject *args)
4227{
4228 PyObject *f;
4229 int tm = 0;
4230
4231 char *cmdstring;
4232 char *mode = "t";
4233 int bufsize = -1;
4234 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4235 return NULL;
4236
4237 if (*mode == 't')
4238 tm = O_TEXT;
4239 else if (*mode != 'b') {
4240 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4241 return NULL;
4242 } else
4243 tm = O_BINARY;
4244
4245 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
4246
4247 return f;
4248}
4249
4250/*
4251 * Variation on os2emx.popen2
4252 *
Tim Peters11b23062003-04-23 02:39:17 +00004253 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004254 * and stdout+stderr combined as a single pipe.
4255 */
4256
4257static PyObject *
4258os2emx_popen4(PyObject *self, PyObject *args)
4259{
4260 PyObject *f;
4261 int tm = 0;
4262
4263 char *cmdstring;
4264 char *mode = "t";
4265 int bufsize = -1;
4266 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4267 return NULL;
4268
4269 if (*mode == 't')
4270 tm = O_TEXT;
4271 else if (*mode != 'b') {
4272 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4273 return NULL;
4274 } else
4275 tm = O_BINARY;
4276
4277 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
4278
4279 return f;
4280}
4281
4282/* a couple of structures for convenient handling of multiple
4283 * file handles and pipes
4284 */
4285struct file_ref
4286{
4287 int handle;
4288 int flags;
4289};
4290
4291struct pipe_ref
4292{
4293 int rd;
4294 int wr;
4295};
4296
4297/* The following code is derived from the win32 code */
4298
4299static PyObject *
4300_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4301{
4302 struct file_ref stdio[3];
4303 struct pipe_ref p_fd[3];
4304 FILE *p_s[3];
Christian Heimesd491d712008-02-01 18:49:26 +00004305 int file_count, i, pipe_err;
4306 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004307 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4308 PyObject *f, *p_f[3];
4309
4310 /* file modes for subsequent fdopen's on pipe handles */
4311 if (mode == O_TEXT)
4312 {
4313 rd_mode = "rt";
4314 wr_mode = "wt";
4315 }
4316 else
4317 {
4318 rd_mode = "rb";
4319 wr_mode = "wb";
4320 }
4321
4322 /* prepare shell references */
4323 if ((shell = getenv("EMXSHELL")) == NULL)
4324 if ((shell = getenv("COMSPEC")) == NULL)
4325 {
4326 errno = ENOENT;
4327 return posix_error();
4328 }
4329
4330 sh_name = _getname(shell);
4331 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4332 opt = "/c";
4333 else
4334 opt = "-c";
4335
4336 /* save current stdio fds + their flags, and set not inheritable */
4337 i = pipe_err = 0;
4338 while (pipe_err >= 0 && i < 3)
4339 {
4340 pipe_err = stdio[i].handle = dup(i);
4341 stdio[i].flags = fcntl(i, F_GETFD, 0);
4342 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4343 i++;
4344 }
4345 if (pipe_err < 0)
4346 {
4347 /* didn't get them all saved - clean up and bail out */
4348 int saved_err = errno;
4349 while (i-- > 0)
4350 {
4351 close(stdio[i].handle);
4352 }
4353 errno = saved_err;
4354 return posix_error();
4355 }
4356
4357 /* create pipe ends */
4358 file_count = 2;
4359 if (n == POPEN_3)
4360 file_count = 3;
4361 i = pipe_err = 0;
4362 while ((pipe_err == 0) && (i < file_count))
4363 pipe_err = pipe((int *)&p_fd[i++]);
4364 if (pipe_err < 0)
4365 {
4366 /* didn't get them all made - clean up and bail out */
4367 while (i-- > 0)
4368 {
4369 close(p_fd[i].wr);
4370 close(p_fd[i].rd);
4371 }
4372 errno = EPIPE;
4373 return posix_error();
4374 }
4375
4376 /* change the actual standard IO streams over temporarily,
4377 * making the retained pipe ends non-inheritable
4378 */
4379 pipe_err = 0;
4380
4381 /* - stdin */
4382 if (dup2(p_fd[0].rd, 0) == 0)
4383 {
4384 close(p_fd[0].rd);
4385 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4386 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4387 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4388 {
4389 close(p_fd[0].wr);
4390 pipe_err = -1;
4391 }
4392 }
4393 else
4394 {
4395 pipe_err = -1;
4396 }
4397
4398 /* - stdout */
4399 if (pipe_err == 0)
4400 {
4401 if (dup2(p_fd[1].wr, 1) == 1)
4402 {
4403 close(p_fd[1].wr);
4404 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4405 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4406 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4407 {
4408 close(p_fd[1].rd);
4409 pipe_err = -1;
4410 }
4411 }
4412 else
4413 {
4414 pipe_err = -1;
4415 }
4416 }
4417
4418 /* - stderr, as required */
4419 if (pipe_err == 0)
4420 switch (n)
4421 {
4422 case POPEN_3:
4423 {
4424 if (dup2(p_fd[2].wr, 2) == 2)
4425 {
4426 close(p_fd[2].wr);
4427 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4428 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4429 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4430 {
4431 close(p_fd[2].rd);
4432 pipe_err = -1;
4433 }
4434 }
4435 else
4436 {
4437 pipe_err = -1;
4438 }
4439 break;
4440 }
4441
4442 case POPEN_4:
4443 {
4444 if (dup2(1, 2) != 2)
4445 {
4446 pipe_err = -1;
4447 }
4448 break;
4449 }
4450 }
4451
4452 /* spawn the child process */
4453 if (pipe_err == 0)
4454 {
4455 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4456 if (pipe_pid == -1)
4457 {
4458 pipe_err = -1;
4459 }
4460 else
4461 {
4462 /* save the PID into the FILE structure
4463 * NOTE: this implementation doesn't actually
4464 * take advantage of this, but do it for
4465 * completeness - AIM Apr01
4466 */
4467 for (i = 0; i < file_count; i++)
4468 p_s[i]->_pid = pipe_pid;
4469 }
4470 }
4471
4472 /* reset standard IO to normal */
4473 for (i = 0; i < 3; i++)
4474 {
4475 dup2(stdio[i].handle, i);
4476 fcntl(i, F_SETFD, stdio[i].flags);
4477 close(stdio[i].handle);
4478 }
4479
4480 /* if any remnant problems, clean up and bail out */
4481 if (pipe_err < 0)
4482 {
4483 for (i = 0; i < 3; i++)
4484 {
4485 close(p_fd[i].rd);
4486 close(p_fd[i].wr);
4487 }
4488 errno = EPIPE;
4489 return posix_error_with_filename(cmdstring);
4490 }
4491
4492 /* build tuple of file objects to return */
4493 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4494 PyFile_SetBufSize(p_f[0], bufsize);
4495 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4496 PyFile_SetBufSize(p_f[1], bufsize);
4497 if (n == POPEN_3)
4498 {
4499 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4500 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004501 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004502 }
4503 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004504 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004505
4506 /*
4507 * Insert the files we've created into the process dictionary
4508 * all referencing the list with the process handle and the
4509 * initial number of files (see description below in _PyPclose).
4510 * Since if _PyPclose later tried to wait on a process when all
4511 * handles weren't closed, it could create a deadlock with the
4512 * child, we spend some energy here to try to ensure that we
4513 * either insert all file handles into the dictionary or none
4514 * at all. It's a little clumsy with the various popen modes
4515 * and variable number of files involved.
4516 */
4517 if (!_PyPopenProcs)
4518 {
4519 _PyPopenProcs = PyDict_New();
4520 }
4521
4522 if (_PyPopenProcs)
4523 {
4524 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4525 int ins_rc[3];
4526
4527 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4528 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4529
4530 procObj = PyList_New(2);
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00004531 pidObj = PyLong_FromPid(pipe_pid);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004532 intObj = PyInt_FromLong((long) file_count);
4533
4534 if (procObj && pidObj && intObj)
4535 {
4536 PyList_SetItem(procObj, 0, pidObj);
4537 PyList_SetItem(procObj, 1, intObj);
4538
4539 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4540 if (fileObj[0])
4541 {
4542 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4543 fileObj[0],
4544 procObj);
4545 }
4546 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4547 if (fileObj[1])
4548 {
4549 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4550 fileObj[1],
4551 procObj);
4552 }
4553 if (file_count >= 3)
4554 {
4555 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4556 if (fileObj[2])
4557 {
4558 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4559 fileObj[2],
4560 procObj);
4561 }
4562 }
4563
4564 if (ins_rc[0] < 0 || !fileObj[0] ||
4565 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4566 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4567 {
4568 /* Something failed - remove any dictionary
4569 * entries that did make it.
4570 */
4571 if (!ins_rc[0] && fileObj[0])
4572 {
4573 PyDict_DelItem(_PyPopenProcs,
4574 fileObj[0]);
4575 }
4576 if (!ins_rc[1] && fileObj[1])
4577 {
4578 PyDict_DelItem(_PyPopenProcs,
4579 fileObj[1]);
4580 }
4581 if (!ins_rc[2] && fileObj[2])
4582 {
4583 PyDict_DelItem(_PyPopenProcs,
4584 fileObj[2]);
4585 }
4586 }
4587 }
Tim Peters11b23062003-04-23 02:39:17 +00004588
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004589 /*
4590 * Clean up our localized references for the dictionary keys
4591 * and value since PyDict_SetItem will Py_INCREF any copies
4592 * that got placed in the dictionary.
4593 */
4594 Py_XDECREF(procObj);
4595 Py_XDECREF(fileObj[0]);
4596 Py_XDECREF(fileObj[1]);
4597 Py_XDECREF(fileObj[2]);
4598 }
4599
4600 /* Child is launched. */
4601 return f;
4602}
4603
4604/*
4605 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4606 * exit code for the child process and return as a result of the close.
4607 *
4608 * This function uses the _PyPopenProcs dictionary in order to map the
4609 * input file pointer to information about the process that was
4610 * originally created by the popen* call that created the file pointer.
4611 * The dictionary uses the file pointer as a key (with one entry
4612 * inserted for each file returned by the original popen* call) and a
4613 * single list object as the value for all files from a single call.
4614 * The list object contains the Win32 process handle at [0], and a file
4615 * count at [1], which is initialized to the total number of file
4616 * handles using that list.
4617 *
4618 * This function closes whichever handle it is passed, and decrements
4619 * the file count in the dictionary for the process handle pointed to
4620 * by this file. On the last close (when the file count reaches zero),
4621 * this function will wait for the child process and then return its
4622 * exit code as the result of the close() operation. This permits the
4623 * files to be closed in any order - it is always the close() of the
4624 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004625 *
4626 * NOTE: This function is currently called with the GIL released.
4627 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004628 */
4629
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004630static int _PyPclose(FILE *file)
4631{
4632 int result;
4633 int exit_code;
Christian Heimesd491d712008-02-01 18:49:26 +00004634 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004635 PyObject *procObj, *pidObj, *intObj, *fileObj;
4636 int file_count;
4637#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004638 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004639#endif
4640
4641 /* Close the file handle first, to ensure it can't block the
4642 * child from exiting if it's the last handle.
4643 */
4644 result = fclose(file);
4645
4646#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004647 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004648#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004649 if (_PyPopenProcs)
4650 {
4651 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4652 (procObj = PyDict_GetItem(_PyPopenProcs,
4653 fileObj)) != NULL &&
4654 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4655 (intObj = PyList_GetItem(procObj,1)) != NULL)
4656 {
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00004657 pipe_pid = (pid_t) PyLong_AsPid(pidObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004658 file_count = (int) PyInt_AsLong(intObj);
4659
4660 if (file_count > 1)
4661 {
4662 /* Still other files referencing process */
4663 file_count--;
4664 PyList_SetItem(procObj,1,
4665 PyInt_FromLong((long) file_count));
4666 }
4667 else
4668 {
4669 /* Last file for this process */
4670 if (result != EOF &&
4671 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4672 {
4673 /* extract exit status */
4674 if (WIFEXITED(exit_code))
4675 {
4676 result = WEXITSTATUS(exit_code);
4677 }
4678 else
4679 {
4680 errno = EPIPE;
4681 result = -1;
4682 }
4683 }
4684 else
4685 {
4686 /* Indicate failure - this will cause the file object
4687 * to raise an I/O error and translate the last
4688 * error code from errno. We do have a problem with
4689 * last errors that overlap the normal errno table,
4690 * but that's a consistent problem with the file object.
4691 */
4692 result = -1;
4693 }
4694 }
4695
4696 /* Remove this file pointer from dictionary */
4697 PyDict_DelItem(_PyPopenProcs, fileObj);
4698
4699 if (PyDict_Size(_PyPopenProcs) == 0)
4700 {
4701 Py_DECREF(_PyPopenProcs);
4702 _PyPopenProcs = NULL;
4703 }
4704
4705 } /* if object retrieval ok */
4706
4707 Py_XDECREF(fileObj);
4708 } /* if _PyPopenProcs */
4709
4710#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004711 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004712#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004713 return result;
4714}
4715
4716#endif /* PYCC_??? */
4717
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004718#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004719
4720/*
4721 * Portable 'popen' replacement for Win32.
4722 *
4723 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4724 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004725 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004726 */
4727
4728#include <malloc.h>
4729#include <io.h>
4730#include <fcntl.h>
4731
4732/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4733#define POPEN_1 1
4734#define POPEN_2 2
4735#define POPEN_3 3
4736#define POPEN_4 4
4737
4738static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004739static int _PyPclose(FILE *file);
4740
4741/*
4742 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004743 * for use when retrieving the process exit code. See _PyPclose() below
4744 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004745 */
4746static PyObject *_PyPopenProcs = NULL;
4747
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004748
4749/* popen that works from a GUI.
4750 *
4751 * The result of this function is a pipe (file) connected to the
4752 * processes stdin or stdout, depending on the requested mode.
4753 */
4754
4755static PyObject *
4756posix_popen(PyObject *self, PyObject *args)
4757{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004758 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004759 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004760
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004761 char *cmdstring;
4762 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004763 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004764 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004765 return NULL;
4766
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004767 if (*mode == 'r')
4768 tm = _O_RDONLY;
4769 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004770 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004771 return NULL;
4772 } else
4773 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004774
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004775 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004776 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004777 return NULL;
4778 }
4779
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004780 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004781 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004782 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004783 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004784 else
4785 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4786
4787 return f;
4788}
4789
4790/* Variation on win32pipe.popen
4791 *
4792 * The result of this function is a pipe (file) connected to the
4793 * process's stdin, and a pipe connected to the process's stdout.
4794 */
4795
4796static PyObject *
4797win32_popen2(PyObject *self, PyObject *args)
4798{
4799 PyObject *f;
4800 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004801
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004802 char *cmdstring;
4803 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004804 int bufsize = -1;
4805 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004806 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004807
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004808 if (*mode == 't')
4809 tm = _O_TEXT;
4810 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004811 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004812 return NULL;
4813 } else
4814 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004815
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004816 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004817 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004818 return NULL;
4819 }
4820
4821 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004822
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004823 return f;
4824}
4825
4826/*
4827 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004828 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004829 * The result of this function is 3 pipes - the process's stdin,
4830 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004831 */
4832
4833static PyObject *
4834win32_popen3(PyObject *self, PyObject *args)
4835{
4836 PyObject *f;
4837 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004838
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004839 char *cmdstring;
4840 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004841 int bufsize = -1;
4842 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004843 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004844
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004845 if (*mode == 't')
4846 tm = _O_TEXT;
4847 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004848 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004849 return NULL;
4850 } else
4851 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004852
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004853 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004854 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004855 return NULL;
4856 }
4857
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004858 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004859
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004860 return f;
4861}
4862
4863/*
4864 * Variation on win32pipe.popen
4865 *
Tim Peters5aa91602002-01-30 05:46:57 +00004866 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004867 * and stdout+stderr combined as a single pipe.
4868 */
4869
4870static PyObject *
4871win32_popen4(PyObject *self, PyObject *args)
4872{
4873 PyObject *f;
4874 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004875
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004876 char *cmdstring;
4877 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004878 int bufsize = -1;
4879 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004880 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004881
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004882 if (*mode == 't')
4883 tm = _O_TEXT;
4884 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004885 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004886 return NULL;
4887 } else
4888 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004889
4890 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004891 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004892 return NULL;
4893 }
4894
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004895 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004896
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004897 return f;
4898}
4899
Mark Hammond08501372001-01-31 07:30:29 +00004900static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004901_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004902 HANDLE hStdin,
4903 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004904 HANDLE hStderr,
4905 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004906{
4907 PROCESS_INFORMATION piProcInfo;
4908 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004909 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004910 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004911 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004912 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004913 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004914
4915 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004916 char *comshell;
4917
Tim Peters92e4dd82002-10-05 01:47:34 +00004918 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004919 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004920 /* x < i, so x fits into an integer */
4921 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004922
4923 /* Explicitly check if we are using COMMAND.COM. If we are
4924 * then use the w9xpopen hack.
4925 */
4926 comshell = s1 + x;
4927 while (comshell >= s1 && *comshell != '\\')
4928 --comshell;
4929 ++comshell;
4930
4931 if (GetVersion() < 0x80000000 &&
4932 _stricmp(comshell, "command.com") != 0) {
4933 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004934 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004935 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004936 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004937 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004938 }
4939 else {
4940 /*
Tim Peters402d5982001-08-27 06:37:48 +00004941 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4942 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004943 */
Mark Hammond08501372001-01-31 07:30:29 +00004944 char modulepath[_MAX_PATH];
4945 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004946 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Martin v. Löwis26fd9602006-04-22 11:15:41 +00004947 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004948 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004949 x = i+1;
4950 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004951 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004952 strncat(modulepath,
4953 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004954 (sizeof(modulepath)/sizeof(modulepath[0]))
4955 -strlen(modulepath));
4956 if (stat(modulepath, &statinfo) != 0) {
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00004957 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
Tim Peters5aa91602002-01-30 05:46:57 +00004958 /* Eeek - file-not-found - possibly an embedding
4959 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004960 */
Tim Peters5aa91602002-01-30 05:46:57 +00004961 strncpy(modulepath,
4962 Py_GetExecPrefix(),
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00004963 mplen);
4964 modulepath[mplen-1] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004965 if (modulepath[strlen(modulepath)-1] != '\\')
4966 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004967 strncat(modulepath,
4968 szConsoleSpawn,
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00004969 mplen-strlen(modulepath));
Mark Hammond08501372001-01-31 07:30:29 +00004970 /* No where else to look - raise an easily identifiable
4971 error, rather than leaving Windows to report
4972 "file not found" - as the user is probably blissfully
4973 unaware this shim EXE is used, and it will confuse them.
4974 (well, it confused me for a while ;-)
4975 */
4976 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004977 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004978 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004979 "for popen to work with your shell "
4980 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004981 szConsoleSpawn);
4982 return FALSE;
4983 }
4984 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004985 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004986 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004987 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004988
Tim Peters92e4dd82002-10-05 01:47:34 +00004989 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004990 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004991 /* To maintain correct argument passing semantics,
4992 we pass the command-line as it stands, and allow
4993 quoting to be applied. w9xpopen.exe will then
4994 use its argv vector, and re-quote the necessary
4995 args for the ultimate child process.
4996 */
Tim Peters75cdad52001-11-28 22:07:30 +00004997 PyOS_snprintf(
4998 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004999 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005000 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005001 s1,
5002 s3,
5003 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005004 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00005005 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005006 dialog:
5007 "Your program accessed mem currently in use at xxx"
5008 and a hopeful warning about the stability of your
5009 system.
Mark Dickinson3e4caeb2009-02-21 20:27:01 +00005010 Cost is Ctrl+C won't kill children, but anyone
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005011 who cares can have a go!
5012 */
5013 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005014 }
5015 }
5016
5017 /* Could be an else here to try cmd.exe / command.com in the path
5018 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00005019 else {
Tim Peters402d5982001-08-27 06:37:48 +00005020 PyErr_SetString(PyExc_RuntimeError,
5021 "Cannot locate a COMSPEC environment variable to "
5022 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00005023 return FALSE;
5024 }
Tim Peters5aa91602002-01-30 05:46:57 +00005025
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005026 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5027 siStartInfo.cb = sizeof(STARTUPINFO);
5028 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5029 siStartInfo.hStdInput = hStdin;
5030 siStartInfo.hStdOutput = hStdout;
5031 siStartInfo.hStdError = hStderr;
5032 siStartInfo.wShowWindow = SW_HIDE;
5033
5034 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005035 s2,
5036 NULL,
5037 NULL,
5038 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005039 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005040 NULL,
5041 NULL,
5042 &siStartInfo,
5043 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005044 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005045 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005046
Mark Hammondb37a3732000-08-14 04:47:33 +00005047 /* Return process handle */
5048 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005049 return TRUE;
5050 }
Tim Peters402d5982001-08-27 06:37:48 +00005051 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005052 return FALSE;
5053}
5054
5055/* The following code is based off of KB: Q190351 */
5056
5057static PyObject *
5058_PyPopen(char *cmdstring, int mode, int n)
5059{
5060 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5061 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00005062 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005063
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005064 SECURITY_ATTRIBUTES saAttr;
5065 BOOL fSuccess;
5066 int fd1, fd2, fd3;
5067 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00005068 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005069 PyObject *f;
5070
5071 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5072 saAttr.bInheritHandle = TRUE;
5073 saAttr.lpSecurityDescriptor = NULL;
5074
5075 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5076 return win32_error("CreatePipe", NULL);
5077
5078 /* Create new output read handle and the input write handle. Set
5079 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005080 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005081 * being created. */
5082 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005083 GetCurrentProcess(), &hChildStdinWrDup, 0,
5084 FALSE,
5085 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005086 if (!fSuccess)
5087 return win32_error("DuplicateHandle", NULL);
5088
5089 /* Close the inheritable version of ChildStdin
5090 that we're using. */
5091 CloseHandle(hChildStdinWr);
5092
5093 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5094 return win32_error("CreatePipe", NULL);
5095
5096 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005097 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5098 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005099 if (!fSuccess)
5100 return win32_error("DuplicateHandle", NULL);
5101
5102 /* Close the inheritable version of ChildStdout
5103 that we're using. */
5104 CloseHandle(hChildStdoutRd);
5105
5106 if (n != POPEN_4) {
5107 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5108 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005109 fSuccess = DuplicateHandle(GetCurrentProcess(),
5110 hChildStderrRd,
5111 GetCurrentProcess(),
5112 &hChildStderrRdDup, 0,
5113 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005114 if (!fSuccess)
5115 return win32_error("DuplicateHandle", NULL);
5116 /* Close the inheritable version of ChildStdErr that we're using. */
5117 CloseHandle(hChildStderrRd);
5118 }
Tim Peters5aa91602002-01-30 05:46:57 +00005119
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005120 switch (n) {
5121 case POPEN_1:
5122 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5123 case _O_WRONLY | _O_TEXT:
5124 /* Case for writing to child Stdin in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005125 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005126 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005127 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005128 PyFile_SetBufSize(f, 0);
5129 /* We don't care about these pipes anymore, so close them. */
5130 CloseHandle(hChildStdoutRdDup);
5131 CloseHandle(hChildStderrRdDup);
5132 break;
5133
5134 case _O_RDONLY | _O_TEXT:
5135 /* Case for reading from child Stdout in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005136 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005137 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005138 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005139 PyFile_SetBufSize(f, 0);
5140 /* We don't care about these pipes anymore, so close them. */
5141 CloseHandle(hChildStdinWrDup);
5142 CloseHandle(hChildStderrRdDup);
5143 break;
5144
5145 case _O_RDONLY | _O_BINARY:
5146 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005147 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005148 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005149 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005150 PyFile_SetBufSize(f, 0);
5151 /* We don't care about these pipes anymore, so close them. */
5152 CloseHandle(hChildStdinWrDup);
5153 CloseHandle(hChildStderrRdDup);
5154 break;
5155
5156 case _O_WRONLY | _O_BINARY:
5157 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005158 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005159 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005160 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005161 PyFile_SetBufSize(f, 0);
5162 /* We don't care about these pipes anymore, so close them. */
5163 CloseHandle(hChildStdoutRdDup);
5164 CloseHandle(hChildStderrRdDup);
5165 break;
5166 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005167 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005168 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005169
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005170 case POPEN_2:
5171 case POPEN_4:
5172 {
5173 char *m1, *m2;
5174 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005175
Tim Peters7dca21e2002-08-19 00:42:29 +00005176 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005177 m1 = "r";
5178 m2 = "w";
5179 } else {
5180 m1 = "rb";
5181 m2 = "wb";
5182 }
5183
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005184 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005185 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005186 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005187 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005188 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005189 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00005190 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005191 PyFile_SetBufSize(p2, 0);
5192
5193 if (n != 4)
5194 CloseHandle(hChildStderrRdDup);
5195
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005196 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00005197 Py_XDECREF(p1);
5198 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00005199 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005200 break;
5201 }
Tim Peters5aa91602002-01-30 05:46:57 +00005202
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005203 case POPEN_3:
5204 {
5205 char *m1, *m2;
5206 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005207
Tim Peters7dca21e2002-08-19 00:42:29 +00005208 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005209 m1 = "r";
5210 m2 = "w";
5211 } else {
5212 m1 = "rb";
5213 m2 = "wb";
5214 }
5215
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005216 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005217 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005218 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005219 f2 = _fdopen(fd2, m1);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005220 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005221 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005222 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00005223 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5224 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005225 PyFile_SetBufSize(p1, 0);
5226 PyFile_SetBufSize(p2, 0);
5227 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005228 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00005229 Py_XDECREF(p1);
5230 Py_XDECREF(p2);
5231 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00005232 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005233 break;
5234 }
5235 }
5236
5237 if (n == POPEN_4) {
5238 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005239 hChildStdinRd,
5240 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005241 hChildStdoutWr,
5242 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005243 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005244 }
5245 else {
5246 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005247 hChildStdinRd,
5248 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005249 hChildStderrWr,
5250 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005251 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005252 }
5253
Mark Hammondb37a3732000-08-14 04:47:33 +00005254 /*
5255 * Insert the files we've created into the process dictionary
5256 * all referencing the list with the process handle and the
5257 * initial number of files (see description below in _PyPclose).
5258 * Since if _PyPclose later tried to wait on a process when all
5259 * handles weren't closed, it could create a deadlock with the
5260 * child, we spend some energy here to try to ensure that we
5261 * either insert all file handles into the dictionary or none
5262 * at all. It's a little clumsy with the various popen modes
5263 * and variable number of files involved.
5264 */
5265 if (!_PyPopenProcs) {
5266 _PyPopenProcs = PyDict_New();
5267 }
5268
5269 if (_PyPopenProcs) {
5270 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5271 int ins_rc[3];
5272
5273 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5274 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
5275
5276 procObj = PyList_New(2);
5277 hProcessObj = PyLong_FromVoidPtr(hProcess);
5278 intObj = PyInt_FromLong(file_count);
5279
5280 if (procObj && hProcessObj && intObj) {
5281 PyList_SetItem(procObj,0,hProcessObj);
5282 PyList_SetItem(procObj,1,intObj);
5283
5284 fileObj[0] = PyLong_FromVoidPtr(f1);
5285 if (fileObj[0]) {
5286 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5287 fileObj[0],
5288 procObj);
5289 }
5290 if (file_count >= 2) {
5291 fileObj[1] = PyLong_FromVoidPtr(f2);
5292 if (fileObj[1]) {
5293 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5294 fileObj[1],
5295 procObj);
5296 }
5297 }
5298 if (file_count >= 3) {
5299 fileObj[2] = PyLong_FromVoidPtr(f3);
5300 if (fileObj[2]) {
5301 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5302 fileObj[2],
5303 procObj);
5304 }
5305 }
5306
5307 if (ins_rc[0] < 0 || !fileObj[0] ||
5308 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5309 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5310 /* Something failed - remove any dictionary
5311 * entries that did make it.
5312 */
5313 if (!ins_rc[0] && fileObj[0]) {
5314 PyDict_DelItem(_PyPopenProcs,
5315 fileObj[0]);
5316 }
5317 if (!ins_rc[1] && fileObj[1]) {
5318 PyDict_DelItem(_PyPopenProcs,
5319 fileObj[1]);
5320 }
5321 if (!ins_rc[2] && fileObj[2]) {
5322 PyDict_DelItem(_PyPopenProcs,
5323 fileObj[2]);
5324 }
5325 }
5326 }
Tim Peters5aa91602002-01-30 05:46:57 +00005327
Mark Hammondb37a3732000-08-14 04:47:33 +00005328 /*
5329 * Clean up our localized references for the dictionary keys
5330 * and value since PyDict_SetItem will Py_INCREF any copies
5331 * that got placed in the dictionary.
5332 */
5333 Py_XDECREF(procObj);
5334 Py_XDECREF(fileObj[0]);
5335 Py_XDECREF(fileObj[1]);
5336 Py_XDECREF(fileObj[2]);
5337 }
5338
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005339 /* Child is launched. Close the parents copy of those pipe
5340 * handles that only the child should have open. You need to
5341 * make sure that no handles to the write end of the output pipe
5342 * are maintained in this process or else the pipe will not close
5343 * when the child process exits and the ReadFile will hang. */
5344
5345 if (!CloseHandle(hChildStdinRd))
5346 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005347
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005348 if (!CloseHandle(hChildStdoutWr))
5349 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005350
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005351 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5352 return win32_error("CloseHandle", NULL);
5353
5354 return f;
5355}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005356
5357/*
5358 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5359 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005360 *
5361 * This function uses the _PyPopenProcs dictionary in order to map the
5362 * input file pointer to information about the process that was
5363 * originally created by the popen* call that created the file pointer.
5364 * The dictionary uses the file pointer as a key (with one entry
5365 * inserted for each file returned by the original popen* call) and a
5366 * single list object as the value for all files from a single call.
5367 * The list object contains the Win32 process handle at [0], and a file
5368 * count at [1], which is initialized to the total number of file
5369 * handles using that list.
5370 *
5371 * This function closes whichever handle it is passed, and decrements
5372 * the file count in the dictionary for the process handle pointed to
5373 * by this file. On the last close (when the file count reaches zero),
5374 * this function will wait for the child process and then return its
5375 * exit code as the result of the close() operation. This permits the
5376 * files to be closed in any order - it is always the close() of the
5377 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005378 *
5379 * NOTE: This function is currently called with the GIL released.
5380 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005381 */
Tim Peters736aa322000-09-01 06:51:24 +00005382
Fredrik Lundh56055a42000-07-23 19:47:12 +00005383static int _PyPclose(FILE *file)
5384{
Fredrik Lundh20318932000-07-26 17:29:12 +00005385 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005386 DWORD exit_code;
5387 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00005388 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5389 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005390#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005391 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005392#endif
5393
Fredrik Lundh20318932000-07-26 17:29:12 +00005394 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00005395 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00005396 */
5397 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005398#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005399 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005400#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005401 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005402 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5403 (procObj = PyDict_GetItem(_PyPopenProcs,
5404 fileObj)) != NULL &&
5405 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5406 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5407
5408 hProcess = PyLong_AsVoidPtr(hProcessObj);
5409 file_count = PyInt_AsLong(intObj);
5410
5411 if (file_count > 1) {
5412 /* Still other files referencing process */
5413 file_count--;
5414 PyList_SetItem(procObj,1,
5415 PyInt_FromLong(file_count));
5416 } else {
5417 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00005418 if (result != EOF &&
5419 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5420 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00005421 /* Possible truncation here in 16-bit environments, but
5422 * real exit codes are just the lower byte in any event.
5423 */
5424 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005425 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00005426 /* Indicate failure - this will cause the file object
5427 * to raise an I/O error and translate the last Win32
5428 * error code from errno. We do have a problem with
5429 * last errors that overlap the normal errno table,
5430 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005431 */
Fredrik Lundh20318932000-07-26 17:29:12 +00005432 if (result != EOF) {
5433 /* If the error wasn't from the fclose(), then
5434 * set errno for the file object error handling.
5435 */
5436 errno = GetLastError();
5437 }
5438 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005439 }
5440
5441 /* Free up the native handle at this point */
5442 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00005443 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005444
Mark Hammondb37a3732000-08-14 04:47:33 +00005445 /* Remove this file pointer from dictionary */
5446 PyDict_DelItem(_PyPopenProcs, fileObj);
5447
5448 if (PyDict_Size(_PyPopenProcs) == 0) {
5449 Py_DECREF(_PyPopenProcs);
5450 _PyPopenProcs = NULL;
5451 }
5452
5453 } /* if object retrieval ok */
5454
5455 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005456 } /* if _PyPopenProcs */
5457
Tim Peters736aa322000-09-01 06:51:24 +00005458#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005459 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005460#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005461 return result;
5462}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005463
5464#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005465static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005466posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005467{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005468 char *name;
5469 char *mode = "r";
5470 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00005471 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005472 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005473 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00005474 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00005475 /* Strip mode of binary or text modifiers */
5476 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5477 mode = "r";
5478 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5479 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00005480 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005481 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005482 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00005483 if (fp == NULL)
5484 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005485 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005486 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005487 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005488 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005489}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005490
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005491#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005492#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005493
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005494
Guido van Rossumb6775db1994-08-01 11:34:53 +00005495#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005496PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005497"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005498Set the current process's user id.");
5499
Barry Warsaw53699e91996-12-10 23:23:01 +00005500static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005501posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005502{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005503 long uid_arg;
5504 uid_t uid;
5505 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005506 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005507 uid = uid_arg;
5508 if (uid != uid_arg) {
5509 PyErr_SetString(PyExc_OverflowError, "user id too big");
5510 return NULL;
5511 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005512 if (setuid(uid) < 0)
5513 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005514 Py_INCREF(Py_None);
5515 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005516}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005517#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005518
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005519
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005520#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005521PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005522"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005523Set the current process's effective user id.");
5524
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005525static PyObject *
5526posix_seteuid (PyObject *self, PyObject *args)
5527{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005528 long euid_arg;
5529 uid_t euid;
5530 if (!PyArg_ParseTuple(args, "l", &euid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005531 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005532 euid = euid_arg;
5533 if (euid != euid_arg) {
5534 PyErr_SetString(PyExc_OverflowError, "user id too big");
5535 return NULL;
5536 }
5537 if (seteuid(euid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005538 return posix_error();
5539 } else {
5540 Py_INCREF(Py_None);
5541 return Py_None;
5542 }
5543}
5544#endif /* HAVE_SETEUID */
5545
5546#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005547PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005548"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005549Set the current process's effective group id.");
5550
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005551static PyObject *
5552posix_setegid (PyObject *self, PyObject *args)
5553{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005554 long egid_arg;
5555 gid_t egid;
5556 if (!PyArg_ParseTuple(args, "l", &egid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005557 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005558 egid = egid_arg;
5559 if (egid != egid_arg) {
5560 PyErr_SetString(PyExc_OverflowError, "group id too big");
5561 return NULL;
5562 }
5563 if (setegid(egid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005564 return posix_error();
5565 } else {
5566 Py_INCREF(Py_None);
5567 return Py_None;
5568 }
5569}
5570#endif /* HAVE_SETEGID */
5571
5572#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005573PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005574"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005575Set the current process's real and effective user ids.");
5576
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005577static PyObject *
5578posix_setreuid (PyObject *self, PyObject *args)
5579{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005580 long ruid_arg, euid_arg;
5581 uid_t ruid, euid;
5582 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005583 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005584 ruid = ruid_arg;
5585 euid = euid_arg;
5586 if (euid != euid_arg || ruid != ruid_arg) {
5587 PyErr_SetString(PyExc_OverflowError, "user id too big");
5588 return NULL;
5589 }
5590 if (setreuid(ruid, euid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005591 return posix_error();
5592 } else {
5593 Py_INCREF(Py_None);
5594 return Py_None;
5595 }
5596}
5597#endif /* HAVE_SETREUID */
5598
5599#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005600PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005601"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005602Set the current process's real and effective group ids.");
5603
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005604static PyObject *
5605posix_setregid (PyObject *self, PyObject *args)
5606{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005607 long rgid_arg, egid_arg;
5608 gid_t rgid, egid;
5609 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005610 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005611 rgid = rgid_arg;
5612 egid = egid_arg;
5613 if (egid != egid_arg || rgid != rgid_arg) {
5614 PyErr_SetString(PyExc_OverflowError, "group id too big");
5615 return NULL;
5616 }
5617 if (setregid(rgid, egid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005618 return posix_error();
5619 } else {
5620 Py_INCREF(Py_None);
5621 return Py_None;
5622 }
5623}
5624#endif /* HAVE_SETREGID */
5625
Guido van Rossumb6775db1994-08-01 11:34:53 +00005626#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005627PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005628"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005629Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005630
Barry Warsaw53699e91996-12-10 23:23:01 +00005631static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005632posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005633{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005634 long gid_arg;
5635 gid_t gid;
5636 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005637 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005638 gid = gid_arg;
5639 if (gid != gid_arg) {
5640 PyErr_SetString(PyExc_OverflowError, "group id too big");
5641 return NULL;
5642 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005643 if (setgid(gid) < 0)
5644 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005645 Py_INCREF(Py_None);
5646 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005647}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005648#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005649
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005650#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005651PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005652"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005653Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005654
5655static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005656posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005657{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005658 int i, len;
5659 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005660
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005661 if (!PySequence_Check(groups)) {
5662 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5663 return NULL;
5664 }
5665 len = PySequence_Size(groups);
5666 if (len > MAX_GROUPS) {
5667 PyErr_SetString(PyExc_ValueError, "too many groups");
5668 return NULL;
5669 }
5670 for(i = 0; i < len; i++) {
5671 PyObject *elem;
5672 elem = PySequence_GetItem(groups, i);
5673 if (!elem)
5674 return NULL;
5675 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005676 if (!PyLong_Check(elem)) {
5677 PyErr_SetString(PyExc_TypeError,
5678 "groups must be integers");
5679 Py_DECREF(elem);
5680 return NULL;
5681 } else {
5682 unsigned long x = PyLong_AsUnsignedLong(elem);
5683 if (PyErr_Occurred()) {
5684 PyErr_SetString(PyExc_TypeError,
5685 "group id too big");
5686 Py_DECREF(elem);
5687 return NULL;
5688 }
5689 grouplist[i] = x;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005690 /* read back to see if it fits in gid_t */
Georg Brandla13c2442005-11-22 19:30:31 +00005691 if (grouplist[i] != x) {
5692 PyErr_SetString(PyExc_TypeError,
5693 "group id too big");
5694 Py_DECREF(elem);
5695 return NULL;
5696 }
5697 }
5698 } else {
5699 long x = PyInt_AsLong(elem);
5700 grouplist[i] = x;
5701 if (grouplist[i] != x) {
5702 PyErr_SetString(PyExc_TypeError,
5703 "group id too big");
5704 Py_DECREF(elem);
5705 return NULL;
5706 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005707 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005708 Py_DECREF(elem);
5709 }
5710
5711 if (setgroups(len, grouplist) < 0)
5712 return posix_error();
5713 Py_INCREF(Py_None);
5714 return Py_None;
5715}
5716#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005717
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005718#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005719static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00005720wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00005721{
5722 PyObject *result;
5723 static PyObject *struct_rusage;
5724
5725 if (pid == -1)
5726 return posix_error();
5727
5728 if (struct_rusage == NULL) {
Christian Heimes000a0742008-01-03 22:16:32 +00005729 PyObject *m = PyImport_ImportModuleNoBlock("resource");
Neal Norwitz05a45592006-03-20 06:30:08 +00005730 if (m == NULL)
5731 return NULL;
5732 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5733 Py_DECREF(m);
5734 if (struct_rusage == NULL)
5735 return NULL;
5736 }
5737
5738 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5739 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5740 if (!result)
5741 return NULL;
5742
5743#ifndef doubletime
5744#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5745#endif
5746
5747 PyStructSequence_SET_ITEM(result, 0,
5748 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5749 PyStructSequence_SET_ITEM(result, 1,
5750 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5751#define SET_INT(result, index, value)\
5752 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5753 SET_INT(result, 2, ru->ru_maxrss);
5754 SET_INT(result, 3, ru->ru_ixrss);
5755 SET_INT(result, 4, ru->ru_idrss);
5756 SET_INT(result, 5, ru->ru_isrss);
5757 SET_INT(result, 6, ru->ru_minflt);
5758 SET_INT(result, 7, ru->ru_majflt);
5759 SET_INT(result, 8, ru->ru_nswap);
5760 SET_INT(result, 9, ru->ru_inblock);
5761 SET_INT(result, 10, ru->ru_oublock);
5762 SET_INT(result, 11, ru->ru_msgsnd);
5763 SET_INT(result, 12, ru->ru_msgrcv);
5764 SET_INT(result, 13, ru->ru_nsignals);
5765 SET_INT(result, 14, ru->ru_nvcsw);
5766 SET_INT(result, 15, ru->ru_nivcsw);
5767#undef SET_INT
5768
5769 if (PyErr_Occurred()) {
5770 Py_DECREF(result);
5771 return NULL;
5772 }
5773
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005774 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005775}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005776#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005777
5778#ifdef HAVE_WAIT3
5779PyDoc_STRVAR(posix_wait3__doc__,
5780"wait3(options) -> (pid, status, rusage)\n\n\
5781Wait for completion of a child process.");
5782
5783static PyObject *
5784posix_wait3(PyObject *self, PyObject *args)
5785{
Christian Heimesd491d712008-02-01 18:49:26 +00005786 pid_t pid;
5787 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005788 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005789 WAIT_TYPE status;
5790 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005791
5792 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5793 return NULL;
5794
5795 Py_BEGIN_ALLOW_THREADS
5796 pid = wait3(&status, options, &ru);
5797 Py_END_ALLOW_THREADS
5798
Neal Norwitzd5a37542006-03-20 06:48:34 +00005799 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005800}
5801#endif /* HAVE_WAIT3 */
5802
5803#ifdef HAVE_WAIT4
5804PyDoc_STRVAR(posix_wait4__doc__,
5805"wait4(pid, options) -> (pid, status, rusage)\n\n\
5806Wait for completion of a given child process.");
5807
5808static PyObject *
5809posix_wait4(PyObject *self, PyObject *args)
5810{
Christian Heimesd491d712008-02-01 18:49:26 +00005811 pid_t pid;
5812 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005813 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005814 WAIT_TYPE status;
5815 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005816
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005817 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
Neal Norwitz05a45592006-03-20 06:30:08 +00005818 return NULL;
5819
5820 Py_BEGIN_ALLOW_THREADS
5821 pid = wait4(pid, &status, options, &ru);
5822 Py_END_ALLOW_THREADS
5823
Neal Norwitzd5a37542006-03-20 06:48:34 +00005824 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005825}
5826#endif /* HAVE_WAIT4 */
5827
Guido van Rossumb6775db1994-08-01 11:34:53 +00005828#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005829PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005830"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005831Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005832
Barry Warsaw53699e91996-12-10 23:23:01 +00005833static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005834posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005835{
Christian Heimesd491d712008-02-01 18:49:26 +00005836 pid_t pid;
5837 int options;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005838 WAIT_TYPE status;
5839 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005840
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005841 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005842 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005843 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005844 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005845 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005846 if (pid == -1)
5847 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005848
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005849 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005850}
5851
Tim Petersab034fa2002-02-01 11:27:43 +00005852#elif defined(HAVE_CWAIT)
5853
5854/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005855PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005856"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005857"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005858
5859static PyObject *
5860posix_waitpid(PyObject *self, PyObject *args)
5861{
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005862 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005863 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005864
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005865 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
Tim Petersab034fa2002-02-01 11:27:43 +00005866 return NULL;
5867 Py_BEGIN_ALLOW_THREADS
5868 pid = _cwait(&status, pid, options);
5869 Py_END_ALLOW_THREADS
5870 if (pid == -1)
5871 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005872
5873 /* shift the status left a byte so this is more like the POSIX waitpid */
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005874 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005875}
5876#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005877
Guido van Rossumad0ee831995-03-01 10:34:45 +00005878#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005879PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005880"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005881Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005882
Barry Warsaw53699e91996-12-10 23:23:01 +00005883static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005884posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005885{
Christian Heimesd491d712008-02-01 18:49:26 +00005886 pid_t pid;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005887 WAIT_TYPE status;
5888 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005889
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005890 Py_BEGIN_ALLOW_THREADS
5891 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005892 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005893 if (pid == -1)
5894 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005895
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00005896 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005897}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005898#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005899
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005900
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005901PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005902"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005903Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005904
Barry Warsaw53699e91996-12-10 23:23:01 +00005905static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005906posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005907{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005908#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005909 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005910#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005911#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005912 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005913#else
5914 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5915#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005916#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005917}
5918
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005919
Guido van Rossumb6775db1994-08-01 11:34:53 +00005920#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005921PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005922"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005923Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005924
Barry Warsaw53699e91996-12-10 23:23:01 +00005925static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005926posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005927{
Ronald Oussoren10168f22006-10-22 10:45:18 +00005928 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005929 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005930 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005931 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00005932#ifdef Py_USING_UNICODE
5933 int arg_is_unicode = 0;
5934#endif
5935
5936 if (!PyArg_ParseTuple(args, "et:readlink",
5937 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005938 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00005939#ifdef Py_USING_UNICODE
5940 v = PySequence_GetItem(args, 0);
Neal Norwitz91a57212007-08-12 17:11:13 +00005941 if (v == NULL) {
5942 PyMem_Free(path);
5943 return NULL;
5944 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00005945
5946 if (PyUnicode_Check(v)) {
5947 arg_is_unicode = 1;
5948 }
5949 Py_DECREF(v);
5950#endif
5951
Barry Warsaw53699e91996-12-10 23:23:01 +00005952 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005953 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005954 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005955 if (n < 0)
Neal Norwitz91a57212007-08-12 17:11:13 +00005956 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00005957
Neal Norwitz91a57212007-08-12 17:11:13 +00005958 PyMem_Free(path);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00005959 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00005960#ifdef Py_USING_UNICODE
5961 if (arg_is_unicode) {
5962 PyObject *w;
5963
5964 w = PyUnicode_FromEncodedObject(v,
5965 Py_FileSystemDefaultEncoding,
5966 "strict");
5967 if (w != NULL) {
5968 Py_DECREF(v);
5969 v = w;
5970 }
5971 else {
5972 /* fall back to the original byte string, as
5973 discussed in patch #683592 */
5974 PyErr_Clear();
5975 }
5976 }
5977#endif
5978 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005979}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005980#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005981
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005982
Guido van Rossumb6775db1994-08-01 11:34:53 +00005983#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005984PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005985"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005986Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005987
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005988static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005989posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005990{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00005991 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005992}
5993#endif /* HAVE_SYMLINK */
5994
5995
5996#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00005997#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5998static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005999system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006000{
6001 ULONG value = 0;
6002
6003 Py_BEGIN_ALLOW_THREADS
6004 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6005 Py_END_ALLOW_THREADS
6006
6007 return value;
6008}
6009
6010static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006011posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006012{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006013 /* Currently Only Uptime is Provided -- Others Later */
6014 return Py_BuildValue("ddddd",
6015 (double)0 /* t.tms_utime / HZ */,
6016 (double)0 /* t.tms_stime / HZ */,
6017 (double)0 /* t.tms_cutime / HZ */,
6018 (double)0 /* t.tms_cstime / HZ */,
6019 (double)system_uptime() / 1000);
6020}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006021#else /* not OS2 */
Martin v. Löwis03824e42008-12-29 18:17:34 +00006022#define NEED_TICKS_PER_SECOND
6023static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006024static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006025posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006026{
6027 struct tms t;
6028 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00006029 errno = 0;
6030 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00006031 if (c == (clock_t) -1)
6032 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006033 return Py_BuildValue("ddddd",
Martin v. Löwis03824e42008-12-29 18:17:34 +00006034 (double)t.tms_utime / ticks_per_second,
6035 (double)t.tms_stime / ticks_per_second,
6036 (double)t.tms_cutime / ticks_per_second,
6037 (double)t.tms_cstime / ticks_per_second,
6038 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006039}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006040#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006041#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006042
6043
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006044#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006045#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006046static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006047posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006048{
6049 FILETIME create, exit, kernel, user;
6050 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006051 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006052 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6053 /* The fields of a FILETIME structure are the hi and lo part
6054 of a 64-bit value expressed in 100 nanosecond units.
6055 1e7 is one second in such units; 1e-7 the inverse.
6056 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6057 */
Barry Warsaw53699e91996-12-10 23:23:01 +00006058 return Py_BuildValue(
6059 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006060 (double)(user.dwHighDateTime*429.4967296 +
6061 user.dwLowDateTime*1e-7),
Georg Brandl0a40ffb2008-02-13 07:20:22 +00006062 (double)(kernel.dwHighDateTime*429.4967296 +
6063 kernel.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00006064 (double)0,
6065 (double)0,
6066 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006067}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006068#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006069
6070#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006071PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006072"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006073Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006074#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006075
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006076
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006077#ifdef HAVE_GETSID
6078PyDoc_STRVAR(posix_getsid__doc__,
6079"getsid(pid) -> sid\n\n\
6080Call the system call getsid().");
6081
6082static PyObject *
6083posix_getsid(PyObject *self, PyObject *args)
6084{
Christian Heimesd491d712008-02-01 18:49:26 +00006085 pid_t pid;
6086 int sid;
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00006087 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006088 return NULL;
6089 sid = getsid(pid);
6090 if (sid < 0)
6091 return posix_error();
6092 return PyInt_FromLong((long)sid);
6093}
6094#endif /* HAVE_GETSID */
6095
6096
Guido van Rossumb6775db1994-08-01 11:34:53 +00006097#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006098PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006099"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006100Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006101
Barry Warsaw53699e91996-12-10 23:23:01 +00006102static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006103posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006104{
Guido van Rossum687dd131993-05-17 08:34:16 +00006105 if (setsid() < 0)
6106 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006107 Py_INCREF(Py_None);
6108 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006109}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006110#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006111
Guido van Rossumb6775db1994-08-01 11:34:53 +00006112#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006113PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006114"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006115Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006116
Barry Warsaw53699e91996-12-10 23:23:01 +00006117static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006118posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006119{
Christian Heimesd491d712008-02-01 18:49:26 +00006120 pid_t pid;
6121 int pgrp;
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00006122 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00006123 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006124 if (setpgid(pid, pgrp) < 0)
6125 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006126 Py_INCREF(Py_None);
6127 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006128}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006129#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006130
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006131
Guido van Rossumb6775db1994-08-01 11:34:53 +00006132#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006133PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006134"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006135Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006136
Barry Warsaw53699e91996-12-10 23:23:01 +00006137static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006138posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006139{
Christian Heimese6a80742008-02-03 19:51:13 +00006140 int fd;
6141 pid_t pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006142 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006143 return NULL;
6144 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006145 if (pgid < 0)
6146 return posix_error();
Antoine Pitrou5e858fe2009-05-23 15:37:45 +00006147 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006148}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006149#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006150
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006151
Guido van Rossumb6775db1994-08-01 11:34:53 +00006152#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006153PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006154"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006155Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006156
Barry Warsaw53699e91996-12-10 23:23:01 +00006157static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006158posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006159{
Antoine Pitrou76dd2d12009-05-23 16:06:49 +00006160 int fd;
6161 pid_t pgid;
6162 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006163 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006164 if (tcsetpgrp(fd, pgid) < 0)
6165 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00006166 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00006167 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006168}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006169#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006170
Guido van Rossum687dd131993-05-17 08:34:16 +00006171/* Functions acting on file descriptors */
6172
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006173PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006174"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006175Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006176
Barry Warsaw53699e91996-12-10 23:23:01 +00006177static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006178posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006179{
Mark Hammondef8b6542001-05-13 08:04:26 +00006180 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006181 int flag;
6182 int mode = 0777;
6183 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006184
6185#ifdef MS_WINDOWS
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00006186 PyUnicodeObject *po;
6187 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6188 Py_BEGIN_ALLOW_THREADS
6189 /* PyUnicode_AS_UNICODE OK without thread
6190 lock as it is a simple dereference. */
6191 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6192 Py_END_ALLOW_THREADS
6193 if (fd < 0)
6194 return posix_error();
6195 return PyInt_FromLong((long)fd);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006196 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00006197 /* Drop the argument parsing error as narrow strings
6198 are also valid. */
6199 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006200#endif
6201
Tim Peters5aa91602002-01-30 05:46:57 +00006202 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00006203 Py_FileSystemDefaultEncoding, &file,
6204 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00006205 return NULL;
6206
Barry Warsaw53699e91996-12-10 23:23:01 +00006207 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006208 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00006209 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006210 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00006211 return posix_error_with_allocated_filename(file);
6212 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00006213 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006214}
6215
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006216
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006217PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006218"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006219Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006220
Barry Warsaw53699e91996-12-10 23:23:01 +00006221static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006222posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006223{
6224 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006225 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006226 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006227 if (!_PyVerify_fd(fd))
6228 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006229 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006230 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006231 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006232 if (res < 0)
6233 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006234 Py_INCREF(Py_None);
6235 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006236}
6237
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006238
Georg Brandl309501a2008-01-19 20:22:13 +00006239PyDoc_STRVAR(posix_closerange__doc__,
6240"closerange(fd_low, fd_high)\n\n\
6241Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6242
6243static PyObject *
6244posix_closerange(PyObject *self, PyObject *args)
6245{
6246 int fd_from, fd_to, i;
6247 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6248 return NULL;
6249 Py_BEGIN_ALLOW_THREADS
6250 for (i = fd_from; i < fd_to; i++)
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006251 if (_PyVerify_fd(i))
6252 close(i);
Georg Brandl309501a2008-01-19 20:22:13 +00006253 Py_END_ALLOW_THREADS
6254 Py_RETURN_NONE;
6255}
6256
6257
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006258PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006259"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006260Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006261
Barry Warsaw53699e91996-12-10 23:23:01 +00006262static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006263posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006264{
6265 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006266 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006267 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006268 if (!_PyVerify_fd(fd))
6269 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006270 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006271 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006272 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006273 if (fd < 0)
6274 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006275 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006276}
6277
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006278
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006279PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006280"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006281Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006282
Barry Warsaw53699e91996-12-10 23:23:01 +00006283static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006284posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006285{
6286 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006287 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00006288 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006289 if (!_PyVerify_fd_dup2(fd, fd2))
6290 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006291 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006292 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00006293 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006294 if (res < 0)
6295 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006296 Py_INCREF(Py_None);
6297 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006298}
6299
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006300
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006301PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006302"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006303Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006304
Barry Warsaw53699e91996-12-10 23:23:01 +00006305static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006306posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006307{
6308 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006309#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006310 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006311#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00006312 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006313#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006314 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006315 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00006316 return NULL;
6317#ifdef SEEK_SET
6318 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6319 switch (how) {
6320 case 0: how = SEEK_SET; break;
6321 case 1: how = SEEK_CUR; break;
6322 case 2: how = SEEK_END; break;
6323 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006324#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006325
6326#if !defined(HAVE_LARGEFILE_SUPPORT)
6327 pos = PyInt_AsLong(posobj);
6328#else
6329 pos = PyLong_Check(posobj) ?
6330 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
6331#endif
6332 if (PyErr_Occurred())
6333 return NULL;
6334
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006335 if (!_PyVerify_fd(fd))
6336 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006337 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006338#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00006339 res = _lseeki64(fd, pos, how);
6340#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006341 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006342#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006343 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006344 if (res < 0)
6345 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006346
6347#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00006348 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006349#else
6350 return PyLong_FromLongLong(res);
6351#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006352}
6353
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006354
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006355PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006356"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006357Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006358
Barry Warsaw53699e91996-12-10 23:23:01 +00006359static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006360posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006361{
Guido van Rossum8bac5461996-06-11 18:38:48 +00006362 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00006363 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006364 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00006365 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00006366 if (size < 0) {
6367 errno = EINVAL;
6368 return posix_error();
6369 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006370 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006371 if (buffer == NULL)
6372 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006373 if (!_PyVerify_fd(fd))
6374 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006375 Py_BEGIN_ALLOW_THREADS
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006376 n = read(fd, PyString_AsString(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00006377 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00006378 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006379 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00006380 return posix_error();
6381 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00006382 if (n != size)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006383 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00006384 return buffer;
6385}
6386
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006387
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006388PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006389"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006390Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006391
Barry Warsaw53699e91996-12-10 23:23:01 +00006392static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006393posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006394{
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006395 Py_buffer pbuf;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006396 int fd;
6397 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006398
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006399 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
Guido van Rossum687dd131993-05-17 08:34:16 +00006400 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006401 if (!_PyVerify_fd(fd))
6402 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006403 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006404 size = write(fd, pbuf.buf, (size_t)pbuf.len);
Barry Warsaw53699e91996-12-10 23:23:01 +00006405 Py_END_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006406 PyBuffer_Release(&pbuf);
Guido van Rossum687dd131993-05-17 08:34:16 +00006407 if (size < 0)
6408 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006409 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006410}
6411
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006412
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006413PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006414"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006415Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006416
Barry Warsaw53699e91996-12-10 23:23:01 +00006417static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006418posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006419{
6420 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00006421 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00006422 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006423 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006424 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006425#ifdef __VMS
6426 /* on OpenVMS we must ensure that all bytes are written to the file */
6427 fsync(fd);
6428#endif
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
Fred Drake699f3522000-06-29 21:12:41 +00006432 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00006433 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00006434 if (res != 0) {
6435#ifdef MS_WINDOWS
6436 return win32_error("fstat", NULL);
6437#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006438 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006439#endif
6440 }
Tim Peters5aa91602002-01-30 05:46:57 +00006441
Martin v. Löwis14694662006-02-03 12:54:16 +00006442 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006443}
6444
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006445
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006446PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006447"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006448Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006449
Barry Warsaw53699e91996-12-10 23:23:01 +00006450static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006451posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006452{
Guido van Rossum687dd131993-05-17 08:34:16 +00006453 int fd;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006454 char *orgmode = "r";
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006455 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00006456 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00006457 PyObject *f;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006458 char *mode;
6459 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00006460 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006461
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006462 /* Sanitize mode. See fileobject.c */
6463 mode = PyMem_MALLOC(strlen(orgmode)+3);
6464 if (!mode) {
6465 PyErr_NoMemory();
6466 return NULL;
6467 }
6468 strcpy(mode, orgmode);
6469 if (_PyFile_SanitizeMode(mode)) {
6470 PyMem_FREE(mode);
Thomas Heller1f043e22002-11-07 16:00:59 +00006471 return NULL;
6472 }
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006473 if (!_PyVerify_fd(fd))
6474 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006475 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006476#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Georg Brandl54a188a2006-03-31 20:00:11 +00006477 if (mode[0] == 'a') {
6478 /* try to make sure the O_APPEND flag is set */
6479 int flags;
6480 flags = fcntl(fd, F_GETFL);
6481 if (flags != -1)
6482 fcntl(fd, F_SETFL, flags | O_APPEND);
6483 fp = fdopen(fd, mode);
Thomas Wouters2a9a6b02006-03-31 22:38:19 +00006484 if (fp == NULL && flags != -1)
Georg Brandl54a188a2006-03-31 20:00:11 +00006485 /* restore old mode if fdopen failed */
6486 fcntl(fd, F_SETFL, flags);
6487 } else {
6488 fp = fdopen(fd, mode);
6489 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006490#else
6491 fp = fdopen(fd, mode);
6492#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006493 Py_END_ALLOW_THREADS
Neal Norwitzd83eb312007-05-02 04:47:55 +00006494 PyMem_FREE(mode);
Guido van Rossum687dd131993-05-17 08:34:16 +00006495 if (fp == NULL)
6496 return posix_error();
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006497 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006498 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00006499 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006500 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006501}
6502
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006503PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006504"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006505Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006506connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006507
6508static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006509posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006510{
6511 int fd;
6512 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6513 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006514 if (!_PyVerify_fd(fd))
6515 return PyBool_FromLong(0);
Fred Drake106c1a02002-04-23 15:58:02 +00006516 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006517}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006518
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006519#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006520PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006521"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006522Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006523
Barry Warsaw53699e91996-12-10 23:23:01 +00006524static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006525posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006526{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006527#if defined(PYOS_OS2)
6528 HFILE read, write;
6529 APIRET rc;
6530
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006531 Py_BEGIN_ALLOW_THREADS
6532 rc = DosCreatePipe( &read, &write, 4096);
6533 Py_END_ALLOW_THREADS
6534 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006535 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006536
6537 return Py_BuildValue("(ii)", read, write);
6538#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006539#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00006540 int fds[2];
6541 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00006542 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006543 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00006544 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006545 if (res != 0)
6546 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006547 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006548#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00006549 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006550 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00006551 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00006552 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006553 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00006554 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00006555 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006556 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00006557 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6558 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006559 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006560#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006561#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006562}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006563#endif /* HAVE_PIPE */
6564
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006565
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006566#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006567PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006568"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006569Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006570
Barry Warsaw53699e91996-12-10 23:23:01 +00006571static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006572posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006573{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006574 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006575 int mode = 0666;
6576 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006577 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006578 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006579 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006580 res = mkfifo(filename, mode);
6581 Py_END_ALLOW_THREADS
6582 if (res < 0)
6583 return posix_error();
6584 Py_INCREF(Py_None);
6585 return Py_None;
6586}
6587#endif
6588
6589
Neal Norwitz11690112002-07-30 01:08:28 +00006590#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006591PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006592"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006593Create a filesystem node (file, device special file or named pipe)\n\
6594named filename. mode specifies both the permissions to use and the\n\
6595type of node to be created, being combined (bitwise OR) with one of\n\
6596S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006597device defines the newly created device special file (probably using\n\
6598os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006599
6600
6601static PyObject *
6602posix_mknod(PyObject *self, PyObject *args)
6603{
6604 char *filename;
6605 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006606 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006607 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00006608 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006609 return NULL;
6610 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006611 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00006612 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006613 if (res < 0)
6614 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006615 Py_INCREF(Py_None);
6616 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006617}
6618#endif
6619
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006620#ifdef HAVE_DEVICE_MACROS
6621PyDoc_STRVAR(posix_major__doc__,
6622"major(device) -> major number\n\
6623Extracts a device major number from a raw device number.");
6624
6625static PyObject *
6626posix_major(PyObject *self, PyObject *args)
6627{
6628 int device;
6629 if (!PyArg_ParseTuple(args, "i:major", &device))
6630 return NULL;
6631 return PyInt_FromLong((long)major(device));
6632}
6633
6634PyDoc_STRVAR(posix_minor__doc__,
6635"minor(device) -> minor number\n\
6636Extracts a device minor number from a raw device number.");
6637
6638static PyObject *
6639posix_minor(PyObject *self, PyObject *args)
6640{
6641 int device;
6642 if (!PyArg_ParseTuple(args, "i:minor", &device))
6643 return NULL;
6644 return PyInt_FromLong((long)minor(device));
6645}
6646
6647PyDoc_STRVAR(posix_makedev__doc__,
6648"makedev(major, minor) -> device number\n\
6649Composes a raw device number from the major and minor device numbers.");
6650
6651static PyObject *
6652posix_makedev(PyObject *self, PyObject *args)
6653{
6654 int major, minor;
6655 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6656 return NULL;
6657 return PyInt_FromLong((long)makedev(major, minor));
6658}
6659#endif /* device macros */
6660
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006661
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006662#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006663PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006664"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006665Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006666
Barry Warsaw53699e91996-12-10 23:23:01 +00006667static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006668posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006669{
6670 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006671 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006672 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006673 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006674
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006675 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006676 return NULL;
6677
6678#if !defined(HAVE_LARGEFILE_SUPPORT)
6679 length = PyInt_AsLong(lenobj);
6680#else
6681 length = PyLong_Check(lenobj) ?
6682 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6683#endif
6684 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006685 return NULL;
6686
Barry Warsaw53699e91996-12-10 23:23:01 +00006687 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006688 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006689 Py_END_ALLOW_THREADS
Benjamin Peterson943a6dd2009-01-19 15:51:27 +00006690 if (res < 0)
6691 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006692 Py_INCREF(Py_None);
6693 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006694}
6695#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006696
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006697#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006698PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006699"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006700Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006701
Fred Drake762e2061999-08-26 17:23:54 +00006702/* Save putenv() parameters as values here, so we can collect them when they
6703 * get re-set with another call for the same key. */
6704static PyObject *posix_putenv_garbage;
6705
Tim Peters5aa91602002-01-30 05:46:57 +00006706static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006707posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006708{
6709 char *s1, *s2;
Anthony Baxter64182fe2006-04-11 12:14:09 +00006710 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006711 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006712 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006713
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006714 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006715 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006716
6717#if defined(PYOS_OS2)
6718 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6719 APIRET rc;
6720
Guido van Rossumd48f2521997-12-05 22:19:34 +00006721 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6722 if (rc != NO_ERROR)
6723 return os2_error(rc);
6724
6725 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6726 APIRET rc;
6727
Guido van Rossumd48f2521997-12-05 22:19:34 +00006728 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6729 if (rc != NO_ERROR)
6730 return os2_error(rc);
6731 } else {
6732#endif
6733
Fred Drake762e2061999-08-26 17:23:54 +00006734 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006735 len = strlen(s1) + strlen(s2) + 2;
6736 /* len includes space for a trailing \0; the size arg to
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006737 PyString_FromStringAndSize does not count that */
6738 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006739 if (newstr == NULL)
6740 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006741 newenv = PyString_AS_STRING(newstr);
Anthony Baxter64182fe2006-04-11 12:14:09 +00006742 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6743 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006744 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006745 posix_error();
6746 return NULL;
6747 }
Fred Drake762e2061999-08-26 17:23:54 +00006748 /* Install the first arg and newstr in posix_putenv_garbage;
6749 * this will cause previous value to be collected. This has to
6750 * happen after the real putenv() call because the old value
6751 * was still accessible until then. */
6752 if (PyDict_SetItem(posix_putenv_garbage,
6753 PyTuple_GET_ITEM(args, 0), newstr)) {
6754 /* really not much we can do; just leak */
6755 PyErr_Clear();
6756 }
6757 else {
6758 Py_DECREF(newstr);
6759 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006760
6761#if defined(PYOS_OS2)
6762 }
6763#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006764 Py_INCREF(Py_None);
6765 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006766}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006767#endif /* putenv */
6768
Guido van Rossumc524d952001-10-19 01:31:59 +00006769#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006770PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006771"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006772Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006773
6774static PyObject *
6775posix_unsetenv(PyObject *self, PyObject *args)
6776{
6777 char *s1;
6778
6779 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6780 return NULL;
6781
6782 unsetenv(s1);
6783
6784 /* Remove the key from posix_putenv_garbage;
6785 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006786 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006787 * old value was still accessible until then.
6788 */
6789 if (PyDict_DelItem(posix_putenv_garbage,
6790 PyTuple_GET_ITEM(args, 0))) {
6791 /* really not much we can do; just leak */
6792 PyErr_Clear();
6793 }
6794
6795 Py_INCREF(Py_None);
6796 return Py_None;
6797}
6798#endif /* unsetenv */
6799
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006800PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006801"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006802Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006803
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006804static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006805posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006806{
6807 int code;
6808 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006809 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006810 return NULL;
6811 message = strerror(code);
6812 if (message == NULL) {
6813 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006814 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006815 return NULL;
6816 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006817 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006818}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006819
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006820
Guido van Rossumc9641791998-08-04 15:26:23 +00006821#ifdef HAVE_SYS_WAIT_H
6822
Fred Drake106c1a02002-04-23 15:58:02 +00006823#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006824PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006825"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006826Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006827
6828static PyObject *
6829posix_WCOREDUMP(PyObject *self, PyObject *args)
6830{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006831 WAIT_TYPE status;
6832 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006833
Neal Norwitzd5a37542006-03-20 06:48:34 +00006834 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006835 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006836
6837 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006838}
6839#endif /* WCOREDUMP */
6840
6841#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006842PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006843"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006844Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006845job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006846
6847static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006848posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006849{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006850 WAIT_TYPE status;
6851 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006852
Neal Norwitzd5a37542006-03-20 06:48:34 +00006853 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006854 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006855
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006856 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006857}
6858#endif /* WIFCONTINUED */
6859
Guido van Rossumc9641791998-08-04 15:26:23 +00006860#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006861PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006862"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006863Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006864
6865static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006866posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006867{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006868 WAIT_TYPE status;
6869 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006870
Neal Norwitzd5a37542006-03-20 06:48:34 +00006871 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006872 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006873
Fred Drake106c1a02002-04-23 15:58:02 +00006874 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006875}
6876#endif /* WIFSTOPPED */
6877
6878#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006879PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006880"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006881Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006882
6883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006884posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006885{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006886 WAIT_TYPE status;
6887 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006888
Neal Norwitzd5a37542006-03-20 06:48:34 +00006889 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006890 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006891
Fred Drake106c1a02002-04-23 15:58:02 +00006892 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006893}
6894#endif /* WIFSIGNALED */
6895
6896#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006897PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006898"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006899Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006900system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006901
6902static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006903posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006904{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006905 WAIT_TYPE status;
6906 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006907
Neal Norwitzd5a37542006-03-20 06:48:34 +00006908 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006909 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006910
Fred Drake106c1a02002-04-23 15:58:02 +00006911 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006912}
6913#endif /* WIFEXITED */
6914
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006915#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006916PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006917"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006918Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006919
6920static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006921posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006922{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006923 WAIT_TYPE status;
6924 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006925
Neal Norwitzd5a37542006-03-20 06:48:34 +00006926 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006927 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006928
Guido van Rossumc9641791998-08-04 15:26:23 +00006929 return Py_BuildValue("i", WEXITSTATUS(status));
6930}
6931#endif /* WEXITSTATUS */
6932
6933#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006934PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006935"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006936Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006937value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006938
6939static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006940posix_WTERMSIG(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:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006946 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006947
Guido van Rossumc9641791998-08-04 15:26:23 +00006948 return Py_BuildValue("i", WTERMSIG(status));
6949}
6950#endif /* WTERMSIG */
6951
6952#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006953PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006954"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006955Return the signal that stopped the process that provided\n\
6956the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006957
6958static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006959posix_WSTOPSIG(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:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006965 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006966
Guido van Rossumc9641791998-08-04 15:26:23 +00006967 return Py_BuildValue("i", WSTOPSIG(status));
6968}
6969#endif /* WSTOPSIG */
6970
6971#endif /* HAVE_SYS_WAIT_H */
6972
6973
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006974#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006975#ifdef _SCO_DS
6976/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6977 needed definitions in sys/statvfs.h */
6978#define _SVID3
6979#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006980#include <sys/statvfs.h>
6981
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006982static PyObject*
6983_pystatvfs_fromstructstatvfs(struct statvfs st) {
6984 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6985 if (v == NULL)
6986 return NULL;
6987
6988#if !defined(HAVE_LARGEFILE_SUPPORT)
6989 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6990 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6991 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6992 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6993 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6994 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6995 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6996 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6997 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6998 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6999#else
7000 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7001 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00007002 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007003 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00007004 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007005 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007006 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007007 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00007008 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007009 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00007010 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007011 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00007012 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007013 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007014 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7015 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
7016#endif
7017
7018 return v;
7019}
7020
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007021PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007022"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007023Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007024
7025static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007026posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007027{
7028 int fd, res;
7029 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007030
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007031 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00007032 return NULL;
7033 Py_BEGIN_ALLOW_THREADS
7034 res = fstatvfs(fd, &st);
7035 Py_END_ALLOW_THREADS
7036 if (res != 0)
7037 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007038
7039 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007040}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007041#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007042
7043
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007044#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007045#include <sys/statvfs.h>
7046
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007047PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007048"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007049Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007050
7051static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007052posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007053{
7054 char *path;
7055 int res;
7056 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007057 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00007058 return NULL;
7059 Py_BEGIN_ALLOW_THREADS
7060 res = statvfs(path, &st);
7061 Py_END_ALLOW_THREADS
7062 if (res != 0)
7063 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007064
7065 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007066}
7067#endif /* HAVE_STATVFS */
7068
7069
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007070#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007071PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007072"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007073Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007074The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007075or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007076
7077static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007078posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007079{
7080 PyObject *result = NULL;
7081 char *dir = NULL;
7082 char *pfx = NULL;
7083 char *name;
7084
7085 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
7086 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007087
7088 if (PyErr_Warn(PyExc_RuntimeWarning,
7089 "tempnam is a potential security risk to your program") < 0)
7090 return NULL;
7091
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007092#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007093 name = _tempnam(dir, pfx);
7094#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007095 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007096#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007097 if (name == NULL)
7098 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007099 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007100 free(name);
7101 return result;
7102}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007103#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007104
7105
7106#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007107PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007108"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007109Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007110
7111static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007112posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007113{
7114 FILE *fp;
7115
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007116 fp = tmpfile();
7117 if (fp == NULL)
7118 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007119 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007120}
7121#endif
7122
7123
7124#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007125PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007126"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007127Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007128
7129static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007130posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007131{
7132 char buffer[L_tmpnam];
7133 char *name;
7134
Skip Montanaro95618b52001-08-18 18:52:10 +00007135 if (PyErr_Warn(PyExc_RuntimeWarning,
7136 "tmpnam is a potential security risk to your program") < 0)
7137 return NULL;
7138
Greg Wardb48bc172000-03-01 21:51:56 +00007139#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007140 name = tmpnam_r(buffer);
7141#else
7142 name = tmpnam(buffer);
7143#endif
7144 if (name == NULL) {
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007145 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007146#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007147 "unexpected NULL from tmpnam_r"
7148#else
7149 "unexpected NULL from tmpnam"
7150#endif
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007151 );
7152 PyErr_SetObject(PyExc_OSError, err);
7153 Py_XDECREF(err);
7154 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007155 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007156 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007157}
7158#endif
7159
7160
Fred Drakec9680921999-12-13 16:37:25 +00007161/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7162 * It maps strings representing configuration variable names to
7163 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007164 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007165 * rarely-used constants. There are three separate tables that use
7166 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007167 *
7168 * This code is always included, even if none of the interfaces that
7169 * need it are included. The #if hackery needed to avoid it would be
7170 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007171 */
7172struct constdef {
7173 char *name;
7174 long value;
7175};
7176
Fred Drake12c6e2d1999-12-14 21:25:03 +00007177static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007178conv_confname(PyObject *arg, int *valuep, struct constdef *table,
7179 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007180{
7181 if (PyInt_Check(arg)) {
7182 *valuep = PyInt_AS_LONG(arg);
7183 return 1;
7184 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007185 if (PyString_Check(arg)) {
Fred Drake12c6e2d1999-12-14 21:25:03 +00007186 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00007187 size_t lo = 0;
7188 size_t mid;
7189 size_t hi = tablesize;
7190 int cmp;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007191 char *confname = PyString_AS_STRING(arg);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007192 while (lo < hi) {
7193 mid = (lo + hi) / 2;
7194 cmp = strcmp(confname, table[mid].name);
7195 if (cmp < 0)
7196 hi = mid;
7197 else if (cmp > 0)
7198 lo = mid + 1;
7199 else {
7200 *valuep = table[mid].value;
7201 return 1;
7202 }
7203 }
7204 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
7205 }
7206 else
7207 PyErr_SetString(PyExc_TypeError,
7208 "configuration names must be strings or integers");
7209 return 0;
7210}
7211
7212
7213#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7214static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007215#ifdef _PC_ABI_AIO_XFER_MAX
7216 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
7217#endif
7218#ifdef _PC_ABI_ASYNC_IO
7219 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
7220#endif
Fred Drakec9680921999-12-13 16:37:25 +00007221#ifdef _PC_ASYNC_IO
7222 {"PC_ASYNC_IO", _PC_ASYNC_IO},
7223#endif
7224#ifdef _PC_CHOWN_RESTRICTED
7225 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
7226#endif
7227#ifdef _PC_FILESIZEBITS
7228 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
7229#endif
7230#ifdef _PC_LAST
7231 {"PC_LAST", _PC_LAST},
7232#endif
7233#ifdef _PC_LINK_MAX
7234 {"PC_LINK_MAX", _PC_LINK_MAX},
7235#endif
7236#ifdef _PC_MAX_CANON
7237 {"PC_MAX_CANON", _PC_MAX_CANON},
7238#endif
7239#ifdef _PC_MAX_INPUT
7240 {"PC_MAX_INPUT", _PC_MAX_INPUT},
7241#endif
7242#ifdef _PC_NAME_MAX
7243 {"PC_NAME_MAX", _PC_NAME_MAX},
7244#endif
7245#ifdef _PC_NO_TRUNC
7246 {"PC_NO_TRUNC", _PC_NO_TRUNC},
7247#endif
7248#ifdef _PC_PATH_MAX
7249 {"PC_PATH_MAX", _PC_PATH_MAX},
7250#endif
7251#ifdef _PC_PIPE_BUF
7252 {"PC_PIPE_BUF", _PC_PIPE_BUF},
7253#endif
7254#ifdef _PC_PRIO_IO
7255 {"PC_PRIO_IO", _PC_PRIO_IO},
7256#endif
7257#ifdef _PC_SOCK_MAXBUF
7258 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
7259#endif
7260#ifdef _PC_SYNC_IO
7261 {"PC_SYNC_IO", _PC_SYNC_IO},
7262#endif
7263#ifdef _PC_VDISABLE
7264 {"PC_VDISABLE", _PC_VDISABLE},
7265#endif
7266};
7267
Fred Drakec9680921999-12-13 16:37:25 +00007268static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007269conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007270{
7271 return conv_confname(arg, valuep, posix_constants_pathconf,
7272 sizeof(posix_constants_pathconf)
7273 / sizeof(struct constdef));
7274}
7275#endif
7276
7277#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007278PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007279"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007280Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007281If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007282
7283static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007284posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007285{
7286 PyObject *result = NULL;
7287 int name, fd;
7288
Fred Drake12c6e2d1999-12-14 21:25:03 +00007289 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7290 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00007291 long limit;
7292
7293 errno = 0;
7294 limit = fpathconf(fd, name);
7295 if (limit == -1 && errno != 0)
7296 posix_error();
7297 else
7298 result = PyInt_FromLong(limit);
7299 }
7300 return result;
7301}
7302#endif
7303
7304
7305#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007306PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007307"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007308Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007309If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007310
7311static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007312posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007313{
7314 PyObject *result = NULL;
7315 int name;
7316 char *path;
7317
7318 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7319 conv_path_confname, &name)) {
7320 long limit;
7321
7322 errno = 0;
7323 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007324 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00007325 if (errno == EINVAL)
7326 /* could be a path or name problem */
7327 posix_error();
7328 else
7329 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007330 }
Fred Drakec9680921999-12-13 16:37:25 +00007331 else
7332 result = PyInt_FromLong(limit);
7333 }
7334 return result;
7335}
7336#endif
7337
7338#ifdef HAVE_CONFSTR
7339static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007340#ifdef _CS_ARCHITECTURE
7341 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
7342#endif
7343#ifdef _CS_HOSTNAME
7344 {"CS_HOSTNAME", _CS_HOSTNAME},
7345#endif
7346#ifdef _CS_HW_PROVIDER
7347 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
7348#endif
7349#ifdef _CS_HW_SERIAL
7350 {"CS_HW_SERIAL", _CS_HW_SERIAL},
7351#endif
7352#ifdef _CS_INITTAB_NAME
7353 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
7354#endif
Fred Drakec9680921999-12-13 16:37:25 +00007355#ifdef _CS_LFS64_CFLAGS
7356 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
7357#endif
7358#ifdef _CS_LFS64_LDFLAGS
7359 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
7360#endif
7361#ifdef _CS_LFS64_LIBS
7362 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
7363#endif
7364#ifdef _CS_LFS64_LINTFLAGS
7365 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
7366#endif
7367#ifdef _CS_LFS_CFLAGS
7368 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
7369#endif
7370#ifdef _CS_LFS_LDFLAGS
7371 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
7372#endif
7373#ifdef _CS_LFS_LIBS
7374 {"CS_LFS_LIBS", _CS_LFS_LIBS},
7375#endif
7376#ifdef _CS_LFS_LINTFLAGS
7377 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
7378#endif
Fred Draked86ed291999-12-15 15:34:33 +00007379#ifdef _CS_MACHINE
7380 {"CS_MACHINE", _CS_MACHINE},
7381#endif
Fred Drakec9680921999-12-13 16:37:25 +00007382#ifdef _CS_PATH
7383 {"CS_PATH", _CS_PATH},
7384#endif
Fred Draked86ed291999-12-15 15:34:33 +00007385#ifdef _CS_RELEASE
7386 {"CS_RELEASE", _CS_RELEASE},
7387#endif
7388#ifdef _CS_SRPC_DOMAIN
7389 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
7390#endif
7391#ifdef _CS_SYSNAME
7392 {"CS_SYSNAME", _CS_SYSNAME},
7393#endif
7394#ifdef _CS_VERSION
7395 {"CS_VERSION", _CS_VERSION},
7396#endif
Fred Drakec9680921999-12-13 16:37:25 +00007397#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
7398 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
7399#endif
7400#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
7401 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
7402#endif
7403#ifdef _CS_XBS5_ILP32_OFF32_LIBS
7404 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
7405#endif
7406#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
7407 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
7408#endif
7409#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
7410 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
7411#endif
7412#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
7413 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
7414#endif
7415#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
7416 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
7417#endif
7418#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
7419 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
7420#endif
7421#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7422 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
7423#endif
7424#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7425 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7426#endif
7427#ifdef _CS_XBS5_LP64_OFF64_LIBS
7428 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7429#endif
7430#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7431 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7432#endif
7433#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7434 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7435#endif
7436#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7437 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7438#endif
7439#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7440 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7441#endif
7442#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7443 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7444#endif
Fred Draked86ed291999-12-15 15:34:33 +00007445#ifdef _MIPS_CS_AVAIL_PROCESSORS
7446 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7447#endif
7448#ifdef _MIPS_CS_BASE
7449 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7450#endif
7451#ifdef _MIPS_CS_HOSTID
7452 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7453#endif
7454#ifdef _MIPS_CS_HW_NAME
7455 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7456#endif
7457#ifdef _MIPS_CS_NUM_PROCESSORS
7458 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7459#endif
7460#ifdef _MIPS_CS_OSREL_MAJ
7461 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7462#endif
7463#ifdef _MIPS_CS_OSREL_MIN
7464 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7465#endif
7466#ifdef _MIPS_CS_OSREL_PATCH
7467 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7468#endif
7469#ifdef _MIPS_CS_OS_NAME
7470 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7471#endif
7472#ifdef _MIPS_CS_OS_PROVIDER
7473 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7474#endif
7475#ifdef _MIPS_CS_PROCESSORS
7476 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7477#endif
7478#ifdef _MIPS_CS_SERIAL
7479 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7480#endif
7481#ifdef _MIPS_CS_VENDOR
7482 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7483#endif
Fred Drakec9680921999-12-13 16:37:25 +00007484};
7485
7486static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007487conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007488{
7489 return conv_confname(arg, valuep, posix_constants_confstr,
7490 sizeof(posix_constants_confstr)
7491 / sizeof(struct constdef));
7492}
7493
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007494PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007495"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007496Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007497
7498static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007499posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007500{
7501 PyObject *result = NULL;
7502 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007503 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007504
7505 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Skip Montanarodd527fc2006-04-18 00:49:49 +00007506 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007507
Fred Drakec9680921999-12-13 16:37:25 +00007508 errno = 0;
Skip Montanarodd527fc2006-04-18 00:49:49 +00007509 len = confstr(name, buffer, sizeof(buffer));
Skip Montanaro94785ef2006-04-20 01:29:48 +00007510 if (len == 0) {
7511 if (errno) {
7512 posix_error();
7513 }
7514 else {
7515 result = Py_None;
7516 Py_INCREF(Py_None);
7517 }
Fred Drakec9680921999-12-13 16:37:25 +00007518 }
7519 else {
Neal Norwitz0d21b1e2006-04-20 06:44:42 +00007520 if ((unsigned int)len >= sizeof(buffer)) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007521 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007522 if (result != NULL)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007523 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00007524 }
7525 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007526 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007527 }
7528 }
7529 return result;
7530}
7531#endif
7532
7533
7534#ifdef HAVE_SYSCONF
7535static struct constdef posix_constants_sysconf[] = {
7536#ifdef _SC_2_CHAR_TERM
7537 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7538#endif
7539#ifdef _SC_2_C_BIND
7540 {"SC_2_C_BIND", _SC_2_C_BIND},
7541#endif
7542#ifdef _SC_2_C_DEV
7543 {"SC_2_C_DEV", _SC_2_C_DEV},
7544#endif
7545#ifdef _SC_2_C_VERSION
7546 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7547#endif
7548#ifdef _SC_2_FORT_DEV
7549 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7550#endif
7551#ifdef _SC_2_FORT_RUN
7552 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7553#endif
7554#ifdef _SC_2_LOCALEDEF
7555 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7556#endif
7557#ifdef _SC_2_SW_DEV
7558 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7559#endif
7560#ifdef _SC_2_UPE
7561 {"SC_2_UPE", _SC_2_UPE},
7562#endif
7563#ifdef _SC_2_VERSION
7564 {"SC_2_VERSION", _SC_2_VERSION},
7565#endif
Fred Draked86ed291999-12-15 15:34:33 +00007566#ifdef _SC_ABI_ASYNCHRONOUS_IO
7567 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7568#endif
7569#ifdef _SC_ACL
7570 {"SC_ACL", _SC_ACL},
7571#endif
Fred Drakec9680921999-12-13 16:37:25 +00007572#ifdef _SC_AIO_LISTIO_MAX
7573 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7574#endif
Fred Drakec9680921999-12-13 16:37:25 +00007575#ifdef _SC_AIO_MAX
7576 {"SC_AIO_MAX", _SC_AIO_MAX},
7577#endif
7578#ifdef _SC_AIO_PRIO_DELTA_MAX
7579 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7580#endif
7581#ifdef _SC_ARG_MAX
7582 {"SC_ARG_MAX", _SC_ARG_MAX},
7583#endif
7584#ifdef _SC_ASYNCHRONOUS_IO
7585 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7586#endif
7587#ifdef _SC_ATEXIT_MAX
7588 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7589#endif
Fred Draked86ed291999-12-15 15:34:33 +00007590#ifdef _SC_AUDIT
7591 {"SC_AUDIT", _SC_AUDIT},
7592#endif
Fred Drakec9680921999-12-13 16:37:25 +00007593#ifdef _SC_AVPHYS_PAGES
7594 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7595#endif
7596#ifdef _SC_BC_BASE_MAX
7597 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7598#endif
7599#ifdef _SC_BC_DIM_MAX
7600 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7601#endif
7602#ifdef _SC_BC_SCALE_MAX
7603 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7604#endif
7605#ifdef _SC_BC_STRING_MAX
7606 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7607#endif
Fred Draked86ed291999-12-15 15:34:33 +00007608#ifdef _SC_CAP
7609 {"SC_CAP", _SC_CAP},
7610#endif
Fred Drakec9680921999-12-13 16:37:25 +00007611#ifdef _SC_CHARCLASS_NAME_MAX
7612 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7613#endif
7614#ifdef _SC_CHAR_BIT
7615 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7616#endif
7617#ifdef _SC_CHAR_MAX
7618 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7619#endif
7620#ifdef _SC_CHAR_MIN
7621 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7622#endif
7623#ifdef _SC_CHILD_MAX
7624 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7625#endif
7626#ifdef _SC_CLK_TCK
7627 {"SC_CLK_TCK", _SC_CLK_TCK},
7628#endif
7629#ifdef _SC_COHER_BLKSZ
7630 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7631#endif
7632#ifdef _SC_COLL_WEIGHTS_MAX
7633 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7634#endif
7635#ifdef _SC_DCACHE_ASSOC
7636 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7637#endif
7638#ifdef _SC_DCACHE_BLKSZ
7639 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7640#endif
7641#ifdef _SC_DCACHE_LINESZ
7642 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7643#endif
7644#ifdef _SC_DCACHE_SZ
7645 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7646#endif
7647#ifdef _SC_DCACHE_TBLKSZ
7648 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7649#endif
7650#ifdef _SC_DELAYTIMER_MAX
7651 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7652#endif
7653#ifdef _SC_EQUIV_CLASS_MAX
7654 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7655#endif
7656#ifdef _SC_EXPR_NEST_MAX
7657 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7658#endif
7659#ifdef _SC_FSYNC
7660 {"SC_FSYNC", _SC_FSYNC},
7661#endif
7662#ifdef _SC_GETGR_R_SIZE_MAX
7663 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7664#endif
7665#ifdef _SC_GETPW_R_SIZE_MAX
7666 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7667#endif
7668#ifdef _SC_ICACHE_ASSOC
7669 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7670#endif
7671#ifdef _SC_ICACHE_BLKSZ
7672 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7673#endif
7674#ifdef _SC_ICACHE_LINESZ
7675 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7676#endif
7677#ifdef _SC_ICACHE_SZ
7678 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7679#endif
Fred Draked86ed291999-12-15 15:34:33 +00007680#ifdef _SC_INF
7681 {"SC_INF", _SC_INF},
7682#endif
Fred Drakec9680921999-12-13 16:37:25 +00007683#ifdef _SC_INT_MAX
7684 {"SC_INT_MAX", _SC_INT_MAX},
7685#endif
7686#ifdef _SC_INT_MIN
7687 {"SC_INT_MIN", _SC_INT_MIN},
7688#endif
7689#ifdef _SC_IOV_MAX
7690 {"SC_IOV_MAX", _SC_IOV_MAX},
7691#endif
Fred Draked86ed291999-12-15 15:34:33 +00007692#ifdef _SC_IP_SECOPTS
7693 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7694#endif
Fred Drakec9680921999-12-13 16:37:25 +00007695#ifdef _SC_JOB_CONTROL
7696 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7697#endif
Fred Draked86ed291999-12-15 15:34:33 +00007698#ifdef _SC_KERN_POINTERS
7699 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7700#endif
7701#ifdef _SC_KERN_SIM
7702 {"SC_KERN_SIM", _SC_KERN_SIM},
7703#endif
Fred Drakec9680921999-12-13 16:37:25 +00007704#ifdef _SC_LINE_MAX
7705 {"SC_LINE_MAX", _SC_LINE_MAX},
7706#endif
7707#ifdef _SC_LOGIN_NAME_MAX
7708 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7709#endif
7710#ifdef _SC_LOGNAME_MAX
7711 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7712#endif
7713#ifdef _SC_LONG_BIT
7714 {"SC_LONG_BIT", _SC_LONG_BIT},
7715#endif
Fred Draked86ed291999-12-15 15:34:33 +00007716#ifdef _SC_MAC
7717 {"SC_MAC", _SC_MAC},
7718#endif
Fred Drakec9680921999-12-13 16:37:25 +00007719#ifdef _SC_MAPPED_FILES
7720 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7721#endif
7722#ifdef _SC_MAXPID
7723 {"SC_MAXPID", _SC_MAXPID},
7724#endif
7725#ifdef _SC_MB_LEN_MAX
7726 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7727#endif
7728#ifdef _SC_MEMLOCK
7729 {"SC_MEMLOCK", _SC_MEMLOCK},
7730#endif
7731#ifdef _SC_MEMLOCK_RANGE
7732 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7733#endif
7734#ifdef _SC_MEMORY_PROTECTION
7735 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7736#endif
7737#ifdef _SC_MESSAGE_PASSING
7738 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7739#endif
Fred Draked86ed291999-12-15 15:34:33 +00007740#ifdef _SC_MMAP_FIXED_ALIGNMENT
7741 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7742#endif
Fred Drakec9680921999-12-13 16:37:25 +00007743#ifdef _SC_MQ_OPEN_MAX
7744 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7745#endif
7746#ifdef _SC_MQ_PRIO_MAX
7747 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7748#endif
Fred Draked86ed291999-12-15 15:34:33 +00007749#ifdef _SC_NACLS_MAX
7750 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7751#endif
Fred Drakec9680921999-12-13 16:37:25 +00007752#ifdef _SC_NGROUPS_MAX
7753 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7754#endif
7755#ifdef _SC_NL_ARGMAX
7756 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7757#endif
7758#ifdef _SC_NL_LANGMAX
7759 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7760#endif
7761#ifdef _SC_NL_MSGMAX
7762 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7763#endif
7764#ifdef _SC_NL_NMAX
7765 {"SC_NL_NMAX", _SC_NL_NMAX},
7766#endif
7767#ifdef _SC_NL_SETMAX
7768 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7769#endif
7770#ifdef _SC_NL_TEXTMAX
7771 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7772#endif
7773#ifdef _SC_NPROCESSORS_CONF
7774 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7775#endif
7776#ifdef _SC_NPROCESSORS_ONLN
7777 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7778#endif
Fred Draked86ed291999-12-15 15:34:33 +00007779#ifdef _SC_NPROC_CONF
7780 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7781#endif
7782#ifdef _SC_NPROC_ONLN
7783 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7784#endif
Fred Drakec9680921999-12-13 16:37:25 +00007785#ifdef _SC_NZERO
7786 {"SC_NZERO", _SC_NZERO},
7787#endif
7788#ifdef _SC_OPEN_MAX
7789 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7790#endif
7791#ifdef _SC_PAGESIZE
7792 {"SC_PAGESIZE", _SC_PAGESIZE},
7793#endif
7794#ifdef _SC_PAGE_SIZE
7795 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7796#endif
7797#ifdef _SC_PASS_MAX
7798 {"SC_PASS_MAX", _SC_PASS_MAX},
7799#endif
7800#ifdef _SC_PHYS_PAGES
7801 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7802#endif
7803#ifdef _SC_PII
7804 {"SC_PII", _SC_PII},
7805#endif
7806#ifdef _SC_PII_INTERNET
7807 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7808#endif
7809#ifdef _SC_PII_INTERNET_DGRAM
7810 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7811#endif
7812#ifdef _SC_PII_INTERNET_STREAM
7813 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7814#endif
7815#ifdef _SC_PII_OSI
7816 {"SC_PII_OSI", _SC_PII_OSI},
7817#endif
7818#ifdef _SC_PII_OSI_CLTS
7819 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7820#endif
7821#ifdef _SC_PII_OSI_COTS
7822 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7823#endif
7824#ifdef _SC_PII_OSI_M
7825 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7826#endif
7827#ifdef _SC_PII_SOCKET
7828 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7829#endif
7830#ifdef _SC_PII_XTI
7831 {"SC_PII_XTI", _SC_PII_XTI},
7832#endif
7833#ifdef _SC_POLL
7834 {"SC_POLL", _SC_POLL},
7835#endif
7836#ifdef _SC_PRIORITIZED_IO
7837 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7838#endif
7839#ifdef _SC_PRIORITY_SCHEDULING
7840 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7841#endif
7842#ifdef _SC_REALTIME_SIGNALS
7843 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7844#endif
7845#ifdef _SC_RE_DUP_MAX
7846 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7847#endif
7848#ifdef _SC_RTSIG_MAX
7849 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7850#endif
7851#ifdef _SC_SAVED_IDS
7852 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7853#endif
7854#ifdef _SC_SCHAR_MAX
7855 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7856#endif
7857#ifdef _SC_SCHAR_MIN
7858 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7859#endif
7860#ifdef _SC_SELECT
7861 {"SC_SELECT", _SC_SELECT},
7862#endif
7863#ifdef _SC_SEMAPHORES
7864 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7865#endif
7866#ifdef _SC_SEM_NSEMS_MAX
7867 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7868#endif
7869#ifdef _SC_SEM_VALUE_MAX
7870 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7871#endif
7872#ifdef _SC_SHARED_MEMORY_OBJECTS
7873 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7874#endif
7875#ifdef _SC_SHRT_MAX
7876 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7877#endif
7878#ifdef _SC_SHRT_MIN
7879 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7880#endif
7881#ifdef _SC_SIGQUEUE_MAX
7882 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7883#endif
7884#ifdef _SC_SIGRT_MAX
7885 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7886#endif
7887#ifdef _SC_SIGRT_MIN
7888 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7889#endif
Fred Draked86ed291999-12-15 15:34:33 +00007890#ifdef _SC_SOFTPOWER
7891 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7892#endif
Fred Drakec9680921999-12-13 16:37:25 +00007893#ifdef _SC_SPLIT_CACHE
7894 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7895#endif
7896#ifdef _SC_SSIZE_MAX
7897 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7898#endif
7899#ifdef _SC_STACK_PROT
7900 {"SC_STACK_PROT", _SC_STACK_PROT},
7901#endif
7902#ifdef _SC_STREAM_MAX
7903 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7904#endif
7905#ifdef _SC_SYNCHRONIZED_IO
7906 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7907#endif
7908#ifdef _SC_THREADS
7909 {"SC_THREADS", _SC_THREADS},
7910#endif
7911#ifdef _SC_THREAD_ATTR_STACKADDR
7912 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7913#endif
7914#ifdef _SC_THREAD_ATTR_STACKSIZE
7915 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7916#endif
7917#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7918 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7919#endif
7920#ifdef _SC_THREAD_KEYS_MAX
7921 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7922#endif
7923#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7924 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7925#endif
7926#ifdef _SC_THREAD_PRIO_INHERIT
7927 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7928#endif
7929#ifdef _SC_THREAD_PRIO_PROTECT
7930 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7931#endif
7932#ifdef _SC_THREAD_PROCESS_SHARED
7933 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7934#endif
7935#ifdef _SC_THREAD_SAFE_FUNCTIONS
7936 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7937#endif
7938#ifdef _SC_THREAD_STACK_MIN
7939 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7940#endif
7941#ifdef _SC_THREAD_THREADS_MAX
7942 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7943#endif
7944#ifdef _SC_TIMERS
7945 {"SC_TIMERS", _SC_TIMERS},
7946#endif
7947#ifdef _SC_TIMER_MAX
7948 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7949#endif
7950#ifdef _SC_TTY_NAME_MAX
7951 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7952#endif
7953#ifdef _SC_TZNAME_MAX
7954 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7955#endif
7956#ifdef _SC_T_IOV_MAX
7957 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7958#endif
7959#ifdef _SC_UCHAR_MAX
7960 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7961#endif
7962#ifdef _SC_UINT_MAX
7963 {"SC_UINT_MAX", _SC_UINT_MAX},
7964#endif
7965#ifdef _SC_UIO_MAXIOV
7966 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7967#endif
7968#ifdef _SC_ULONG_MAX
7969 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7970#endif
7971#ifdef _SC_USHRT_MAX
7972 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7973#endif
7974#ifdef _SC_VERSION
7975 {"SC_VERSION", _SC_VERSION},
7976#endif
7977#ifdef _SC_WORD_BIT
7978 {"SC_WORD_BIT", _SC_WORD_BIT},
7979#endif
7980#ifdef _SC_XBS5_ILP32_OFF32
7981 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7982#endif
7983#ifdef _SC_XBS5_ILP32_OFFBIG
7984 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7985#endif
7986#ifdef _SC_XBS5_LP64_OFF64
7987 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7988#endif
7989#ifdef _SC_XBS5_LPBIG_OFFBIG
7990 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7991#endif
7992#ifdef _SC_XOPEN_CRYPT
7993 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7994#endif
7995#ifdef _SC_XOPEN_ENH_I18N
7996 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7997#endif
7998#ifdef _SC_XOPEN_LEGACY
7999 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
8000#endif
8001#ifdef _SC_XOPEN_REALTIME
8002 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
8003#endif
8004#ifdef _SC_XOPEN_REALTIME_THREADS
8005 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
8006#endif
8007#ifdef _SC_XOPEN_SHM
8008 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
8009#endif
8010#ifdef _SC_XOPEN_UNIX
8011 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
8012#endif
8013#ifdef _SC_XOPEN_VERSION
8014 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
8015#endif
8016#ifdef _SC_XOPEN_XCU_VERSION
8017 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
8018#endif
8019#ifdef _SC_XOPEN_XPG2
8020 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
8021#endif
8022#ifdef _SC_XOPEN_XPG3
8023 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
8024#endif
8025#ifdef _SC_XOPEN_XPG4
8026 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
8027#endif
8028};
8029
8030static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008031conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008032{
8033 return conv_confname(arg, valuep, posix_constants_sysconf,
8034 sizeof(posix_constants_sysconf)
8035 / sizeof(struct constdef));
8036}
8037
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008038PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008039"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008040Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008041
8042static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008043posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008044{
8045 PyObject *result = NULL;
8046 int name;
8047
8048 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
8049 int value;
8050
8051 errno = 0;
8052 value = sysconf(name);
8053 if (value == -1 && errno != 0)
8054 posix_error();
8055 else
8056 result = PyInt_FromLong(value);
8057 }
8058 return result;
8059}
8060#endif
8061
8062
Fred Drakebec628d1999-12-15 18:31:10 +00008063/* This code is used to ensure that the tables of configuration value names
8064 * are in sorted order as required by conv_confname(), and also to build the
8065 * the exported dictionaries that are used to publish information about the
8066 * names available on the host platform.
8067 *
8068 * Sorting the table at runtime ensures that the table is properly ordered
8069 * when used, even for platforms we're not able to test on. It also makes
8070 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008071 */
Fred Drakebec628d1999-12-15 18:31:10 +00008072
8073static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008074cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008075{
8076 const struct constdef *c1 =
8077 (const struct constdef *) v1;
8078 const struct constdef *c2 =
8079 (const struct constdef *) v2;
8080
8081 return strcmp(c1->name, c2->name);
8082}
8083
8084static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008085setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008086 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008087{
Fred Drakebec628d1999-12-15 18:31:10 +00008088 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008089 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008090
8091 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8092 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008093 if (d == NULL)
8094 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008095
Barry Warsaw3155db32000-04-13 15:20:40 +00008096 for (i=0; i < tablesize; ++i) {
8097 PyObject *o = PyInt_FromLong(table[i].value);
8098 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8099 Py_XDECREF(o);
8100 Py_DECREF(d);
8101 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008102 }
Barry Warsaw3155db32000-04-13 15:20:40 +00008103 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008104 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008105 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008106}
8107
Fred Drakebec628d1999-12-15 18:31:10 +00008108/* Return -1 on failure, 0 on success. */
8109static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008110setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008111{
8112#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008113 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008114 sizeof(posix_constants_pathconf)
8115 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008116 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008117 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008118#endif
8119#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008120 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008121 sizeof(posix_constants_confstr)
8122 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008123 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008124 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008125#endif
8126#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008127 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008128 sizeof(posix_constants_sysconf)
8129 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008130 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008131 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008132#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008133 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008134}
Fred Draked86ed291999-12-15 15:34:33 +00008135
8136
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008137PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008138"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008139Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008140in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008141
8142static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008143posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008144{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008145 abort();
8146 /*NOTREACHED*/
8147 Py_FatalError("abort() called from Python code didn't abort!");
8148 return NULL;
8149}
Fred Drakebec628d1999-12-15 18:31:10 +00008150
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008151#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008152PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008153"startfile(filepath [, operation]) - Start a file with its associated\n\
8154application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008155\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008156When \"operation\" is not specified or \"open\", this acts like\n\
8157double-clicking the file in Explorer, or giving the file name as an\n\
8158argument to the DOS \"start\" command: the file is opened with whatever\n\
8159application (if any) its extension is associated.\n\
8160When another \"operation\" is given, it specifies what should be done with\n\
8161the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008162\n\
8163startfile returns as soon as the associated application is launched.\n\
8164There is no option to wait for the application to close, and no way\n\
8165to retrieve the application's exit status.\n\
8166\n\
8167The filepath is relative to the current directory. If you want to use\n\
8168an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008169the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008170
8171static PyObject *
8172win32_startfile(PyObject *self, PyObject *args)
8173{
8174 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00008175 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008176 HINSTANCE rc;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008177
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008178 PyObject *unipath, *woperation = NULL;
8179 if (!PyArg_ParseTuple(args, "U|s:startfile",
8180 &unipath, &operation)) {
8181 PyErr_Clear();
8182 goto normal;
8183 }
8184
8185 if (operation) {
8186 woperation = PyUnicode_DecodeASCII(operation,
8187 strlen(operation), NULL);
8188 if (!woperation) {
Georg Brandlad89dc82006-04-03 12:26:26 +00008189 PyErr_Clear();
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008190 operation = NULL;
Georg Brandlad89dc82006-04-03 12:26:26 +00008191 goto normal;
8192 }
Georg Brandlad89dc82006-04-03 12:26:26 +00008193 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008194
8195 Py_BEGIN_ALLOW_THREADS
8196 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
8197 PyUnicode_AS_UNICODE(unipath),
8198 NULL, NULL, SW_SHOWNORMAL);
8199 Py_END_ALLOW_THREADS
8200
8201 Py_XDECREF(woperation);
8202 if (rc <= (HINSTANCE)32) {
8203 PyObject *errval = win32_error_unicode("startfile",
8204 PyUnicode_AS_UNICODE(unipath));
8205 return errval;
8206 }
8207 Py_INCREF(Py_None);
8208 return Py_None;
Georg Brandlad89dc82006-04-03 12:26:26 +00008209
8210normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00008211 if (!PyArg_ParseTuple(args, "et|s:startfile",
8212 Py_FileSystemDefaultEncoding, &filepath,
8213 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00008214 return NULL;
8215 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00008216 rc = ShellExecute((HWND)0, operation, filepath,
8217 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008218 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00008219 if (rc <= (HINSTANCE)32) {
8220 PyObject *errval = win32_error("startfile", filepath);
8221 PyMem_Free(filepath);
8222 return errval;
8223 }
8224 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008225 Py_INCREF(Py_None);
8226 return Py_None;
8227}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008228#endif /* MS_WINDOWS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008229
Martin v. Löwis438b5342002-12-27 10:16:42 +00008230#ifdef HAVE_GETLOADAVG
8231PyDoc_STRVAR(posix_getloadavg__doc__,
8232"getloadavg() -> (float, float, float)\n\n\
8233Return the number of processes in the system run queue averaged over\n\
8234the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8235was unobtainable");
8236
8237static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008238posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008239{
8240 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008241 if (getloadavg(loadavg, 3)!=3) {
8242 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8243 return NULL;
8244 } else
8245 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
8246}
8247#endif
8248
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008249#ifdef MS_WINDOWS
8250
8251PyDoc_STRVAR(win32_urandom__doc__,
8252"urandom(n) -> str\n\n\
8253Return a string of n random bytes suitable for cryptographic use.");
8254
8255typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8256 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8257 DWORD dwFlags );
8258typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8259 BYTE *pbBuffer );
8260
8261static CRYPTGENRANDOM pCryptGenRandom = NULL;
Martin v. Löwisaf699dd2007-09-04 09:51:57 +00008262/* This handle is never explicitly released. Instead, the operating
8263 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008264static HCRYPTPROV hCryptProv = 0;
8265
Tim Peters4ad82172004-08-30 17:02:04 +00008266static PyObject*
8267win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008268{
Tim Petersd3115382004-08-30 17:36:46 +00008269 int howMany;
8270 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008271
Tim Peters4ad82172004-08-30 17:02:04 +00008272 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00008273 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00008274 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00008275 if (howMany < 0)
8276 return PyErr_Format(PyExc_ValueError,
8277 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008278
Tim Peters4ad82172004-08-30 17:02:04 +00008279 if (hCryptProv == 0) {
8280 HINSTANCE hAdvAPI32 = NULL;
8281 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008282
Tim Peters4ad82172004-08-30 17:02:04 +00008283 /* Obtain handle to the DLL containing CryptoAPI
8284 This should not fail */
8285 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8286 if(hAdvAPI32 == NULL)
8287 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008288
Tim Peters4ad82172004-08-30 17:02:04 +00008289 /* Obtain pointers to the CryptoAPI functions
8290 This will fail on some early versions of Win95 */
8291 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8292 hAdvAPI32,
8293 "CryptAcquireContextA");
8294 if (pCryptAcquireContext == NULL)
8295 return PyErr_Format(PyExc_NotImplementedError,
8296 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008297
Tim Peters4ad82172004-08-30 17:02:04 +00008298 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8299 hAdvAPI32, "CryptGenRandom");
Georg Brandl74bb7832006-09-06 06:03:59 +00008300 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00008301 return PyErr_Format(PyExc_NotImplementedError,
8302 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008303
Tim Peters4ad82172004-08-30 17:02:04 +00008304 /* Acquire context */
8305 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8306 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8307 return win32_error("CryptAcquireContext", NULL);
8308 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008309
Tim Peters4ad82172004-08-30 17:02:04 +00008310 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008311 result = PyString_FromStringAndSize(NULL, howMany);
Tim Petersd3115382004-08-30 17:36:46 +00008312 if (result != NULL) {
8313 /* Get random data */
Amaury Forgeot d'Arc74bd40d2008-07-21 21:06:46 +00008314 memset(PyString_AS_STRING(result), 0, howMany); /* zero seed */
Tim Petersd3115382004-08-30 17:36:46 +00008315 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008316 PyString_AS_STRING(result))) {
Tim Petersd3115382004-08-30 17:36:46 +00008317 Py_DECREF(result);
8318 return win32_error("CryptGenRandom", NULL);
8319 }
Tim Peters4ad82172004-08-30 17:02:04 +00008320 }
Tim Petersd3115382004-08-30 17:36:46 +00008321 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008322}
8323#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008324
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008325#ifdef __VMS
8326/* Use openssl random routine */
8327#include <openssl/rand.h>
8328PyDoc_STRVAR(vms_urandom__doc__,
8329"urandom(n) -> str\n\n\
8330Return a string of n random bytes suitable for cryptographic use.");
8331
8332static PyObject*
8333vms_urandom(PyObject *self, PyObject *args)
8334{
8335 int howMany;
8336 PyObject* result;
8337
8338 /* Read arguments */
8339 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8340 return NULL;
8341 if (howMany < 0)
8342 return PyErr_Format(PyExc_ValueError,
8343 "negative argument not allowed");
8344
8345 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008346 result = PyString_FromStringAndSize(NULL, howMany);
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008347 if (result != NULL) {
8348 /* Get random data */
8349 if (RAND_pseudo_bytes((unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008350 PyString_AS_STRING(result),
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008351 howMany) < 0) {
8352 Py_DECREF(result);
8353 return PyErr_Format(PyExc_ValueError,
8354 "RAND_pseudo_bytes");
8355 }
8356 }
8357 return result;
8358}
8359#endif
8360
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008361static PyMethodDef posix_methods[] = {
8362 {"access", posix_access, METH_VARARGS, posix_access__doc__},
8363#ifdef HAVE_TTYNAME
8364 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
8365#endif
8366 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008367#ifdef HAVE_CHFLAGS
8368 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
8369#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008370 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008371#ifdef HAVE_FCHMOD
8372 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
8373#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008374#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008375 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008376#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008377#ifdef HAVE_LCHMOD
8378 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
8379#endif /* HAVE_LCHMOD */
8380#ifdef HAVE_FCHOWN
8381 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
8382#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008383#ifdef HAVE_LCHFLAGS
8384 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
8385#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008386#ifdef HAVE_LCHOWN
8387 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
8388#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008389#ifdef HAVE_CHROOT
8390 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
8391#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008392#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00008393 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008394#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008395#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00008396 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008397#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00008398 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008399#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008400#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008401#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008402 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008403#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008404 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8405 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8406 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008407#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008408 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008409#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008410#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008411 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008412#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008413 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8414 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8415 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008416 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008417#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008418 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008419#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008420#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008421 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008422#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008423 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008424#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00008425 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008426#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008427 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8428 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8429 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008430#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00008431 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008432#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008433 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008434#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008435 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8436 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008437#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008438#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008439 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8440 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008441#if defined(PYOS_OS2)
8442 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8443 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8444#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008445#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008446#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00008447 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008448#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008449#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00008450 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008451#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008452#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00008453 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008454#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008455#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00008456 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008457#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008458#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008459 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008460#endif /* HAVE_GETEGID */
8461#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008462 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008463#endif /* HAVE_GETEUID */
8464#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008465 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008466#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008467#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00008468 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008469#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008470 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008471#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008472 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008473#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008474#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00008475 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008476#endif /* HAVE_GETPPID */
8477#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008478 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008479#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008480#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00008481 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008482#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008483#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008484 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008485#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008486#ifdef HAVE_KILLPG
8487 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8488#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008489#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008490 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008491#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008492#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008493 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008494#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008495 {"popen2", win32_popen2, METH_VARARGS},
8496 {"popen3", win32_popen3, METH_VARARGS},
8497 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00008498 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008499#else
8500#if defined(PYOS_OS2) && defined(PYCC_GCC)
8501 {"popen2", os2emx_popen2, METH_VARARGS},
8502 {"popen3", os2emx_popen3, METH_VARARGS},
8503 {"popen4", os2emx_popen4, METH_VARARGS},
8504#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008505#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008506#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008507#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008508 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008509#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008510#ifdef HAVE_SETEUID
8511 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8512#endif /* HAVE_SETEUID */
8513#ifdef HAVE_SETEGID
8514 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8515#endif /* HAVE_SETEGID */
8516#ifdef HAVE_SETREUID
8517 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8518#endif /* HAVE_SETREUID */
8519#ifdef HAVE_SETREGID
8520 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8521#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008522#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008523 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008524#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008525#ifdef HAVE_SETGROUPS
Georg Brandl96a8c392006-05-29 21:04:52 +00008526 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008527#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008528#ifdef HAVE_GETPGID
8529 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8530#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008531#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008532 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008533#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008534#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00008535 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008536#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008537#ifdef HAVE_WAIT3
8538 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8539#endif /* HAVE_WAIT3 */
8540#ifdef HAVE_WAIT4
8541 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8542#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008543#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008544 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008545#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008546#ifdef HAVE_GETSID
8547 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8548#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008549#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00008550 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008551#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008552#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008553 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008554#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008555#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008556 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008557#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008558#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008559 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008560#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008561 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8562 {"close", posix_close, METH_VARARGS, posix_close__doc__},
Georg Brandl309501a2008-01-19 20:22:13 +00008563 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008564 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8565 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8566 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8567 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8568 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8569 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8570 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00008571 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008572#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00008573 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008574#endif
8575#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008576 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008577#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008578#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008579 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8580#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008581#ifdef HAVE_DEVICE_MACROS
8582 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8583 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8584 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8585#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008586#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008587 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008588#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008589#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008590 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008591#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008592#ifdef HAVE_UNSETENV
8593 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8594#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008595 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008596#ifdef HAVE_FCHDIR
8597 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8598#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008599#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008600 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008601#endif
8602#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008603 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008604#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008605#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008606#ifdef WCOREDUMP
8607 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8608#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008609#ifdef WIFCONTINUED
8610 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8611#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008612#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008613 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008614#endif /* WIFSTOPPED */
8615#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008616 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008617#endif /* WIFSIGNALED */
8618#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008619 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008620#endif /* WIFEXITED */
8621#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008622 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008623#endif /* WEXITSTATUS */
8624#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008625 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008626#endif /* WTERMSIG */
8627#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008628 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008629#endif /* WSTOPSIG */
8630#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008631#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008632 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008633#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008634#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008635 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008636#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008637#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00008638 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008639#endif
8640#ifdef HAVE_TEMPNAM
8641 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8642#endif
8643#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00008644 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008645#endif
Fred Drakec9680921999-12-13 16:37:25 +00008646#ifdef HAVE_CONFSTR
8647 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8648#endif
8649#ifdef HAVE_SYSCONF
8650 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8651#endif
8652#ifdef HAVE_FPATHCONF
8653 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8654#endif
8655#ifdef HAVE_PATHCONF
8656 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8657#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008658 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008659#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00008660 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8661#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008662#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00008663 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008664#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008665 #ifdef MS_WINDOWS
8666 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8667 #endif
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008668 #ifdef __VMS
8669 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8670 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008671 {NULL, NULL} /* Sentinel */
8672};
8673
8674
Barry Warsaw4a342091996-12-19 23:50:02 +00008675static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008676ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008677{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008678 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008679}
8680
Guido van Rossumd48f2521997-12-05 22:19:34 +00008681#if defined(PYOS_OS2)
8682/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008683static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008684{
8685 APIRET rc;
8686 ULONG values[QSV_MAX+1];
8687 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008688 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008689
8690 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008691 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008692 Py_END_ALLOW_THREADS
8693
8694 if (rc != NO_ERROR) {
8695 os2_error(rc);
8696 return -1;
8697 }
8698
Fred Drake4d1e64b2002-04-15 19:40:07 +00008699 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8700 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8701 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8702 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8703 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8704 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8705 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008706
8707 switch (values[QSV_VERSION_MINOR]) {
8708 case 0: ver = "2.00"; break;
8709 case 10: ver = "2.10"; break;
8710 case 11: ver = "2.11"; break;
8711 case 30: ver = "3.00"; break;
8712 case 40: ver = "4.00"; break;
8713 case 50: ver = "5.00"; break;
8714 default:
Tim Peters885d4572001-11-28 20:27:42 +00008715 PyOS_snprintf(tmp, sizeof(tmp),
8716 "%d-%d", values[QSV_VERSION_MAJOR],
8717 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008718 ver = &tmp[0];
8719 }
8720
8721 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008722 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008723 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008724
8725 /* Add Indicator of Which Drive was Used to Boot the System */
8726 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8727 tmp[1] = ':';
8728 tmp[2] = '\0';
8729
Fred Drake4d1e64b2002-04-15 19:40:07 +00008730 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008731}
8732#endif
8733
Barry Warsaw4a342091996-12-19 23:50:02 +00008734static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008735all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008736{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008737#ifdef F_OK
8738 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008739#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008740#ifdef R_OK
8741 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008742#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008743#ifdef W_OK
8744 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008745#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008746#ifdef X_OK
8747 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008748#endif
Fred Drakec9680921999-12-13 16:37:25 +00008749#ifdef NGROUPS_MAX
8750 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8751#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008752#ifdef TMP_MAX
8753 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8754#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008755#ifdef WCONTINUED
8756 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8757#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008758#ifdef WNOHANG
8759 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008760#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008761#ifdef WUNTRACED
8762 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8763#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008764#ifdef O_RDONLY
8765 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8766#endif
8767#ifdef O_WRONLY
8768 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8769#endif
8770#ifdef O_RDWR
8771 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8772#endif
8773#ifdef O_NDELAY
8774 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8775#endif
8776#ifdef O_NONBLOCK
8777 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8778#endif
8779#ifdef O_APPEND
8780 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8781#endif
8782#ifdef O_DSYNC
8783 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8784#endif
8785#ifdef O_RSYNC
8786 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8787#endif
8788#ifdef O_SYNC
8789 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8790#endif
8791#ifdef O_NOCTTY
8792 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8793#endif
8794#ifdef O_CREAT
8795 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8796#endif
8797#ifdef O_EXCL
8798 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8799#endif
8800#ifdef O_TRUNC
8801 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8802#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008803#ifdef O_BINARY
8804 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8805#endif
8806#ifdef O_TEXT
8807 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8808#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008809#ifdef O_LARGEFILE
8810 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8811#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008812#ifdef O_SHLOCK
8813 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8814#endif
8815#ifdef O_EXLOCK
8816 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8817#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008818
Tim Peters5aa91602002-01-30 05:46:57 +00008819/* MS Windows */
8820#ifdef O_NOINHERIT
8821 /* Don't inherit in child processes. */
8822 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8823#endif
8824#ifdef _O_SHORT_LIVED
8825 /* Optimize for short life (keep in memory). */
8826 /* MS forgot to define this one with a non-underscore form too. */
8827 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8828#endif
8829#ifdef O_TEMPORARY
8830 /* Automatically delete when last handle is closed. */
8831 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8832#endif
8833#ifdef O_RANDOM
8834 /* Optimize for random access. */
8835 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8836#endif
8837#ifdef O_SEQUENTIAL
8838 /* Optimize for sequential access. */
8839 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8840#endif
8841
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008842/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00008843#ifdef O_ASYNC
8844 /* Send a SIGIO signal whenever input or output
8845 becomes available on file descriptor */
8846 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
8847#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008848#ifdef O_DIRECT
8849 /* Direct disk access. */
8850 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8851#endif
8852#ifdef O_DIRECTORY
8853 /* Must be a directory. */
8854 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8855#endif
8856#ifdef O_NOFOLLOW
8857 /* Do not follow links. */
8858 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8859#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00008860#ifdef O_NOATIME
8861 /* Do not update the access time. */
8862 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
8863#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008864
Barry Warsaw5676bd12003-01-07 20:57:09 +00008865 /* These come from sysexits.h */
8866#ifdef EX_OK
8867 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008868#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008869#ifdef EX_USAGE
8870 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008871#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008872#ifdef EX_DATAERR
8873 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008874#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008875#ifdef EX_NOINPUT
8876 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008877#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008878#ifdef EX_NOUSER
8879 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008880#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008881#ifdef EX_NOHOST
8882 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008883#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008884#ifdef EX_UNAVAILABLE
8885 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008886#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008887#ifdef EX_SOFTWARE
8888 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008889#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008890#ifdef EX_OSERR
8891 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008892#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008893#ifdef EX_OSFILE
8894 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008895#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008896#ifdef EX_CANTCREAT
8897 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008898#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008899#ifdef EX_IOERR
8900 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008901#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008902#ifdef EX_TEMPFAIL
8903 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008904#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008905#ifdef EX_PROTOCOL
8906 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008907#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008908#ifdef EX_NOPERM
8909 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008910#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008911#ifdef EX_CONFIG
8912 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008913#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008914#ifdef EX_NOTFOUND
8915 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008916#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008917
Guido van Rossum246bc171999-02-01 23:54:31 +00008918#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008919#if defined(PYOS_OS2) && defined(PYCC_GCC)
8920 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8921 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8922 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8923 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8924 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8925 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8926 if (ins(d, "P_PM", (long)P_PM)) return -1;
8927 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8928 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8929 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8930 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8931 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8932 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8933 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8934 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8935 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8936 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8937 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8938 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8939 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8940#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008941 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8942 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8943 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8944 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8945 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008946#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008947#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008948
Guido van Rossumd48f2521997-12-05 22:19:34 +00008949#if defined(PYOS_OS2)
8950 if (insertvalues(d)) return -1;
8951#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008952 return 0;
8953}
8954
8955
Tim Peters5aa91602002-01-30 05:46:57 +00008956#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008957#define INITFUNC initnt
8958#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008959
8960#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008961#define INITFUNC initos2
8962#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008963
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008964#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008965#define INITFUNC initposix
8966#define MODNAME "posix"
8967#endif
8968
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008969PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008970INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008971{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008972 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008973
Fred Drake4d1e64b2002-04-15 19:40:07 +00008974 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008975 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008976 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008977 if (m == NULL)
8978 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008979
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008980 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008981 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008982 Py_XINCREF(v);
8983 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008984 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008985 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008986
Fred Drake4d1e64b2002-04-15 19:40:07 +00008987 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008988 return;
8989
Fred Drake4d1e64b2002-04-15 19:40:07 +00008990 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008991 return;
8992
Fred Drake4d1e64b2002-04-15 19:40:07 +00008993 Py_INCREF(PyExc_OSError);
8994 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008995
Guido van Rossumb3d39562000-01-31 18:41:26 +00008996#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008997 if (posix_putenv_garbage == NULL)
8998 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008999#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009000
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009001 if (!initialized) {
9002 stat_result_desc.name = MODNAME ".stat_result";
9003 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9004 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9005 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9006 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9007 structseq_new = StatResultType.tp_new;
9008 StatResultType.tp_new = statresult_new;
9009
9010 statvfs_result_desc.name = MODNAME ".statvfs_result";
9011 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009012#ifdef NEED_TICKS_PER_SECOND
9013# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
9014 ticks_per_second = sysconf(_SC_CLK_TCK);
9015# elif defined(HZ)
9016 ticks_per_second = HZ;
9017# else
9018 ticks_per_second = 60; /* magic fallback value; may be bogus */
9019# endif
9020#endif
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009021 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009022 Py_INCREF((PyObject*) &StatResultType);
9023 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00009024 Py_INCREF((PyObject*) &StatVFSResultType);
9025 PyModule_AddObject(m, "statvfs_result",
9026 (PyObject*) &StatVFSResultType);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009027 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009028
9029#ifdef __APPLE__
9030 /*
9031 * Step 2 of weak-linking support on Mac OS X.
9032 *
9033 * The code below removes functions that are not available on the
9034 * currently active platform.
9035 *
9036 * This block allow one to use a python binary that was build on
9037 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9038 * OSX 10.4.
9039 */
9040#ifdef HAVE_FSTATVFS
9041 if (fstatvfs == NULL) {
9042 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9043 return;
9044 }
9045 }
9046#endif /* HAVE_FSTATVFS */
9047
9048#ifdef HAVE_STATVFS
9049 if (statvfs == NULL) {
9050 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9051 return;
9052 }
9053 }
9054#endif /* HAVE_STATVFS */
9055
9056# ifdef HAVE_LCHOWN
9057 if (lchown == NULL) {
9058 if (PyObject_DelAttrString(m, "lchown") == -1) {
9059 return;
9060 }
9061 }
9062#endif /* HAVE_LCHOWN */
9063
9064
9065#endif /* __APPLE__ */
9066
Guido van Rossumb6775db1994-08-01 11:34:53 +00009067}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009068
9069#ifdef __cplusplus
9070}
9071#endif
9072
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009073