blob: 4c580c46afcd9866dea985bb67e296b4ed538020 [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"
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000273#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000274#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000275#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000276#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277
Guido van Rossumd48f2521997-12-05 22:19:34 +0000278#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000279#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000280#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000281
Tim Petersbc2e10e2002-03-03 23:17:02 +0000282#ifndef MAXPATHLEN
Thomas Wouters1ddba602006-04-25 15:29:46 +0000283#if defined(PATH_MAX) && PATH_MAX > 1024
284#define MAXPATHLEN PATH_MAX
285#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000286#define MAXPATHLEN 1024
Thomas Wouters1ddba602006-04-25 15:29:46 +0000287#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000288#endif /* MAXPATHLEN */
289
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000290#ifdef UNION_WAIT
291/* Emulate some macros on systems that have a union instead of macros */
292
293#ifndef WIFEXITED
294#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
295#endif
296
297#ifndef WEXITSTATUS
298#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
299#endif
300
301#ifndef WTERMSIG
302#define WTERMSIG(u_wait) ((u_wait).w_termsig)
303#endif
304
Neal Norwitzd5a37542006-03-20 06:48:34 +0000305#define WAIT_TYPE union wait
306#define WAIT_STATUS_INT(s) (s.w_status)
307
308#else /* !UNION_WAIT */
309#define WAIT_TYPE int
310#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000311#endif /* UNION_WAIT */
312
Greg Wardb48bc172000-03-01 21:51:56 +0000313/* Don't use the "_r" form if we don't need it (also, won't have a
314 prototype for it, at least on Solaris -- maybe others as well?). */
315#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
316#define USE_CTERMID_R
317#endif
318
319#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
320#define USE_TMPNAM_R
321#endif
322
Fred Drake699f3522000-06-29 21:12:41 +0000323/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000324#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000325#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000326# define STAT win32_stat
327# define FSTAT win32_fstat
328# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000329#else
330# define STAT stat
331# define FSTAT fstat
332# define STRUCT_STAT struct stat
333#endif
334
Tim Peters11b23062003-04-23 02:39:17 +0000335#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000336#include <sys/mkdev.h>
337#else
338#if defined(MAJOR_IN_SYSMACROS)
339#include <sys/sysmacros.h>
340#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000341#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
342#include <sys/mkdev.h>
343#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000344#endif
Fred Drake699f3522000-06-29 21:12:41 +0000345
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000346/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000347#ifdef WITH_NEXT_FRAMEWORK
348/* On Darwin/MacOSX a shared library or framework has no access to
349** environ directly, we must obtain it with _NSGetEnviron().
350*/
351#include <crt_externs.h>
352static char **environ;
353#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000354extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000355#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000356
Barry Warsaw53699e91996-12-10 23:23:01 +0000357static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000358convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000359{
Barry Warsaw53699e91996-12-10 23:23:01 +0000360 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000361 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000362 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000363 if (d == NULL)
364 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000365#ifdef WITH_NEXT_FRAMEWORK
366 if (environ == NULL)
367 environ = *_NSGetEnviron();
368#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000369 if (environ == NULL)
370 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000371 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000372 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000373 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000374 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000375 char *p = strchr(*e, '=');
376 if (p == NULL)
377 continue;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000378 k = PyString_FromStringAndSize(*e, (int)(p-*e));
Guido van Rossum6a619f41999-08-03 19:41:10 +0000379 if (k == NULL) {
380 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000381 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000382 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000383 v = PyString_FromString(p+1);
Guido van Rossum6a619f41999-08-03 19:41:10 +0000384 if (v == NULL) {
385 PyErr_Clear();
386 Py_DECREF(k);
387 continue;
388 }
389 if (PyDict_GetItem(d, k) == NULL) {
390 if (PyDict_SetItem(d, k, v) != 0)
391 PyErr_Clear();
392 }
393 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000394 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000395 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000396#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000397 {
398 APIRET rc;
399 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
400
401 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000402 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000403 PyObject *v = PyString_FromString(buffer);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000404 PyDict_SetItemString(d, "BEGINLIBPATH", v);
405 Py_DECREF(v);
406 }
407 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
408 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000409 PyObject *v = PyString_FromString(buffer);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000410 PyDict_SetItemString(d, "ENDLIBPATH", v);
411 Py_DECREF(v);
412 }
413 }
414#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000415 return d;
416}
417
418
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000419/* Set a POSIX-specific error from errno, and return NULL */
420
Barry Warsawd58d7641998-07-23 16:14:40 +0000421static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000422posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000423{
Barry Warsawca74da41999-02-09 19:31:45 +0000424 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000425}
Barry Warsawd58d7641998-07-23 16:14:40 +0000426static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000427posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000428{
Barry Warsawca74da41999-02-09 19:31:45 +0000429 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000430}
431
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000432#ifdef Py_WIN_WIDE_FILENAMES
433static PyObject *
434posix_error_with_unicode_filename(Py_UNICODE* name)
435{
436 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
437}
438#endif /* Py_WIN_WIDE_FILENAMES */
439
440
Mark Hammondef8b6542001-05-13 08:04:26 +0000441static PyObject *
442posix_error_with_allocated_filename(char* name)
443{
444 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
445 PyMem_Free(name);
446 return rc;
447}
448
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000449#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000450static PyObject *
451win32_error(char* function, char* filename)
452{
Mark Hammond33a6da92000-08-15 00:46:38 +0000453 /* XXX We should pass the function name along in the future.
454 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000455 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000456 Windows error object, which is non-trivial.
457 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000458 errno = GetLastError();
459 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000460 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000461 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000462 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000463}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000464
465#ifdef Py_WIN_WIDE_FILENAMES
466static PyObject *
467win32_error_unicode(char* function, Py_UNICODE* filename)
468{
469 /* XXX - see win32_error for comments on 'function' */
470 errno = GetLastError();
471 if (filename)
472 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
473 else
474 return PyErr_SetFromWindowsErr(errno);
475}
476
477static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
478{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000479}
480
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000481static int
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000482convert_to_unicode(PyObject **param)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000483{
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000484 if (PyUnicode_CheckExact(*param))
485 Py_INCREF(*param);
486 else if (PyUnicode_Check(*param))
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000487 /* For a Unicode subtype that's not a Unicode object,
488 return a true Unicode object with the same data. */
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000489 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
490 PyUnicode_GET_SIZE(*param));
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000491 else
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000492 *param = PyUnicode_FromEncodedObject(*param,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000493 Py_FileSystemDefaultEncoding,
494 "strict");
495 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000496}
497
498#endif /* Py_WIN_WIDE_FILENAMES */
499
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000500#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000501
Guido van Rossumd48f2521997-12-05 22:19:34 +0000502#if defined(PYOS_OS2)
503/**********************************************************************
504 * Helper Function to Trim and Format OS/2 Messages
505 **********************************************************************/
506 static void
507os2_formatmsg(char *msgbuf, int msglen, char *reason)
508{
509 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
510
511 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
512 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
513
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000514 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000515 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
516 }
517
518 /* Add Optional Reason Text */
519 if (reason) {
520 strcat(msgbuf, " : ");
521 strcat(msgbuf, reason);
522 }
523}
524
525/**********************************************************************
526 * Decode an OS/2 Operating System Error Code
527 *
528 * A convenience function to lookup an OS/2 error code and return a
529 * text message we can use to raise a Python exception.
530 *
531 * Notes:
532 * The messages for errors returned from the OS/2 kernel reside in
533 * the file OSO001.MSG in the \OS2 directory hierarchy.
534 *
535 **********************************************************************/
536 static char *
537os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
538{
539 APIRET rc;
540 ULONG msglen;
541
542 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
543 Py_BEGIN_ALLOW_THREADS
544 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
545 errorcode, "oso001.msg", &msglen);
546 Py_END_ALLOW_THREADS
547
548 if (rc == NO_ERROR)
549 os2_formatmsg(msgbuf, msglen, reason);
550 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000551 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000552 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000553
554 return msgbuf;
555}
556
557/* Set an OS/2-specific error and return NULL. OS/2 kernel
558 errors are not in a global variable e.g. 'errno' nor are
559 they congruent with posix error numbers. */
560
561static PyObject * os2_error(int code)
562{
563 char text[1024];
564 PyObject *v;
565
566 os2_strerror(text, sizeof(text), code, "");
567
568 v = Py_BuildValue("(is)", code, text);
569 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000570 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000571 Py_DECREF(v);
572 }
573 return NULL; /* Signal to Python that an Exception is Pending */
574}
575
576#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000577
578/* POSIX generic methods */
579
Barry Warsaw53699e91996-12-10 23:23:01 +0000580static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000581posix_fildes(PyObject *fdobj, int (*func)(int))
582{
583 int fd;
584 int res;
585 fd = PyObject_AsFileDescriptor(fdobj);
586 if (fd < 0)
587 return NULL;
588 Py_BEGIN_ALLOW_THREADS
589 res = (*func)(fd);
590 Py_END_ALLOW_THREADS
591 if (res < 0)
592 return posix_error();
593 Py_INCREF(Py_None);
594 return Py_None;
595}
Guido van Rossum21142a01999-01-08 21:05:37 +0000596
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000597#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000598static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000599unicode_file_names(void)
600{
601 static int canusewide = -1;
602 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000603 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000604 the Windows NT family. */
605 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
606 }
607 return canusewide;
608}
609#endif
Tim Peters11b23062003-04-23 02:39:17 +0000610
Guido van Rossum21142a01999-01-08 21:05:37 +0000611static PyObject *
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000612posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000613{
Mark Hammondef8b6542001-05-13 08:04:26 +0000614 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000615 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000616 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000617 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000618 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000619 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000620 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000621 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000622 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000623 return posix_error_with_allocated_filename(path1);
624 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000625 Py_INCREF(Py_None);
626 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000627}
628
Barry Warsaw53699e91996-12-10 23:23:01 +0000629static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000630posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000631 char *format,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000632 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000633{
Mark Hammondef8b6542001-05-13 08:04:26 +0000634 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000635 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000636 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000637 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000638 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000639 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000640 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000641 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000642 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000643 PyMem_Free(path1);
644 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000645 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000646 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000647 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000648 Py_INCREF(Py_None);
649 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000650}
651
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000652#ifdef Py_WIN_WIDE_FILENAMES
653static PyObject*
654win32_1str(PyObject* args, char* func,
655 char* format, BOOL (__stdcall *funcA)(LPCSTR),
656 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
657{
658 PyObject *uni;
659 char *ansi;
660 BOOL result;
661 if (unicode_file_names()) {
662 if (!PyArg_ParseTuple(args, wformat, &uni))
663 PyErr_Clear();
664 else {
665 Py_BEGIN_ALLOW_THREADS
666 result = funcW(PyUnicode_AsUnicode(uni));
667 Py_END_ALLOW_THREADS
668 if (!result)
669 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
670 Py_INCREF(Py_None);
671 return Py_None;
672 }
673 }
674 if (!PyArg_ParseTuple(args, format, &ansi))
675 return NULL;
676 Py_BEGIN_ALLOW_THREADS
677 result = funcA(ansi);
678 Py_END_ALLOW_THREADS
679 if (!result)
680 return win32_error(func, ansi);
681 Py_INCREF(Py_None);
682 return Py_None;
683
684}
685
686/* This is a reimplementation of the C library's chdir function,
687 but one that produces Win32 errors instead of DOS error codes.
688 chdir is essentially a wrapper around SetCurrentDirectory; however,
689 it also needs to set "magic" environment variables indicating
690 the per-drive current directory, which are of the form =<drive>: */
691BOOL __stdcall
692win32_chdir(LPCSTR path)
693{
694 char new_path[MAX_PATH+1];
695 int result;
696 char env[4] = "=x:";
697
698 if(!SetCurrentDirectoryA(path))
699 return FALSE;
700 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
701 if (!result)
702 return FALSE;
703 /* In the ANSI API, there should not be any paths longer
704 than MAX_PATH. */
705 assert(result <= MAX_PATH+1);
706 if (strncmp(new_path, "\\\\", 2) == 0 ||
707 strncmp(new_path, "//", 2) == 0)
708 /* UNC path, nothing to do. */
709 return TRUE;
710 env[1] = new_path[0];
711 return SetEnvironmentVariableA(env, new_path);
712}
713
714/* The Unicode version differs from the ANSI version
715 since the current directory might exceed MAX_PATH characters */
716BOOL __stdcall
717win32_wchdir(LPCWSTR path)
718{
719 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
720 int result;
721 wchar_t env[4] = L"=x:";
722
723 if(!SetCurrentDirectoryW(path))
724 return FALSE;
725 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
726 if (!result)
727 return FALSE;
728 if (result > MAX_PATH+1) {
Hirokazu Yamamoto2c66b7c2008-10-09 18:06:58 +0000729 new_path = malloc(result * sizeof(wchar_t));
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000730 if (!new_path) {
731 SetLastError(ERROR_OUTOFMEMORY);
732 return FALSE;
733 }
Hirokazu Yamamoto2c66b7c2008-10-09 18:06:58 +0000734 result = GetCurrentDirectoryW(result, new_path);
735 if (!result) {
736 free(new_path);
737 return FALSE;
738 }
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000739 }
740 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
741 wcsncmp(new_path, L"//", 2) == 0)
742 /* UNC path, nothing to do. */
743 return TRUE;
744 env[1] = new_path[0];
745 result = SetEnvironmentVariableW(env, new_path);
746 if (new_path != _new_path)
747 free(new_path);
748 return result;
749}
750#endif
751
Martin v. Löwis14694662006-02-03 12:54:16 +0000752#ifdef MS_WINDOWS
753/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
754 - time stamps are restricted to second resolution
755 - file modification times suffer from forth-and-back conversions between
756 UTC and local time
757 Therefore, we implement our own stat, based on the Win32 API directly.
758*/
759#define HAVE_STAT_NSEC 1
760
761struct win32_stat{
762 int st_dev;
763 __int64 st_ino;
764 unsigned short st_mode;
765 int st_nlink;
766 int st_uid;
767 int st_gid;
768 int st_rdev;
769 __int64 st_size;
770 int st_atime;
771 int st_atime_nsec;
772 int st_mtime;
773 int st_mtime_nsec;
774 int st_ctime;
775 int st_ctime_nsec;
776};
777
778static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
779
780static void
781FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
782{
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000783 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
784 /* Cannot simply cast and dereference in_ptr,
785 since it might not be aligned properly */
786 __int64 in;
787 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000788 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
789 /* XXX Win32 supports time stamps past 2038; we currently don't */
790 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
791}
792
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000793static void
794time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
795{
796 /* XXX endianness */
797 __int64 out;
798 out = time_in + secs_between_epochs;
Martin v. Löwisf43893a2006-10-09 20:44:25 +0000799 out = out * 10000000 + nsec_in / 100;
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000800 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000801}
802
Martin v. Löwis14694662006-02-03 12:54:16 +0000803/* Below, we *know* that ugo+r is 0444 */
804#if _S_IREAD != 0400
805#error Unsupported C library
806#endif
807static int
808attributes_to_mode(DWORD attr)
809{
810 int m = 0;
811 if (attr & FILE_ATTRIBUTE_DIRECTORY)
812 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
813 else
814 m |= _S_IFREG;
815 if (attr & FILE_ATTRIBUTE_READONLY)
816 m |= 0444;
817 else
818 m |= 0666;
819 return m;
820}
821
822static int
823attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
824{
825 memset(result, 0, sizeof(*result));
826 result->st_mode = attributes_to_mode(info->dwFileAttributes);
827 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
828 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
829 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
830 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
831
832 return 0;
833}
834
Martin v. Löwis012bc722006-10-15 09:43:39 +0000835/* Emulate GetFileAttributesEx[AW] on Windows 95 */
836static int checked = 0;
837static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
838static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
839static void
840check_gfax()
841{
842 HINSTANCE hKernel32;
843 if (checked)
844 return;
845 checked = 1;
846 hKernel32 = GetModuleHandle("KERNEL32");
847 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
848 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
849}
850
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000851static BOOL
852attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
853{
854 HANDLE hFindFile;
855 WIN32_FIND_DATAA FileData;
856 hFindFile = FindFirstFileA(pszFile, &FileData);
857 if (hFindFile == INVALID_HANDLE_VALUE)
858 return FALSE;
859 FindClose(hFindFile);
860 pfad->dwFileAttributes = FileData.dwFileAttributes;
861 pfad->ftCreationTime = FileData.ftCreationTime;
862 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
863 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
864 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
865 pfad->nFileSizeLow = FileData.nFileSizeLow;
866 return TRUE;
867}
868
869static BOOL
870attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
871{
872 HANDLE hFindFile;
873 WIN32_FIND_DATAW FileData;
874 hFindFile = FindFirstFileW(pszFile, &FileData);
875 if (hFindFile == INVALID_HANDLE_VALUE)
876 return FALSE;
877 FindClose(hFindFile);
878 pfad->dwFileAttributes = FileData.dwFileAttributes;
879 pfad->ftCreationTime = FileData.ftCreationTime;
880 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
881 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
882 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
883 pfad->nFileSizeLow = FileData.nFileSizeLow;
884 return TRUE;
885}
886
Martin v. Löwis012bc722006-10-15 09:43:39 +0000887static BOOL WINAPI
888Py_GetFileAttributesExA(LPCSTR pszFile,
889 GET_FILEEX_INFO_LEVELS level,
890 LPVOID pv)
891{
892 BOOL result;
Martin v. Löwis012bc722006-10-15 09:43:39 +0000893 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
894 /* First try to use the system's implementation, if that is
895 available and either succeeds to gives an error other than
896 that it isn't implemented. */
897 check_gfax();
898 if (gfaxa) {
899 result = gfaxa(pszFile, level, pv);
900 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
901 return result;
902 }
903 /* It's either not present, or not implemented.
904 Emulate using FindFirstFile. */
905 if (level != GetFileExInfoStandard) {
906 SetLastError(ERROR_INVALID_PARAMETER);
907 return FALSE;
908 }
909 /* Use GetFileAttributes to validate that the file name
910 does not contain wildcards (which FindFirstFile would
911 accept). */
912 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
913 return FALSE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000914 return attributes_from_dir(pszFile, pfad);
Martin v. Löwis012bc722006-10-15 09:43:39 +0000915}
916
917static BOOL WINAPI
918Py_GetFileAttributesExW(LPCWSTR pszFile,
919 GET_FILEEX_INFO_LEVELS level,
920 LPVOID pv)
921{
922 BOOL result;
Martin v. Löwis012bc722006-10-15 09:43:39 +0000923 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
924 /* First try to use the system's implementation, if that is
925 available and either succeeds to gives an error other than
926 that it isn't implemented. */
927 check_gfax();
928 if (gfaxa) {
929 result = gfaxw(pszFile, level, pv);
930 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
931 return result;
932 }
933 /* It's either not present, or not implemented.
934 Emulate using FindFirstFile. */
935 if (level != GetFileExInfoStandard) {
936 SetLastError(ERROR_INVALID_PARAMETER);
937 return FALSE;
938 }
939 /* Use GetFileAttributes to validate that the file name
940 does not contain wildcards (which FindFirstFile would
941 accept). */
942 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
943 return FALSE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000944 return attributes_from_dir_w(pszFile, pfad);
Martin v. Löwis012bc722006-10-15 09:43:39 +0000945}
946
Martin v. Löwis14694662006-02-03 12:54:16 +0000947static int
948win32_stat(const char* path, struct win32_stat *result)
949{
950 WIN32_FILE_ATTRIBUTE_DATA info;
951 int code;
952 char *dot;
953 /* XXX not supported on Win95 and NT 3.x */
Martin v. Löwis012bc722006-10-15 09:43:39 +0000954 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000955 if (GetLastError() != ERROR_SHARING_VIOLATION) {
956 /* Protocol violation: we explicitly clear errno, instead of
957 setting it to a POSIX error. Callers should use GetLastError. */
958 errno = 0;
959 return -1;
960 } else {
961 /* Could not get attributes on open file. Fall back to
962 reading the directory. */
963 if (!attributes_from_dir(path, &info)) {
964 /* Very strange. This should not fail now */
965 errno = 0;
966 return -1;
967 }
968 }
Martin v. Löwis14694662006-02-03 12:54:16 +0000969 }
970 code = attribute_data_to_stat(&info, result);
971 if (code != 0)
972 return code;
973 /* Set S_IFEXEC if it is an .exe, .bat, ... */
974 dot = strrchr(path, '.');
975 if (dot) {
976 if (stricmp(dot, ".bat") == 0 ||
977 stricmp(dot, ".cmd") == 0 ||
978 stricmp(dot, ".exe") == 0 ||
979 stricmp(dot, ".com") == 0)
980 result->st_mode |= 0111;
981 }
982 return code;
983}
984
985static int
986win32_wstat(const wchar_t* path, struct win32_stat *result)
987{
988 int code;
989 const wchar_t *dot;
990 WIN32_FILE_ATTRIBUTE_DATA info;
991 /* XXX not supported on Win95 and NT 3.x */
Martin v. Löwis012bc722006-10-15 09:43:39 +0000992 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000993 if (GetLastError() != ERROR_SHARING_VIOLATION) {
994 /* Protocol violation: we explicitly clear errno, instead of
995 setting it to a POSIX error. Callers should use GetLastError. */
996 errno = 0;
997 return -1;
998 } else {
999 /* Could not get attributes on open file. Fall back to
1000 reading the directory. */
1001 if (!attributes_from_dir_w(path, &info)) {
1002 /* Very strange. This should not fail now */
1003 errno = 0;
1004 return -1;
1005 }
1006 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001007 }
1008 code = attribute_data_to_stat(&info, result);
1009 if (code < 0)
1010 return code;
1011 /* Set IFEXEC if it is an .exe, .bat, ... */
1012 dot = wcsrchr(path, '.');
1013 if (dot) {
1014 if (_wcsicmp(dot, L".bat") == 0 ||
1015 _wcsicmp(dot, L".cmd") == 0 ||
1016 _wcsicmp(dot, L".exe") == 0 ||
1017 _wcsicmp(dot, L".com") == 0)
1018 result->st_mode |= 0111;
1019 }
1020 return code;
1021}
1022
1023static int
1024win32_fstat(int file_number, struct win32_stat *result)
1025{
1026 BY_HANDLE_FILE_INFORMATION info;
1027 HANDLE h;
1028 int type;
1029
1030 h = (HANDLE)_get_osfhandle(file_number);
1031
1032 /* Protocol violation: we explicitly clear errno, instead of
1033 setting it to a POSIX error. Callers should use GetLastError. */
1034 errno = 0;
1035
1036 if (h == INVALID_HANDLE_VALUE) {
1037 /* This is really a C library error (invalid file handle).
1038 We set the Win32 error to the closes one matching. */
1039 SetLastError(ERROR_INVALID_HANDLE);
1040 return -1;
1041 }
1042 memset(result, 0, sizeof(*result));
1043
1044 type = GetFileType(h);
1045 if (type == FILE_TYPE_UNKNOWN) {
1046 DWORD error = GetLastError();
1047 if (error != 0) {
1048 return -1;
1049 }
1050 /* else: valid but unknown file */
1051 }
1052
1053 if (type != FILE_TYPE_DISK) {
1054 if (type == FILE_TYPE_CHAR)
1055 result->st_mode = _S_IFCHR;
1056 else if (type == FILE_TYPE_PIPE)
1057 result->st_mode = _S_IFIFO;
1058 return 0;
1059 }
1060
1061 if (!GetFileInformationByHandle(h, &info)) {
1062 return -1;
1063 }
1064
1065 /* similar to stat() */
1066 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1067 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1068 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1069 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1070 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1071 /* specific to fstat() */
1072 result->st_nlink = info.nNumberOfLinks;
1073 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1074 return 0;
1075}
1076
1077#endif /* MS_WINDOWS */
1078
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001079PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001080"stat_result: Result from stat or lstat.\n\n\
1081This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001082 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001083or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1084\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001085Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1086or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001087\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001088See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001089
1090static PyStructSequence_Field stat_result_fields[] = {
1091 {"st_mode", "protection bits"},
1092 {"st_ino", "inode"},
1093 {"st_dev", "device"},
1094 {"st_nlink", "number of hard links"},
1095 {"st_uid", "user ID of owner"},
1096 {"st_gid", "group ID of owner"},
1097 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001098 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1099 {NULL, "integer time of last access"},
1100 {NULL, "integer time of last modification"},
1101 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001102 {"st_atime", "time of last access"},
1103 {"st_mtime", "time of last modification"},
1104 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001105#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001106 {"st_blksize", "blocksize for filesystem I/O"},
1107#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001108#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001109 {"st_blocks", "number of blocks allocated"},
1110#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001111#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001112 {"st_rdev", "device type (if inode device)"},
1113#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001114#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1115 {"st_flags", "user defined flags for file"},
1116#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001117#ifdef HAVE_STRUCT_STAT_ST_GEN
1118 {"st_gen", "generation number"},
1119#endif
1120#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1121 {"st_birthtime", "time of creation"},
1122#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001123 {0}
1124};
1125
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001126#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001127#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001128#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001129#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001130#endif
1131
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001132#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001133#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1134#else
1135#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1136#endif
1137
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001138#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001139#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1140#else
1141#define ST_RDEV_IDX ST_BLOCKS_IDX
1142#endif
1143
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001144#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1145#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1146#else
1147#define ST_FLAGS_IDX ST_RDEV_IDX
1148#endif
1149
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001150#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001151#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001152#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001153#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001154#endif
1155
1156#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1157#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1158#else
1159#define ST_BIRTHTIME_IDX ST_GEN_IDX
1160#endif
1161
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001162static PyStructSequence_Desc stat_result_desc = {
1163 "stat_result", /* name */
1164 stat_result__doc__, /* doc */
1165 stat_result_fields,
1166 10
1167};
1168
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001169PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001170"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1171This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001172 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001173or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001174\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001175See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001176
1177static PyStructSequence_Field statvfs_result_fields[] = {
1178 {"f_bsize", },
1179 {"f_frsize", },
1180 {"f_blocks", },
1181 {"f_bfree", },
1182 {"f_bavail", },
1183 {"f_files", },
1184 {"f_ffree", },
1185 {"f_favail", },
1186 {"f_flag", },
1187 {"f_namemax",},
1188 {0}
1189};
1190
1191static PyStructSequence_Desc statvfs_result_desc = {
1192 "statvfs_result", /* name */
1193 statvfs_result__doc__, /* doc */
1194 statvfs_result_fields,
1195 10
1196};
1197
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001198static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001199static PyTypeObject StatResultType;
1200static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001201static newfunc structseq_new;
1202
1203static PyObject *
1204statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1205{
1206 PyStructSequence *result;
1207 int i;
1208
1209 result = (PyStructSequence*)structseq_new(type, args, kwds);
1210 if (!result)
1211 return NULL;
1212 /* If we have been initialized from a tuple,
1213 st_?time might be set to None. Initialize it
1214 from the int slots. */
1215 for (i = 7; i <= 9; i++) {
1216 if (result->ob_item[i+3] == Py_None) {
1217 Py_DECREF(Py_None);
1218 Py_INCREF(result->ob_item[i]);
1219 result->ob_item[i+3] = result->ob_item[i];
1220 }
1221 }
1222 return (PyObject*)result;
1223}
1224
1225
1226
1227/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001228static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001229
1230PyDoc_STRVAR(stat_float_times__doc__,
1231"stat_float_times([newval]) -> oldval\n\n\
1232Determine whether os.[lf]stat represents time stamps as float objects.\n\
1233If newval is True, future calls to stat() return floats, if it is False,\n\
1234future calls return ints. \n\
1235If newval is omitted, return the current setting.\n");
1236
1237static PyObject*
1238stat_float_times(PyObject* self, PyObject *args)
1239{
1240 int newval = -1;
1241 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1242 return NULL;
1243 if (newval == -1)
1244 /* Return old value */
1245 return PyBool_FromLong(_stat_float_times);
1246 _stat_float_times = newval;
1247 Py_INCREF(Py_None);
1248 return Py_None;
1249}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001250
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001251static void
1252fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1253{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001254 PyObject *fval,*ival;
1255#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001256 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001257#else
1258 ival = PyInt_FromLong((long)sec);
1259#endif
Neal Norwitze0a81af2006-08-12 01:50:38 +00001260 if (!ival)
1261 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001262 if (_stat_float_times) {
1263 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1264 } else {
1265 fval = ival;
1266 Py_INCREF(fval);
1267 }
1268 PyStructSequence_SET_ITEM(v, index, ival);
1269 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001270}
1271
Tim Peters5aa91602002-01-30 05:46:57 +00001272/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001273 (used by posix_stat() and posix_fstat()) */
1274static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001275_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001276{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001277 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001278 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001279 if (v == NULL)
1280 return NULL;
1281
Martin v. Löwis14694662006-02-03 12:54:16 +00001282 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001283#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001284 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001285 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001286#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001287 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001288#endif
1289#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001290 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001291 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001292#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001293 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001294#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001295 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1296 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1297 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001298#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001299 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001300 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001301#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001302 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001303#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001304
Martin v. Löwis14694662006-02-03 12:54:16 +00001305#if defined(HAVE_STAT_TV_NSEC)
1306 ansec = st->st_atim.tv_nsec;
1307 mnsec = st->st_mtim.tv_nsec;
1308 cnsec = st->st_ctim.tv_nsec;
1309#elif defined(HAVE_STAT_TV_NSEC2)
1310 ansec = st->st_atimespec.tv_nsec;
1311 mnsec = st->st_mtimespec.tv_nsec;
1312 cnsec = st->st_ctimespec.tv_nsec;
1313#elif defined(HAVE_STAT_NSEC)
1314 ansec = st->st_atime_nsec;
1315 mnsec = st->st_mtime_nsec;
1316 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001317#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001318 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001319#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001320 fill_time(v, 7, st->st_atime, ansec);
1321 fill_time(v, 8, st->st_mtime, mnsec);
1322 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001323
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001324#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001325 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001326 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001327#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001328#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001329 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001330 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001331#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001332#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001333 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001334 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001335#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001336#ifdef HAVE_STRUCT_STAT_ST_GEN
1337 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001338 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001339#endif
1340#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1341 {
1342 PyObject *val;
1343 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001344 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001345#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001346 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001347#else
1348 bnsec = 0;
1349#endif
1350 if (_stat_float_times) {
1351 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1352 } else {
1353 val = PyInt_FromLong((long)bsec);
1354 }
1355 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1356 val);
1357 }
1358#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001359#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1360 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001361 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001362#endif
Fred Drake699f3522000-06-29 21:12:41 +00001363
1364 if (PyErr_Occurred()) {
1365 Py_DECREF(v);
1366 return NULL;
1367 }
1368
1369 return v;
1370}
1371
Martin v. Löwisd8948722004-06-02 09:57:56 +00001372#ifdef MS_WINDOWS
1373
1374/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1375 where / can be used in place of \ and the trailing slash is optional.
1376 Both SERVER and SHARE must have at least one character.
1377*/
1378
1379#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1380#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001381#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001382#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001383#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001384
Tim Peters4ad82172004-08-30 17:02:04 +00001385static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001386IsUNCRootA(char *path, int pathlen)
1387{
1388 #define ISSLASH ISSLASHA
1389
1390 int i, share;
1391
1392 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1393 /* minimum UNCRoot is \\x\y */
1394 return FALSE;
1395 for (i = 2; i < pathlen ; i++)
1396 if (ISSLASH(path[i])) break;
1397 if (i == 2 || i == pathlen)
1398 /* do not allow \\\SHARE or \\SERVER */
1399 return FALSE;
1400 share = i+1;
1401 for (i = share; i < pathlen; i++)
1402 if (ISSLASH(path[i])) break;
1403 return (i != share && (i == pathlen || i == pathlen-1));
1404
1405 #undef ISSLASH
1406}
1407
1408#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001409static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001410IsUNCRootW(Py_UNICODE *path, int pathlen)
1411{
1412 #define ISSLASH ISSLASHW
1413
1414 int i, share;
1415
1416 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1417 /* minimum UNCRoot is \\x\y */
1418 return FALSE;
1419 for (i = 2; i < pathlen ; i++)
1420 if (ISSLASH(path[i])) break;
1421 if (i == 2 || i == pathlen)
1422 /* do not allow \\\SHARE or \\SERVER */
1423 return FALSE;
1424 share = i+1;
1425 for (i = share; i < pathlen; i++)
1426 if (ISSLASH(path[i])) break;
1427 return (i != share && (i == pathlen || i == pathlen-1));
1428
1429 #undef ISSLASH
1430}
1431#endif /* Py_WIN_WIDE_FILENAMES */
1432#endif /* MS_WINDOWS */
1433
Barry Warsaw53699e91996-12-10 23:23:01 +00001434static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001435posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001436 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001437#ifdef __VMS
1438 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1439#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001440 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001441#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001442 char *wformat,
1443 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001444{
Fred Drake699f3522000-06-29 21:12:41 +00001445 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001446 char *path = NULL; /* pass this to stat; do not free() it */
1447 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001448 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001449 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001450
1451#ifdef Py_WIN_WIDE_FILENAMES
1452 /* If on wide-character-capable OS see if argument
1453 is Unicode and if so use wide API. */
1454 if (unicode_file_names()) {
1455 PyUnicodeObject *po;
1456 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001457 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1458
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001459 Py_BEGIN_ALLOW_THREADS
1460 /* PyUnicode_AS_UNICODE result OK without
1461 thread lock as it is a simple dereference. */
1462 res = wstatfunc(wpath, &st);
1463 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001464
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001465 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001466 return win32_error_unicode("stat", wpath);
1467 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001468 }
1469 /* Drop the argument parsing error as narrow strings
1470 are also valid. */
1471 PyErr_Clear();
1472 }
1473#endif
1474
Tim Peters5aa91602002-01-30 05:46:57 +00001475 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001476 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001477 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001478 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001479
Barry Warsaw53699e91996-12-10 23:23:01 +00001480 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001481 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001482 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001483
1484 if (res != 0) {
1485#ifdef MS_WINDOWS
1486 result = win32_error("stat", pathfree);
1487#else
1488 result = posix_error_with_filename(pathfree);
1489#endif
1490 }
1491 else
1492 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001493
Tim Peters500bd032001-12-19 19:05:01 +00001494 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001495 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001496}
1497
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001498/* POSIX methods */
1499
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001500PyDoc_STRVAR(posix_access__doc__,
Georg Brandl7a284472007-01-27 19:38:50 +00001501"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001502Use the real uid/gid to test for access to a path. Note that most\n\
1503operations will use the effective uid/gid, therefore this routine can\n\
1504be used in a suid/sgid environment to test if the invoking user has the\n\
1505specified access to the path. The mode argument can be F_OK to test\n\
1506existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001507
1508static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001509posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001510{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001511 char *path;
1512 int mode;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001513
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001514#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001515 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001516 if (unicode_file_names()) {
1517 PyUnicodeObject *po;
1518 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1519 Py_BEGIN_ALLOW_THREADS
1520 /* PyUnicode_AS_UNICODE OK without thread lock as
1521 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001522 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001523 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001524 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001525 }
1526 /* Drop the argument parsing error as narrow strings
1527 are also valid. */
1528 PyErr_Clear();
1529 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001530 if (!PyArg_ParseTuple(args, "eti:access",
1531 Py_FileSystemDefaultEncoding, &path, &mode))
1532 return 0;
1533 Py_BEGIN_ALLOW_THREADS
1534 attr = GetFileAttributesA(path);
1535 Py_END_ALLOW_THREADS
1536 PyMem_Free(path);
1537finish:
1538 if (attr == 0xFFFFFFFF)
1539 /* File does not exist, or cannot read attributes */
1540 return PyBool_FromLong(0);
1541 /* Access is possible if either write access wasn't requested, or
Martin v. Löwis7b3cc062007-12-03 23:09:04 +00001542 the file isn't read-only, or if it's a directory, as there are
1543 no read-only directories on Windows. */
1544 return PyBool_FromLong(!(mode & 2)
1545 || !(attr & FILE_ATTRIBUTE_READONLY)
1546 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001547#else
1548 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001549 if (!PyArg_ParseTuple(args, "eti:access",
1550 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001551 return NULL;
1552 Py_BEGIN_ALLOW_THREADS
1553 res = access(path, mode);
1554 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001555 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001556 return PyBool_FromLong(res == 0);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001557#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001558}
1559
Guido van Rossumd371ff11999-01-25 16:12:23 +00001560#ifndef F_OK
1561#define F_OK 0
1562#endif
1563#ifndef R_OK
1564#define R_OK 4
1565#endif
1566#ifndef W_OK
1567#define W_OK 2
1568#endif
1569#ifndef X_OK
1570#define X_OK 1
1571#endif
1572
1573#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001574PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001575"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001576Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001577
1578static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001579posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001580{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001581 int id;
1582 char *ret;
1583
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001584 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001585 return NULL;
1586
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001587#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001588 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001589 if (id == 0) {
1590 ret = ttyname();
1591 }
1592 else {
1593 ret = NULL;
1594 }
1595#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001596 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001597#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001598 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001599 return posix_error();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001600 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001601}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001602#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001603
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001604#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001605PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001606"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001607Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001608
1609static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001610posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001611{
1612 char *ret;
1613 char buffer[L_ctermid];
1614
Greg Wardb48bc172000-03-01 21:51:56 +00001615#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001616 ret = ctermid_r(buffer);
1617#else
1618 ret = ctermid(buffer);
1619#endif
1620 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001621 return posix_error();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001622 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001623}
1624#endif
1625
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001626PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001627"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001628Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001629
Barry Warsaw53699e91996-12-10 23:23:01 +00001630static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001631posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001632{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001633#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001634 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001635#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001636 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001637#elif defined(__VMS)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001638 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001639#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001640 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001641#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001642}
1643
Fred Drake4d1e64b2002-04-15 19:40:07 +00001644#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001645PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001646"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001647Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001648opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001649
1650static PyObject *
1651posix_fchdir(PyObject *self, PyObject *fdobj)
1652{
1653 return posix_fildes(fdobj, fchdir);
1654}
1655#endif /* HAVE_FCHDIR */
1656
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001657
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001658PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001659"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001660Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001661
Barry Warsaw53699e91996-12-10 23:23:01 +00001662static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001663posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001664{
Mark Hammondef8b6542001-05-13 08:04:26 +00001665 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001666 int i;
1667 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001668#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001669 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001670 if (unicode_file_names()) {
1671 PyUnicodeObject *po;
1672 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1673 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001674 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1675 if (attr != 0xFFFFFFFF) {
1676 if (i & _S_IWRITE)
1677 attr &= ~FILE_ATTRIBUTE_READONLY;
1678 else
1679 attr |= FILE_ATTRIBUTE_READONLY;
1680 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1681 }
1682 else
1683 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001684 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001685 if (!res)
1686 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001687 PyUnicode_AS_UNICODE(po));
1688 Py_INCREF(Py_None);
1689 return Py_None;
1690 }
1691 /* Drop the argument parsing error as narrow strings
1692 are also valid. */
1693 PyErr_Clear();
1694 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001695 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1696 &path, &i))
1697 return NULL;
1698 Py_BEGIN_ALLOW_THREADS
1699 attr = GetFileAttributesA(path);
1700 if (attr != 0xFFFFFFFF) {
1701 if (i & _S_IWRITE)
1702 attr &= ~FILE_ATTRIBUTE_READONLY;
1703 else
1704 attr |= FILE_ATTRIBUTE_READONLY;
1705 res = SetFileAttributesA(path, attr);
1706 }
1707 else
1708 res = 0;
1709 Py_END_ALLOW_THREADS
1710 if (!res) {
1711 win32_error("chmod", path);
1712 PyMem_Free(path);
1713 return NULL;
1714 }
Martin v. Löwis9f485bc2006-05-08 05:25:56 +00001715 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001716 Py_INCREF(Py_None);
1717 return Py_None;
1718#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001719 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001720 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001721 return NULL;
1722 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001723 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001724 Py_END_ALLOW_THREADS
1725 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001726 return posix_error_with_allocated_filename(path);
1727 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001728 Py_INCREF(Py_None);
1729 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001730#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001731}
1732
Christian Heimes36281872007-11-30 21:11:28 +00001733#ifdef HAVE_FCHMOD
1734PyDoc_STRVAR(posix_fchmod__doc__,
1735"fchmod(fd, mode)\n\n\
1736Change the access permissions of the file given by file\n\
1737descriptor fd.");
1738
1739static PyObject *
1740posix_fchmod(PyObject *self, PyObject *args)
1741{
1742 int fd, mode, res;
1743 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1744 return NULL;
1745 Py_BEGIN_ALLOW_THREADS
1746 res = fchmod(fd, mode);
1747 Py_END_ALLOW_THREADS
1748 if (res < 0)
1749 return posix_error();
1750 Py_RETURN_NONE;
1751}
1752#endif /* HAVE_FCHMOD */
1753
1754#ifdef HAVE_LCHMOD
1755PyDoc_STRVAR(posix_lchmod__doc__,
1756"lchmod(path, mode)\n\n\
1757Change the access permissions of a file. If path is a symlink, this\n\
1758affects the link itself rather than the target.");
1759
1760static PyObject *
1761posix_lchmod(PyObject *self, PyObject *args)
1762{
1763 char *path = NULL;
1764 int i;
1765 int res;
1766 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1767 &path, &i))
1768 return NULL;
1769 Py_BEGIN_ALLOW_THREADS
1770 res = lchmod(path, i);
1771 Py_END_ALLOW_THREADS
1772 if (res < 0)
1773 return posix_error_with_allocated_filename(path);
1774 PyMem_Free(path);
1775 Py_RETURN_NONE;
1776}
1777#endif /* HAVE_LCHMOD */
1778
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001779
Martin v. Löwis382abef2007-02-19 10:55:19 +00001780#ifdef HAVE_CHFLAGS
1781PyDoc_STRVAR(posix_chflags__doc__,
1782"chflags(path, flags)\n\n\
1783Set file flags.");
1784
1785static PyObject *
1786posix_chflags(PyObject *self, PyObject *args)
1787{
1788 char *path;
1789 unsigned long flags;
1790 int res;
1791 if (!PyArg_ParseTuple(args, "etk:chflags",
1792 Py_FileSystemDefaultEncoding, &path, &flags))
1793 return NULL;
1794 Py_BEGIN_ALLOW_THREADS
1795 res = chflags(path, flags);
1796 Py_END_ALLOW_THREADS
1797 if (res < 0)
1798 return posix_error_with_allocated_filename(path);
1799 PyMem_Free(path);
1800 Py_INCREF(Py_None);
1801 return Py_None;
1802}
1803#endif /* HAVE_CHFLAGS */
1804
1805#ifdef HAVE_LCHFLAGS
1806PyDoc_STRVAR(posix_lchflags__doc__,
1807"lchflags(path, flags)\n\n\
1808Set file flags.\n\
1809This function will not follow symbolic links.");
1810
1811static PyObject *
1812posix_lchflags(PyObject *self, PyObject *args)
1813{
1814 char *path;
1815 unsigned long flags;
1816 int res;
1817 if (!PyArg_ParseTuple(args, "etk:lchflags",
1818 Py_FileSystemDefaultEncoding, &path, &flags))
1819 return NULL;
1820 Py_BEGIN_ALLOW_THREADS
1821 res = lchflags(path, flags);
1822 Py_END_ALLOW_THREADS
1823 if (res < 0)
1824 return posix_error_with_allocated_filename(path);
1825 PyMem_Free(path);
1826 Py_INCREF(Py_None);
1827 return Py_None;
1828}
1829#endif /* HAVE_LCHFLAGS */
1830
Martin v. Löwis244edc82001-10-04 22:44:26 +00001831#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001832PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001833"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001834Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001835
1836static PyObject *
1837posix_chroot(PyObject *self, PyObject *args)
1838{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001839 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001840}
1841#endif
1842
Guido van Rossum21142a01999-01-08 21:05:37 +00001843#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001844PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001845"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001846force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001847
1848static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001849posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001850{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001851 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001852}
1853#endif /* HAVE_FSYNC */
1854
1855#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001856
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001857#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001858extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1859#endif
1860
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001861PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001862"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001863force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001864 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001865
1866static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001867posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001868{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001869 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001870}
1871#endif /* HAVE_FDATASYNC */
1872
1873
Fredrik Lundh10723342000-07-10 16:38:09 +00001874#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001875PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001876"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001877Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001878
Barry Warsaw53699e91996-12-10 23:23:01 +00001879static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001880posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001881{
Mark Hammondef8b6542001-05-13 08:04:26 +00001882 char *path = NULL;
Gregory P. Smithf48da8f2008-03-18 19:05:32 +00001883 long uid, gid;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001884 int res;
Gregory P. Smithf48da8f2008-03-18 19:05:32 +00001885 if (!PyArg_ParseTuple(args, "etll:chown",
Tim Peters5aa91602002-01-30 05:46:57 +00001886 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001887 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001888 return NULL;
1889 Py_BEGIN_ALLOW_THREADS
1890 res = chown(path, (uid_t) uid, (gid_t) gid);
1891 Py_END_ALLOW_THREADS
1892 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001893 return posix_error_with_allocated_filename(path);
1894 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001895 Py_INCREF(Py_None);
1896 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001897}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001898#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001899
Christian Heimes36281872007-11-30 21:11:28 +00001900#ifdef HAVE_FCHOWN
1901PyDoc_STRVAR(posix_fchown__doc__,
1902"fchown(fd, uid, gid)\n\n\
1903Change the owner and group id of the file given by file descriptor\n\
1904fd to the numeric uid and gid.");
1905
1906static PyObject *
1907posix_fchown(PyObject *self, PyObject *args)
1908{
1909 int fd, uid, gid;
1910 int res;
1911 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
1912 return NULL;
1913 Py_BEGIN_ALLOW_THREADS
1914 res = fchown(fd, (uid_t) uid, (gid_t) gid);
1915 Py_END_ALLOW_THREADS
1916 if (res < 0)
1917 return posix_error();
1918 Py_RETURN_NONE;
1919}
1920#endif /* HAVE_FCHOWN */
1921
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001922#ifdef HAVE_LCHOWN
1923PyDoc_STRVAR(posix_lchown__doc__,
1924"lchown(path, uid, gid)\n\n\
1925Change the owner and group id of path to the numeric uid and gid.\n\
1926This function will not follow symbolic links.");
1927
1928static PyObject *
1929posix_lchown(PyObject *self, PyObject *args)
1930{
1931 char *path = NULL;
1932 int uid, gid;
1933 int res;
1934 if (!PyArg_ParseTuple(args, "etii:lchown",
1935 Py_FileSystemDefaultEncoding, &path,
1936 &uid, &gid))
1937 return NULL;
1938 Py_BEGIN_ALLOW_THREADS
1939 res = lchown(path, (uid_t) uid, (gid_t) gid);
1940 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001941 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001942 return posix_error_with_allocated_filename(path);
1943 PyMem_Free(path);
1944 Py_INCREF(Py_None);
1945 return Py_None;
1946}
1947#endif /* HAVE_LCHOWN */
1948
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001949
Guido van Rossum36bc6801995-06-14 22:54:23 +00001950#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001951PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001952"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001953Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001954
Barry Warsaw53699e91996-12-10 23:23:01 +00001955static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001956posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001957{
Facundo Batista5596b0c2008-06-22 13:36:20 +00001958 int bufsize_incr = 1024;
1959 int bufsize = 0;
1960 char *tmpbuf = NULL;
1961 char *res = NULL;
1962 PyObject *dynamic_return;
Neal Norwitze241ce82003-02-17 18:17:05 +00001963
Barry Warsaw53699e91996-12-10 23:23:01 +00001964 Py_BEGIN_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00001965 do {
1966 bufsize = bufsize + bufsize_incr;
1967 tmpbuf = malloc(bufsize);
1968 if (tmpbuf == NULL) {
1969 break;
1970 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001971#if defined(PYOS_OS2) && defined(PYCC_GCC)
Facundo Batista5596b0c2008-06-22 13:36:20 +00001972 res = _getcwd2(tmpbuf, bufsize);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001973#else
Facundo Batista5596b0c2008-06-22 13:36:20 +00001974 res = getcwd(tmpbuf, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001975#endif
Facundo Batista5596b0c2008-06-22 13:36:20 +00001976
1977 if (res == NULL) {
1978 free(tmpbuf);
1979 }
1980 } while ((res == NULL) && (errno == ERANGE));
Barry Warsaw53699e91996-12-10 23:23:01 +00001981 Py_END_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00001982
Guido van Rossumff4949e1992-08-05 19:58:53 +00001983 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001984 return posix_error();
Facundo Batista5596b0c2008-06-22 13:36:20 +00001985
1986 dynamic_return = PyString_FromString(tmpbuf);
1987 free(tmpbuf);
1988
1989 return dynamic_return;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001990}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001991
Walter Dörwald3b918c32002-11-21 20:18:46 +00001992#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001993PyDoc_STRVAR(posix_getcwdu__doc__,
1994"getcwdu() -> path\n\n\
1995Return a unicode string representing the current working directory.");
1996
1997static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001998posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001999{
2000 char buf[1026];
2001 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002002
2003#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002004 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002005 if (unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002006 wchar_t wbuf[1026];
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002007 wchar_t *wbuf2 = wbuf;
2008 PyObject *resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002009 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002010 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2011 /* If the buffer is large enough, len does not include the
2012 terminating \0. If the buffer is too small, len includes
2013 the space needed for the terminator. */
2014 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2015 wbuf2 = malloc(len * sizeof(wchar_t));
2016 if (wbuf2)
2017 len = GetCurrentDirectoryW(len, wbuf2);
2018 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002019 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002020 if (!wbuf2) {
2021 PyErr_NoMemory();
2022 return NULL;
2023 }
2024 if (!len) {
2025 if (wbuf2 != wbuf) free(wbuf2);
2026 return win32_error("getcwdu", NULL);
2027 }
2028 resobj = PyUnicode_FromWideChar(wbuf2, len);
2029 if (wbuf2 != wbuf) free(wbuf2);
2030 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002031 }
2032#endif
2033
2034 Py_BEGIN_ALLOW_THREADS
2035#if defined(PYOS_OS2) && defined(PYCC_GCC)
2036 res = _getcwd2(buf, sizeof buf);
2037#else
2038 res = getcwd(buf, sizeof buf);
2039#endif
2040 Py_END_ALLOW_THREADS
2041 if (res == NULL)
2042 return posix_error();
2043 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
2044}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002045#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00002046#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002047
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002048
Guido van Rossumb6775db1994-08-01 11:34:53 +00002049#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002050PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002051"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002052Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002053
Barry Warsaw53699e91996-12-10 23:23:01 +00002054static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002055posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002056{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002057 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002058}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002059#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002060
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002061
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002062PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002063"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002064Return a list containing the names of the entries in the directory.\n\
2065\n\
2066 path: path of directory to list\n\
2067\n\
2068The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002069entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002070
Barry Warsaw53699e91996-12-10 23:23:01 +00002071static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002072posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002073{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002074 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002075 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002076#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002077
Barry Warsaw53699e91996-12-10 23:23:01 +00002078 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002079 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002080 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002081 WIN32_FIND_DATA FileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002082 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00002083 char *bufptr = namebuf;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002084 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002085
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002086#ifdef Py_WIN_WIDE_FILENAMES
2087 /* If on wide-character-capable OS see if argument
2088 is Unicode and if so use wide API. */
2089 if (unicode_file_names()) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002090 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002091 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2092 WIN32_FIND_DATAW wFileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002093 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002094 Py_UNICODE wch;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002095 /* Overallocate for \\*.*\0 */
2096 len = PyUnicode_GET_SIZE(po);
2097 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2098 if (!wnamebuf) {
2099 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002100 return NULL;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002101 }
2102 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2103 wch = len > 0 ? wnamebuf[len-1] : '\0';
2104 if (wch != L'/' && wch != L'\\' && wch != L':')
2105 wnamebuf[len++] = L'\\';
2106 wcscpy(wnamebuf + len, L"*.*");
2107 if ((d = PyList_New(0)) == NULL) {
2108 free(wnamebuf);
2109 return NULL;
2110 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002111 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2112 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002113 int error = GetLastError();
2114 if (error == ERROR_FILE_NOT_FOUND) {
2115 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002116 return d;
2117 }
2118 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002119 win32_error_unicode("FindFirstFileW", wnamebuf);
2120 free(wnamebuf);
2121 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002122 }
2123 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002124 /* Skip over . and .. */
2125 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2126 wcscmp(wFileData.cFileName, L"..") != 0) {
2127 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2128 if (v == NULL) {
2129 Py_DECREF(d);
2130 d = NULL;
2131 break;
2132 }
2133 if (PyList_Append(d, v) != 0) {
2134 Py_DECREF(v);
2135 Py_DECREF(d);
2136 d = NULL;
2137 break;
2138 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002139 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002140 }
Georg Brandl622927b2006-03-07 12:48:03 +00002141 Py_BEGIN_ALLOW_THREADS
2142 result = FindNextFileW(hFindFile, &wFileData);
2143 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00002144 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2145 it got to the end of the directory. */
2146 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2147 Py_DECREF(d);
2148 win32_error_unicode("FindNextFileW", wnamebuf);
2149 FindClose(hFindFile);
2150 free(wnamebuf);
2151 return NULL;
2152 }
Georg Brandl622927b2006-03-07 12:48:03 +00002153 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002154
2155 if (FindClose(hFindFile) == FALSE) {
2156 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002157 win32_error_unicode("FindClose", wnamebuf);
2158 free(wnamebuf);
2159 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002160 }
Martin v. Löwise3edaea2006-05-15 05:51:36 +00002161 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002162 return d;
2163 }
2164 /* Drop the argument parsing error as narrow strings
2165 are also valid. */
2166 PyErr_Clear();
2167 }
2168#endif
2169
Tim Peters5aa91602002-01-30 05:46:57 +00002170 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002171 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002172 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002173 if (len > 0) {
2174 char ch = namebuf[len-1];
2175 if (ch != SEP && ch != ALTSEP && ch != ':')
2176 namebuf[len++] = '/';
2177 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002178 strcpy(namebuf + len, "*.*");
2179
Barry Warsaw53699e91996-12-10 23:23:01 +00002180 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002181 return NULL;
2182
2183 hFindFile = FindFirstFile(namebuf, &FileData);
2184 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002185 int error = GetLastError();
2186 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002187 return d;
2188 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002189 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002190 }
2191 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002192 /* Skip over . and .. */
2193 if (strcmp(FileData.cFileName, ".") != 0 &&
2194 strcmp(FileData.cFileName, "..") != 0) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002195 v = PyString_FromString(FileData.cFileName);
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002196 if (v == NULL) {
2197 Py_DECREF(d);
2198 d = NULL;
2199 break;
2200 }
2201 if (PyList_Append(d, v) != 0) {
2202 Py_DECREF(v);
2203 Py_DECREF(d);
2204 d = NULL;
2205 break;
2206 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002207 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002208 }
Georg Brandl622927b2006-03-07 12:48:03 +00002209 Py_BEGIN_ALLOW_THREADS
2210 result = FindNextFile(hFindFile, &FileData);
2211 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00002212 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2213 it got to the end of the directory. */
2214 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2215 Py_DECREF(d);
2216 win32_error("FindNextFile", namebuf);
2217 FindClose(hFindFile);
2218 return NULL;
2219 }
Georg Brandl622927b2006-03-07 12:48:03 +00002220 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002221
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002222 if (FindClose(hFindFile) == FALSE) {
2223 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002224 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002225 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002226
2227 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002228
Tim Peters0bb44a42000-09-15 07:44:49 +00002229#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002230
2231#ifndef MAX_PATH
2232#define MAX_PATH CCHMAXPATH
2233#endif
2234 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002235 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002236 PyObject *d, *v;
2237 char namebuf[MAX_PATH+5];
2238 HDIR hdir = 1;
2239 ULONG srchcnt = 1;
2240 FILEFINDBUF3 ep;
2241 APIRET rc;
2242
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002243 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002244 return NULL;
2245 if (len >= MAX_PATH) {
2246 PyErr_SetString(PyExc_ValueError, "path too long");
2247 return NULL;
2248 }
2249 strcpy(namebuf, name);
2250 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002251 if (*pt == ALTSEP)
2252 *pt = SEP;
2253 if (namebuf[len-1] != SEP)
2254 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002255 strcpy(namebuf + len, "*.*");
2256
2257 if ((d = PyList_New(0)) == NULL)
2258 return NULL;
2259
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002260 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2261 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002262 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002263 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2264 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2265 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002266
2267 if (rc != NO_ERROR) {
2268 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002269 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002270 }
2271
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002272 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002273 do {
2274 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002275 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002276 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002277
2278 strcpy(namebuf, ep.achName);
2279
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002280 /* Leave Case of Name Alone -- In Native Form */
2281 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002282
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002283 v = PyString_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002284 if (v == NULL) {
2285 Py_DECREF(d);
2286 d = NULL;
2287 break;
2288 }
2289 if (PyList_Append(d, v) != 0) {
2290 Py_DECREF(v);
2291 Py_DECREF(d);
2292 d = NULL;
2293 break;
2294 }
2295 Py_DECREF(v);
2296 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2297 }
2298
2299 return d;
2300#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002301
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002302 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002303 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002304 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002305 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002306 int arg_is_unicode = 1;
2307
Georg Brandl05e89b82006-04-11 07:04:06 +00002308 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002309 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2310 arg_is_unicode = 0;
2311 PyErr_Clear();
2312 }
2313 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002314 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002315 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002316 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002317 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002318 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002319 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002320 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002321 return NULL;
2322 }
Georg Brandl622927b2006-03-07 12:48:03 +00002323 for (;;) {
Georg Brandl86cbf812008-07-16 21:31:41 +00002324 errno = 0;
Georg Brandl622927b2006-03-07 12:48:03 +00002325 Py_BEGIN_ALLOW_THREADS
2326 ep = readdir(dirp);
2327 Py_END_ALLOW_THREADS
Georg Brandl86cbf812008-07-16 21:31:41 +00002328 if (ep == NULL) {
2329 if (errno == 0) {
2330 break;
2331 } else {
2332 closedir(dirp);
2333 Py_DECREF(d);
2334 return posix_error_with_allocated_filename(name);
2335 }
2336 }
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002337 if (ep->d_name[0] == '.' &&
2338 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002339 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002340 continue;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002341 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002342 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002343 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002344 d = NULL;
2345 break;
2346 }
Just van Rossum46c97842003-02-25 21:42:15 +00002347#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00002348 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002349 PyObject *w;
2350
2351 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002352 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002353 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002354 if (w != NULL) {
2355 Py_DECREF(v);
2356 v = w;
2357 }
2358 else {
2359 /* fall back to the original byte string, as
2360 discussed in patch #683592 */
2361 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002362 }
Just van Rossum46c97842003-02-25 21:42:15 +00002363 }
2364#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002365 if (PyList_Append(d, v) != 0) {
2366 Py_DECREF(v);
2367 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002368 d = NULL;
2369 break;
2370 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002371 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002372 }
2373 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002374 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002375
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002376 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002377
Tim Peters0bb44a42000-09-15 07:44:49 +00002378#endif /* which OS */
2379} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002380
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002381#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002382/* A helper function for abspath on win32 */
2383static PyObject *
2384posix__getfullpathname(PyObject *self, PyObject *args)
2385{
2386 /* assume encoded strings wont more than double no of chars */
2387 char inbuf[MAX_PATH*2];
2388 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002389 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002390 char outbuf[MAX_PATH*2];
2391 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002392#ifdef Py_WIN_WIDE_FILENAMES
2393 if (unicode_file_names()) {
2394 PyUnicodeObject *po;
2395 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2396 Py_UNICODE woutbuf[MAX_PATH*2];
2397 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00002398 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002399 sizeof(woutbuf)/sizeof(woutbuf[0]),
2400 woutbuf, &wtemp))
2401 return win32_error("GetFullPathName", "");
2402 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
2403 }
2404 /* Drop the argument parsing error as narrow strings
2405 are also valid. */
2406 PyErr_Clear();
2407 }
2408#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002409 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2410 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002411 &insize))
2412 return NULL;
2413 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2414 outbuf, &temp))
2415 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002416 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2417 return PyUnicode_Decode(outbuf, strlen(outbuf),
2418 Py_FileSystemDefaultEncoding, NULL);
2419 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002420 return PyString_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002421} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002422#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002423
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002424PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002425"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002426Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002427
Barry Warsaw53699e91996-12-10 23:23:01 +00002428static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002429posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002430{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002431 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002432 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002433 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002434
2435#ifdef Py_WIN_WIDE_FILENAMES
2436 if (unicode_file_names()) {
2437 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002438 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002439 Py_BEGIN_ALLOW_THREADS
2440 /* PyUnicode_AS_UNICODE OK without thread lock as
2441 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002442 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002443 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002444 if (!res)
2445 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002446 Py_INCREF(Py_None);
2447 return Py_None;
2448 }
2449 /* Drop the argument parsing error as narrow strings
2450 are also valid. */
2451 PyErr_Clear();
2452 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002453 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2454 Py_FileSystemDefaultEncoding, &path, &mode))
2455 return NULL;
2456 Py_BEGIN_ALLOW_THREADS
2457 /* PyUnicode_AS_UNICODE OK without thread lock as
2458 it is a simple dereference. */
2459 res = CreateDirectoryA(path, NULL);
2460 Py_END_ALLOW_THREADS
2461 if (!res) {
2462 win32_error("mkdir", path);
2463 PyMem_Free(path);
2464 return NULL;
2465 }
2466 PyMem_Free(path);
2467 Py_INCREF(Py_None);
2468 return Py_None;
2469#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002470
Tim Peters5aa91602002-01-30 05:46:57 +00002471 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002472 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002473 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002474 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002475#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002476 res = mkdir(path);
2477#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002478 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002479#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002480 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002481 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002482 return posix_error_with_allocated_filename(path);
2483 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002484 Py_INCREF(Py_None);
2485 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002486#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002487}
2488
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002489
Neal Norwitz1818ed72006-03-26 00:29:48 +00002490/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2491#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002492#include <sys/resource.h>
2493#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002494
Neal Norwitz1818ed72006-03-26 00:29:48 +00002495
2496#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002497PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002498"nice(inc) -> new_priority\n\n\
2499Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002500
Barry Warsaw53699e91996-12-10 23:23:01 +00002501static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002502posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002503{
2504 int increment, value;
2505
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002506 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002507 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002508
2509 /* There are two flavours of 'nice': one that returns the new
2510 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002511 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2512 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002513
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002514 If we are of the nice family that returns the new priority, we
2515 need to clear errno before the call, and check if errno is filled
2516 before calling posix_error() on a returnvalue of -1, because the
2517 -1 may be the actual new priority! */
2518
2519 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002520 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002521#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002522 if (value == 0)
2523 value = getpriority(PRIO_PROCESS, 0);
2524#endif
2525 if (value == -1 && errno != 0)
2526 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002527 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002528 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002529}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002530#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002531
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002532PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002533"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002534Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002535
Barry Warsaw53699e91996-12-10 23:23:01 +00002536static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002537posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002538{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002539#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002540 PyObject *o1, *o2;
2541 char *p1, *p2;
2542 BOOL result;
2543 if (unicode_file_names()) {
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002544 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2545 goto error;
2546 if (!convert_to_unicode(&o1))
2547 goto error;
2548 if (!convert_to_unicode(&o2)) {
2549 Py_DECREF(o1);
2550 goto error;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002551 }
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002552 Py_BEGIN_ALLOW_THREADS
2553 result = MoveFileW(PyUnicode_AsUnicode(o1),
2554 PyUnicode_AsUnicode(o2));
2555 Py_END_ALLOW_THREADS
2556 Py_DECREF(o1);
2557 Py_DECREF(o2);
2558 if (!result)
2559 return win32_error("rename", NULL);
2560 Py_INCREF(Py_None);
2561 return Py_None;
2562error:
2563 PyErr_Clear();
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002564 }
2565 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2566 return NULL;
2567 Py_BEGIN_ALLOW_THREADS
2568 result = MoveFileA(p1, p2);
2569 Py_END_ALLOW_THREADS
2570 if (!result)
2571 return win32_error("rename", NULL);
2572 Py_INCREF(Py_None);
2573 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002574#else
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002575 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002576#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002577}
2578
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002579
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002580PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002581"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002582Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002583
Barry Warsaw53699e91996-12-10 23:23:01 +00002584static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002585posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002586{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002587#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002588 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002589#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002590 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002591#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002592}
2593
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002594
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002595PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002596"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002597Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002598
Barry Warsaw53699e91996-12-10 23:23:01 +00002599static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002600posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002601{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002602#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002603 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002604#else
2605 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2606#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002607}
2608
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002609
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002610#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002611PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002612"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002613Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002614
Barry Warsaw53699e91996-12-10 23:23:01 +00002615static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002616posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002617{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002618 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002619 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002620 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002621 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002622 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002623 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002624 Py_END_ALLOW_THREADS
2625 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002626}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002627#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002628
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002629
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002630PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002631"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002632Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002633
Barry Warsaw53699e91996-12-10 23:23:01 +00002634static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002635posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002636{
2637 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002638 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002639 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002640 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002641 if (i < 0)
2642 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002643 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002644}
2645
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002646
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002647PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002648"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002649Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002650
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002651PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002652"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002653Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002654
Barry Warsaw53699e91996-12-10 23:23:01 +00002655static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002656posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002657{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002658#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002659 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002660#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002661 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002662#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002663}
2664
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002665
Guido van Rossumb6775db1994-08-01 11:34:53 +00002666#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002667PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002668"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002669Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002670
Barry Warsaw53699e91996-12-10 23:23:01 +00002671static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002672posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002673{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002674 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002675 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002676
Barry Warsaw53699e91996-12-10 23:23:01 +00002677 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002678 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002679 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002680 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002681 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002682 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002683 u.sysname,
2684 u.nodename,
2685 u.release,
2686 u.version,
2687 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002688}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002689#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002690
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002691static int
2692extract_time(PyObject *t, long* sec, long* usec)
2693{
2694 long intval;
2695 if (PyFloat_Check(t)) {
2696 double tval = PyFloat_AsDouble(t);
Christian Heimese93237d2007-12-19 02:37:44 +00002697 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002698 if (!intobj)
2699 return -1;
2700 intval = PyInt_AsLong(intobj);
2701 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002702 if (intval == -1 && PyErr_Occurred())
2703 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002704 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002705 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002706 if (*usec < 0)
2707 /* If rounding gave us a negative number,
2708 truncate. */
2709 *usec = 0;
2710 return 0;
2711 }
2712 intval = PyInt_AsLong(t);
2713 if (intval == -1 && PyErr_Occurred())
2714 return -1;
2715 *sec = intval;
2716 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002717 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002718}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002719
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002720PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002721"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002722utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002723Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002724second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002725
Barry Warsaw53699e91996-12-10 23:23:01 +00002726static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002727posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002728{
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002729#ifdef Py_WIN_WIDE_FILENAMES
2730 PyObject *arg;
2731 PyUnicodeObject *obwpath;
2732 wchar_t *wpath = NULL;
2733 char *apath = NULL;
2734 HANDLE hFile;
2735 long atimesec, mtimesec, ausec, musec;
2736 FILETIME atime, mtime;
2737 PyObject *result = NULL;
2738
2739 if (unicode_file_names()) {
2740 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2741 wpath = PyUnicode_AS_UNICODE(obwpath);
2742 Py_BEGIN_ALLOW_THREADS
2743 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002744 NULL, OPEN_EXISTING,
2745 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002746 Py_END_ALLOW_THREADS
2747 if (hFile == INVALID_HANDLE_VALUE)
2748 return win32_error_unicode("utime", wpath);
2749 } else
2750 /* Drop the argument parsing error as narrow strings
2751 are also valid. */
2752 PyErr_Clear();
2753 }
2754 if (!wpath) {
2755 if (!PyArg_ParseTuple(args, "etO:utime",
2756 Py_FileSystemDefaultEncoding, &apath, &arg))
2757 return NULL;
2758 Py_BEGIN_ALLOW_THREADS
2759 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002760 NULL, OPEN_EXISTING,
2761 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002762 Py_END_ALLOW_THREADS
2763 if (hFile == INVALID_HANDLE_VALUE) {
2764 win32_error("utime", apath);
2765 PyMem_Free(apath);
2766 return NULL;
2767 }
2768 PyMem_Free(apath);
2769 }
2770
2771 if (arg == Py_None) {
2772 SYSTEMTIME now;
2773 GetSystemTime(&now);
2774 if (!SystemTimeToFileTime(&now, &mtime) ||
2775 !SystemTimeToFileTime(&now, &atime)) {
2776 win32_error("utime", NULL);
2777 goto done;
2778 }
2779 }
2780 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2781 PyErr_SetString(PyExc_TypeError,
2782 "utime() arg 2 must be a tuple (atime, mtime)");
2783 goto done;
2784 }
2785 else {
2786 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2787 &atimesec, &ausec) == -1)
2788 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002789 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002790 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2791 &mtimesec, &musec) == -1)
2792 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002793 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002794 }
2795 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2796 /* Avoid putting the file name into the error here,
2797 as that may confuse the user into believing that
2798 something is wrong with the file, when it also
2799 could be the time stamp that gives a problem. */
2800 win32_error("utime", NULL);
2801 }
2802 Py_INCREF(Py_None);
2803 result = Py_None;
2804done:
2805 CloseHandle(hFile);
2806 return result;
2807#else /* Py_WIN_WIDE_FILENAMES */
2808
Neal Norwitz2adf2102004-06-09 01:46:02 +00002809 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002810 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002811 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002812 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002813
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002814#if defined(HAVE_UTIMES)
2815 struct timeval buf[2];
2816#define ATIME buf[0].tv_sec
2817#define MTIME buf[1].tv_sec
2818#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002819/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002820 struct utimbuf buf;
2821#define ATIME buf.actime
2822#define MTIME buf.modtime
2823#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002824#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002825 time_t buf[2];
2826#define ATIME buf[0]
2827#define MTIME buf[1]
2828#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002829#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002830
Mark Hammond817c9292003-12-03 01:22:38 +00002831
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002832 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002833 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002834 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002835 if (arg == Py_None) {
2836 /* optional time values not given */
2837 Py_BEGIN_ALLOW_THREADS
2838 res = utime(path, NULL);
2839 Py_END_ALLOW_THREADS
2840 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002841 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002842 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002843 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002844 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002845 return NULL;
2846 }
2847 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002848 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002849 &atime, &ausec) == -1) {
2850 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002851 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002852 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002853 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002854 &mtime, &musec) == -1) {
2855 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002856 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002857 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002858 ATIME = atime;
2859 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002860#ifdef HAVE_UTIMES
2861 buf[0].tv_usec = ausec;
2862 buf[1].tv_usec = musec;
2863 Py_BEGIN_ALLOW_THREADS
2864 res = utimes(path, buf);
2865 Py_END_ALLOW_THREADS
2866#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002867 Py_BEGIN_ALLOW_THREADS
2868 res = utime(path, UTIME_ARG);
2869 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002870#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002871 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002872 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002873 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002874 }
Neal Norwitz96652712004-06-06 20:40:27 +00002875 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002876 Py_INCREF(Py_None);
2877 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002878#undef UTIME_ARG
2879#undef ATIME
2880#undef MTIME
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002881#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002882}
2883
Guido van Rossum85e3b011991-06-03 12:42:10 +00002884
Guido van Rossum3b066191991-06-04 19:40:25 +00002885/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002886
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002887PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002888"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002889Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002890
Barry Warsaw53699e91996-12-10 23:23:01 +00002891static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002892posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002893{
2894 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002895 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002896 return NULL;
2897 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002898 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002899}
2900
Martin v. Löwis114619e2002-10-07 06:44:21 +00002901#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2902static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002903free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002904{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002905 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002906 for (i = 0; i < count; i++)
2907 PyMem_Free(array[i]);
2908 PyMem_DEL(array);
2909}
2910#endif
2911
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002912
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002913#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002914PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002915"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002916Execute an executable path with arguments, replacing current process.\n\
2917\n\
2918 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002919 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002920
Barry Warsaw53699e91996-12-10 23:23:01 +00002921static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002922posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002923{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002924 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002925 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002926 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002927 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002928 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002929
Guido van Rossum89b33251993-10-22 14:26:06 +00002930 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002931 argv is a list or tuple of strings. */
2932
Martin v. Löwis114619e2002-10-07 06:44:21 +00002933 if (!PyArg_ParseTuple(args, "etO:execv",
2934 Py_FileSystemDefaultEncoding,
2935 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002936 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002937 if (PyList_Check(argv)) {
2938 argc = PyList_Size(argv);
2939 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002940 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002941 else if (PyTuple_Check(argv)) {
2942 argc = PyTuple_Size(argv);
2943 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002944 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002945 else {
Fred Drake661ea262000-10-24 19:57:45 +00002946 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002947 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002948 return NULL;
2949 }
2950
Barry Warsaw53699e91996-12-10 23:23:01 +00002951 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002952 if (argvlist == NULL) {
2953 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002954 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002955 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002956 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002957 if (!PyArg_Parse((*getitem)(argv, i), "et",
2958 Py_FileSystemDefaultEncoding,
2959 &argvlist[i])) {
2960 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002961 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002962 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002963 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002964 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002965
Guido van Rossum85e3b011991-06-03 12:42:10 +00002966 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002967 }
2968 argvlist[argc] = NULL;
2969
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002970 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002971
Guido van Rossum85e3b011991-06-03 12:42:10 +00002972 /* If we get here it's definitely an error */
2973
Martin v. Löwis114619e2002-10-07 06:44:21 +00002974 free_string_array(argvlist, argc);
2975 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002976 return posix_error();
2977}
2978
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002979
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002980PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002981"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002982Execute a path with arguments and environment, replacing current process.\n\
2983\n\
2984 path: path of executable file\n\
2985 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002986 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002987
Barry Warsaw53699e91996-12-10 23:23:01 +00002988static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002989posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002990{
2991 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002992 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002993 char **argvlist;
2994 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002995 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002996 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002997 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002998 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002999
3000 /* execve has three arguments: (path, argv, env), where
3001 argv is a list or tuple of strings and env is a dictionary
3002 like posix.environ. */
3003
Martin v. Löwis114619e2002-10-07 06:44:21 +00003004 if (!PyArg_ParseTuple(args, "etOO:execve",
3005 Py_FileSystemDefaultEncoding,
3006 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003007 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003008 if (PyList_Check(argv)) {
3009 argc = PyList_Size(argv);
3010 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003011 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003012 else if (PyTuple_Check(argv)) {
3013 argc = PyTuple_Size(argv);
3014 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003015 }
3016 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003017 PyErr_SetString(PyExc_TypeError,
3018 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003019 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003020 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003021 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003022 PyErr_SetString(PyExc_TypeError,
3023 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003024 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003025 }
3026
Barry Warsaw53699e91996-12-10 23:23:01 +00003027 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003028 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003029 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003030 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003031 }
3032 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003033 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00003034 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00003035 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00003036 &argvlist[i]))
3037 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003038 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003039 goto fail_1;
3040 }
3041 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003042 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003043 argvlist[argc] = NULL;
3044
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003045 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003046 if (i < 0)
3047 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00003048 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003049 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003050 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003051 goto fail_1;
3052 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003053 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003054 keys = PyMapping_Keys(env);
3055 vals = PyMapping_Values(env);
3056 if (!keys || !vals)
3057 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003058 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3059 PyErr_SetString(PyExc_TypeError,
3060 "execve(): env.keys() or env.values() is not a list");
3061 goto fail_2;
3062 }
Tim Peters5aa91602002-01-30 05:46:57 +00003063
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003064 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003065 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003066 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003067
3068 key = PyList_GetItem(keys, pos);
3069 val = PyList_GetItem(vals, pos);
3070 if (!key || !val)
3071 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003072
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003073 if (!PyArg_Parse(
3074 key,
3075 "s;execve() arg 3 contains a non-string key",
3076 &k) ||
3077 !PyArg_Parse(
3078 val,
3079 "s;execve() arg 3 contains a non-string value",
3080 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003081 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003082 goto fail_2;
3083 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003084
3085#if defined(PYOS_OS2)
3086 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3087 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3088#endif
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003089 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003090 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003091 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003092 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003093 goto fail_2;
3094 }
Tim Petersc8996f52001-12-03 20:41:00 +00003095 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003096 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003097#if defined(PYOS_OS2)
3098 }
3099#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003100 }
3101 envlist[envc] = 0;
3102
3103 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003104
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003105 /* If we get here it's definitely an error */
3106
3107 (void) posix_error();
3108
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003109 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003110 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003111 PyMem_DEL(envlist[envc]);
3112 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003113 fail_1:
3114 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003115 Py_XDECREF(vals);
3116 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003117 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003118 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003119 return NULL;
3120}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003121#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003122
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003123
Guido van Rossuma1065681999-01-25 23:20:23 +00003124#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003125PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003126"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003127Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003128\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003129 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003130 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003131 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003132
3133static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003134posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003135{
3136 char *path;
3137 PyObject *argv;
3138 char **argvlist;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003139 int mode, i;
3140 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003141 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003142 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003143
3144 /* spawnv has three arguments: (mode, path, argv), where
3145 argv is a list or tuple of strings. */
3146
Martin v. Löwis114619e2002-10-07 06:44:21 +00003147 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3148 Py_FileSystemDefaultEncoding,
3149 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003150 return NULL;
3151 if (PyList_Check(argv)) {
3152 argc = PyList_Size(argv);
3153 getitem = PyList_GetItem;
3154 }
3155 else if (PyTuple_Check(argv)) {
3156 argc = PyTuple_Size(argv);
3157 getitem = PyTuple_GetItem;
3158 }
3159 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003160 PyErr_SetString(PyExc_TypeError,
3161 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003162 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003163 return NULL;
3164 }
3165
3166 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003167 if (argvlist == NULL) {
3168 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003169 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003170 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003171 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003172 if (!PyArg_Parse((*getitem)(argv, i), "et",
3173 Py_FileSystemDefaultEncoding,
3174 &argvlist[i])) {
3175 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003176 PyErr_SetString(
3177 PyExc_TypeError,
3178 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003179 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00003180 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003181 }
3182 }
3183 argvlist[argc] = NULL;
3184
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003185#if defined(PYOS_OS2) && defined(PYCC_GCC)
3186 Py_BEGIN_ALLOW_THREADS
3187 spawnval = spawnv(mode, path, argvlist);
3188 Py_END_ALLOW_THREADS
3189#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003190 if (mode == _OLD_P_OVERLAY)
3191 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003192
Tim Peters25059d32001-12-07 20:35:43 +00003193 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003194 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003195 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003196#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003197
Martin v. Löwis114619e2002-10-07 06:44:21 +00003198 free_string_array(argvlist, argc);
3199 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003200
Fred Drake699f3522000-06-29 21:12:41 +00003201 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003202 return posix_error();
3203 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003204#if SIZEOF_LONG == SIZEOF_VOID_P
3205 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003206#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003207 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003208#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003209}
3210
3211
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003212PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003213"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003214Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003215\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003216 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003217 path: path of executable file\n\
3218 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003219 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003220
3221static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003222posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003223{
3224 char *path;
3225 PyObject *argv, *env;
3226 char **argvlist;
3227 char **envlist;
3228 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003229 int mode, pos, envc;
3230 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003231 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003232 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003233 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003234
3235 /* spawnve has four arguments: (mode, path, argv, env), where
3236 argv is a list or tuple of strings and env is a dictionary
3237 like posix.environ. */
3238
Martin v. Löwis114619e2002-10-07 06:44:21 +00003239 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3240 Py_FileSystemDefaultEncoding,
3241 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003242 return NULL;
3243 if (PyList_Check(argv)) {
3244 argc = PyList_Size(argv);
3245 getitem = PyList_GetItem;
3246 }
3247 else if (PyTuple_Check(argv)) {
3248 argc = PyTuple_Size(argv);
3249 getitem = PyTuple_GetItem;
3250 }
3251 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003252 PyErr_SetString(PyExc_TypeError,
3253 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003254 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003255 }
3256 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003257 PyErr_SetString(PyExc_TypeError,
3258 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003259 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003260 }
3261
3262 argvlist = PyMem_NEW(char *, argc+1);
3263 if (argvlist == NULL) {
3264 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003265 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003266 }
3267 for (i = 0; i < argc; i++) {
3268 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003269 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00003270 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00003271 &argvlist[i]))
3272 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003273 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003274 goto fail_1;
3275 }
3276 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003277 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003278 argvlist[argc] = NULL;
3279
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003280 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003281 if (i < 0)
3282 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003283 envlist = PyMem_NEW(char *, i + 1);
3284 if (envlist == NULL) {
3285 PyErr_NoMemory();
3286 goto fail_1;
3287 }
3288 envc = 0;
3289 keys = PyMapping_Keys(env);
3290 vals = PyMapping_Values(env);
3291 if (!keys || !vals)
3292 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003293 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3294 PyErr_SetString(PyExc_TypeError,
3295 "spawnve(): env.keys() or env.values() is not a list");
3296 goto fail_2;
3297 }
Tim Peters5aa91602002-01-30 05:46:57 +00003298
Guido van Rossuma1065681999-01-25 23:20:23 +00003299 for (pos = 0; pos < i; pos++) {
3300 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003301 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003302
3303 key = PyList_GetItem(keys, pos);
3304 val = PyList_GetItem(vals, pos);
3305 if (!key || !val)
3306 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003307
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003308 if (!PyArg_Parse(
3309 key,
3310 "s;spawnve() arg 3 contains a non-string key",
3311 &k) ||
3312 !PyArg_Parse(
3313 val,
3314 "s;spawnve() arg 3 contains a non-string value",
3315 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003316 {
3317 goto fail_2;
3318 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003319 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003320 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003321 if (p == NULL) {
3322 PyErr_NoMemory();
3323 goto fail_2;
3324 }
Tim Petersc8996f52001-12-03 20:41:00 +00003325 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003326 envlist[envc++] = p;
3327 }
3328 envlist[envc] = 0;
3329
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003330#if defined(PYOS_OS2) && defined(PYCC_GCC)
3331 Py_BEGIN_ALLOW_THREADS
3332 spawnval = spawnve(mode, path, argvlist, envlist);
3333 Py_END_ALLOW_THREADS
3334#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003335 if (mode == _OLD_P_OVERLAY)
3336 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003337
3338 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003339 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003340 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003341#endif
Tim Peters25059d32001-12-07 20:35:43 +00003342
Fred Drake699f3522000-06-29 21:12:41 +00003343 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003344 (void) posix_error();
3345 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003346#if SIZEOF_LONG == SIZEOF_VOID_P
3347 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003348#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003349 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003350#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003351
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003352 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003353 while (--envc >= 0)
3354 PyMem_DEL(envlist[envc]);
3355 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003356 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003357 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003358 Py_XDECREF(vals);
3359 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003360 fail_0:
3361 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003362 return res;
3363}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003364
3365/* OS/2 supports spawnvp & spawnvpe natively */
3366#if defined(PYOS_OS2)
3367PyDoc_STRVAR(posix_spawnvp__doc__,
3368"spawnvp(mode, file, args)\n\n\
3369Execute the program 'file' in a new process, using the environment\n\
3370search path to find the file.\n\
3371\n\
3372 mode: mode of process creation\n\
3373 file: executable file name\n\
3374 args: tuple or list of strings");
3375
3376static PyObject *
3377posix_spawnvp(PyObject *self, PyObject *args)
3378{
3379 char *path;
3380 PyObject *argv;
3381 char **argvlist;
3382 int mode, i, argc;
3383 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003384 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003385
3386 /* spawnvp has three arguments: (mode, path, argv), where
3387 argv is a list or tuple of strings. */
3388
3389 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3390 Py_FileSystemDefaultEncoding,
3391 &path, &argv))
3392 return NULL;
3393 if (PyList_Check(argv)) {
3394 argc = PyList_Size(argv);
3395 getitem = PyList_GetItem;
3396 }
3397 else if (PyTuple_Check(argv)) {
3398 argc = PyTuple_Size(argv);
3399 getitem = PyTuple_GetItem;
3400 }
3401 else {
3402 PyErr_SetString(PyExc_TypeError,
3403 "spawnvp() arg 2 must be a tuple or list");
3404 PyMem_Free(path);
3405 return NULL;
3406 }
3407
3408 argvlist = PyMem_NEW(char *, argc+1);
3409 if (argvlist == NULL) {
3410 PyMem_Free(path);
3411 return PyErr_NoMemory();
3412 }
3413 for (i = 0; i < argc; i++) {
3414 if (!PyArg_Parse((*getitem)(argv, i), "et",
3415 Py_FileSystemDefaultEncoding,
3416 &argvlist[i])) {
3417 free_string_array(argvlist, i);
3418 PyErr_SetString(
3419 PyExc_TypeError,
3420 "spawnvp() arg 2 must contain only strings");
3421 PyMem_Free(path);
3422 return NULL;
3423 }
3424 }
3425 argvlist[argc] = NULL;
3426
3427 Py_BEGIN_ALLOW_THREADS
3428#if defined(PYCC_GCC)
3429 spawnval = spawnvp(mode, path, argvlist);
3430#else
3431 spawnval = _spawnvp(mode, path, argvlist);
3432#endif
3433 Py_END_ALLOW_THREADS
3434
3435 free_string_array(argvlist, argc);
3436 PyMem_Free(path);
3437
3438 if (spawnval == -1)
3439 return posix_error();
3440 else
3441 return Py_BuildValue("l", (long) spawnval);
3442}
3443
3444
3445PyDoc_STRVAR(posix_spawnvpe__doc__,
3446"spawnvpe(mode, file, args, env)\n\n\
3447Execute the program 'file' in a new process, using the environment\n\
3448search path to find the file.\n\
3449\n\
3450 mode: mode of process creation\n\
3451 file: executable file name\n\
3452 args: tuple or list of arguments\n\
3453 env: dictionary of strings mapping to strings");
3454
3455static PyObject *
3456posix_spawnvpe(PyObject *self, PyObject *args)
3457{
3458 char *path;
3459 PyObject *argv, *env;
3460 char **argvlist;
3461 char **envlist;
3462 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3463 int mode, i, pos, argc, envc;
3464 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003465 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003466 int lastarg = 0;
3467
3468 /* spawnvpe has four arguments: (mode, path, argv, env), where
3469 argv is a list or tuple of strings and env is a dictionary
3470 like posix.environ. */
3471
3472 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3473 Py_FileSystemDefaultEncoding,
3474 &path, &argv, &env))
3475 return NULL;
3476 if (PyList_Check(argv)) {
3477 argc = PyList_Size(argv);
3478 getitem = PyList_GetItem;
3479 }
3480 else if (PyTuple_Check(argv)) {
3481 argc = PyTuple_Size(argv);
3482 getitem = PyTuple_GetItem;
3483 }
3484 else {
3485 PyErr_SetString(PyExc_TypeError,
3486 "spawnvpe() arg 2 must be a tuple or list");
3487 goto fail_0;
3488 }
3489 if (!PyMapping_Check(env)) {
3490 PyErr_SetString(PyExc_TypeError,
3491 "spawnvpe() arg 3 must be a mapping object");
3492 goto fail_0;
3493 }
3494
3495 argvlist = PyMem_NEW(char *, argc+1);
3496 if (argvlist == NULL) {
3497 PyErr_NoMemory();
3498 goto fail_0;
3499 }
3500 for (i = 0; i < argc; i++) {
3501 if (!PyArg_Parse((*getitem)(argv, i),
3502 "et;spawnvpe() arg 2 must contain only strings",
3503 Py_FileSystemDefaultEncoding,
3504 &argvlist[i]))
3505 {
3506 lastarg = i;
3507 goto fail_1;
3508 }
3509 }
3510 lastarg = argc;
3511 argvlist[argc] = NULL;
3512
3513 i = PyMapping_Size(env);
3514 if (i < 0)
3515 goto fail_1;
3516 envlist = PyMem_NEW(char *, i + 1);
3517 if (envlist == NULL) {
3518 PyErr_NoMemory();
3519 goto fail_1;
3520 }
3521 envc = 0;
3522 keys = PyMapping_Keys(env);
3523 vals = PyMapping_Values(env);
3524 if (!keys || !vals)
3525 goto fail_2;
3526 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3527 PyErr_SetString(PyExc_TypeError,
3528 "spawnvpe(): env.keys() or env.values() is not a list");
3529 goto fail_2;
3530 }
3531
3532 for (pos = 0; pos < i; pos++) {
3533 char *p, *k, *v;
3534 size_t len;
3535
3536 key = PyList_GetItem(keys, pos);
3537 val = PyList_GetItem(vals, pos);
3538 if (!key || !val)
3539 goto fail_2;
3540
3541 if (!PyArg_Parse(
3542 key,
3543 "s;spawnvpe() arg 3 contains a non-string key",
3544 &k) ||
3545 !PyArg_Parse(
3546 val,
3547 "s;spawnvpe() arg 3 contains a non-string value",
3548 &v))
3549 {
3550 goto fail_2;
3551 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003552 len = PyString_Size(key) + PyString_Size(val) + 2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003553 p = PyMem_NEW(char, len);
3554 if (p == NULL) {
3555 PyErr_NoMemory();
3556 goto fail_2;
3557 }
3558 PyOS_snprintf(p, len, "%s=%s", k, v);
3559 envlist[envc++] = p;
3560 }
3561 envlist[envc] = 0;
3562
3563 Py_BEGIN_ALLOW_THREADS
3564#if defined(PYCC_GCC)
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003565 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003566#else
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003567 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003568#endif
3569 Py_END_ALLOW_THREADS
3570
3571 if (spawnval == -1)
3572 (void) posix_error();
3573 else
3574 res = Py_BuildValue("l", (long) spawnval);
3575
3576 fail_2:
3577 while (--envc >= 0)
3578 PyMem_DEL(envlist[envc]);
3579 PyMem_DEL(envlist);
3580 fail_1:
3581 free_string_array(argvlist, lastarg);
3582 Py_XDECREF(vals);
3583 Py_XDECREF(keys);
3584 fail_0:
3585 PyMem_Free(path);
3586 return res;
3587}
3588#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003589#endif /* HAVE_SPAWNV */
3590
3591
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003592#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003593PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003594"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003595Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3596\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003597Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003598
3599static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003600posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003601{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003602 pid_t pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003603 if (pid == -1)
3604 return posix_error();
Gregory P. Smithfb7a50f2008-07-14 06:06:48 +00003605 if (pid == 0)
3606 PyOS_AfterFork();
Christian Heimes951cc0f2008-01-31 23:08:23 +00003607 return PyInt_FromLong(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003608}
3609#endif
3610
3611
Guido van Rossumad0ee831995-03-01 10:34:45 +00003612#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003613PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003614"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003615Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003616Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003617
Barry Warsaw53699e91996-12-10 23:23:01 +00003618static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003619posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003620{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003621 pid_t pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003622 if (pid == -1)
3623 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003624 if (pid == 0)
3625 PyOS_AfterFork();
Christian Heimes951cc0f2008-01-31 23:08:23 +00003626 return PyInt_FromLong(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003627}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003628#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003629
Neal Norwitzb59798b2003-03-21 01:43:31 +00003630/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003631/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3632#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003633#define DEV_PTY_FILE "/dev/ptc"
3634#define HAVE_DEV_PTMX
3635#else
3636#define DEV_PTY_FILE "/dev/ptmx"
3637#endif
3638
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003639#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003640#ifdef HAVE_PTY_H
3641#include <pty.h>
3642#else
3643#ifdef HAVE_LIBUTIL_H
3644#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003645#endif /* HAVE_LIBUTIL_H */
3646#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003647#ifdef HAVE_STROPTS_H
3648#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003649#endif
3650#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003651
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003652#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003653PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003654"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003655Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003656
3657static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003658posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003659{
3660 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003661#ifndef HAVE_OPENPTY
3662 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003663#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003664#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003665 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003666#ifdef sun
Neal Norwitz84a98e02006-04-10 07:44:23 +00003667 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003668#endif
3669#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003670
Thomas Wouters70c21a12000-07-14 14:28:33 +00003671#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003672 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3673 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003674#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003675 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3676 if (slave_name == NULL)
3677 return posix_error();
3678
3679 slave_fd = open(slave_name, O_RDWR);
3680 if (slave_fd < 0)
3681 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003682#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003683 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003684 if (master_fd < 0)
3685 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003686 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003687 /* change permission of slave */
3688 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003689 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003690 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003691 }
3692 /* unlock slave */
3693 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003694 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003695 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003696 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003697 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003698 slave_name = ptsname(master_fd); /* get name of slave */
3699 if (slave_name == NULL)
3700 return posix_error();
3701 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3702 if (slave_fd < 0)
3703 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003704#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003705 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3706 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003707#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003708 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003709#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003710#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003711#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003712
Fred Drake8cef4cf2000-06-28 16:40:38 +00003713 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003714
Fred Drake8cef4cf2000-06-28 16:40:38 +00003715}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003716#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003717
3718#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003719PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003720"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003721Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3722Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003723To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003724
3725static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003726posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003727{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003728 int master_fd = -1;
3729 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003730
Fred Drake8cef4cf2000-06-28 16:40:38 +00003731 pid = forkpty(&master_fd, NULL, NULL, NULL);
3732 if (pid == -1)
3733 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003734 if (pid == 0)
3735 PyOS_AfterFork();
Christian Heimes951cc0f2008-01-31 23:08:23 +00003736 return Py_BuildValue("(li)", pid, master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003737}
3738#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003739
Guido van Rossumad0ee831995-03-01 10:34:45 +00003740#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003741PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003742"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003743Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003744
Barry Warsaw53699e91996-12-10 23:23:01 +00003745static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003746posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003747{
Barry Warsaw53699e91996-12-10 23:23:01 +00003748 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003749}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003750#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003751
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003752
Guido van Rossumad0ee831995-03-01 10:34:45 +00003753#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003754PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003755"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003756Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003757
Barry Warsaw53699e91996-12-10 23:23:01 +00003758static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003759posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003760{
Barry Warsaw53699e91996-12-10 23:23:01 +00003761 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003762}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003763#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003764
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003765
Guido van Rossumad0ee831995-03-01 10:34:45 +00003766#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003767PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003768"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003769Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003770
Barry Warsaw53699e91996-12-10 23:23:01 +00003771static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003772posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003773{
Barry Warsaw53699e91996-12-10 23:23:01 +00003774 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003775}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003776#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003777
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003778
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003779PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003780"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003781Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003782
Barry Warsaw53699e91996-12-10 23:23:01 +00003783static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003784posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003785{
Barry Warsaw53699e91996-12-10 23:23:01 +00003786 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003787}
3788
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003789
Fred Drakec9680921999-12-13 16:37:25 +00003790#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003791PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003792"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003793Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003794
3795static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003796posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003797{
3798 PyObject *result = NULL;
3799
Fred Drakec9680921999-12-13 16:37:25 +00003800#ifdef NGROUPS_MAX
3801#define MAX_GROUPS NGROUPS_MAX
3802#else
3803 /* defined to be 16 on Solaris7, so this should be a small number */
3804#define MAX_GROUPS 64
3805#endif
3806 gid_t grouplist[MAX_GROUPS];
3807 int n;
3808
3809 n = getgroups(MAX_GROUPS, grouplist);
3810 if (n < 0)
3811 posix_error();
3812 else {
3813 result = PyList_New(n);
3814 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003815 int i;
3816 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003817 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003818 if (o == NULL) {
3819 Py_DECREF(result);
3820 result = NULL;
3821 break;
3822 }
3823 PyList_SET_ITEM(result, i, o);
3824 }
3825 }
3826 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003827
Fred Drakec9680921999-12-13 16:37:25 +00003828 return result;
3829}
3830#endif
3831
Martin v. Löwis606edc12002-06-13 21:09:11 +00003832#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003833PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003834"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003835Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003836
3837static PyObject *
3838posix_getpgid(PyObject *self, PyObject *args)
3839{
3840 int pid, pgid;
3841 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3842 return NULL;
3843 pgid = getpgid(pid);
3844 if (pgid < 0)
3845 return posix_error();
3846 return PyInt_FromLong((long)pgid);
3847}
3848#endif /* HAVE_GETPGID */
3849
3850
Guido van Rossumb6775db1994-08-01 11:34:53 +00003851#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003852PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003853"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003854Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003855
Barry Warsaw53699e91996-12-10 23:23:01 +00003856static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003857posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003858{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003859#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003860 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003861#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003862 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003863#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003864}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003865#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003866
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003867
Guido van Rossumb6775db1994-08-01 11:34:53 +00003868#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003869PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003870"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003871Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003872
Barry Warsaw53699e91996-12-10 23:23:01 +00003873static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003874posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003875{
Guido van Rossum64933891994-10-20 21:56:42 +00003876#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003877 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003878#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003879 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003880#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003881 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003882 Py_INCREF(Py_None);
3883 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003884}
3885
Guido van Rossumb6775db1994-08-01 11:34:53 +00003886#endif /* HAVE_SETPGRP */
3887
Guido van Rossumad0ee831995-03-01 10:34:45 +00003888#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003889PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003890"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003891Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003892
Barry Warsaw53699e91996-12-10 23:23:01 +00003893static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003894posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003895{
Christian Heimesd491d712008-02-01 18:49:26 +00003896 return PyInt_FromLong(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003897}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003898#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003899
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003900
Fred Drake12c6e2d1999-12-14 21:25:03 +00003901#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003902PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003903"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003904Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003905
3906static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003907posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003908{
Neal Norwitze241ce82003-02-17 18:17:05 +00003909 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003910 char *name;
3911 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003912
Fred Drakea30680b2000-12-06 21:24:28 +00003913 errno = 0;
3914 name = getlogin();
3915 if (name == NULL) {
3916 if (errno)
3917 posix_error();
3918 else
3919 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003920 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003921 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003922 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003923 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003924 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003925
Fred Drake12c6e2d1999-12-14 21:25:03 +00003926 return result;
3927}
3928#endif
3929
Guido van Rossumad0ee831995-03-01 10:34:45 +00003930#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003931PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003932"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003933Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003934
Barry Warsaw53699e91996-12-10 23:23:01 +00003935static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003936posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003937{
Barry Warsaw53699e91996-12-10 23:23:01 +00003938 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003939}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003940#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003941
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003942
Guido van Rossumad0ee831995-03-01 10:34:45 +00003943#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003944PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003945"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003946Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003947
Barry Warsaw53699e91996-12-10 23:23:01 +00003948static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003949posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003950{
Christian Heimesd491d712008-02-01 18:49:26 +00003951 pid_t pid;
3952 int sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003953 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003954 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003955#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003956 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3957 APIRET rc;
3958 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003959 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003960
3961 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3962 APIRET rc;
3963 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003964 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003965
3966 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003967 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003968#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003969 if (kill(pid, sig) == -1)
3970 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003971#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003972 Py_INCREF(Py_None);
3973 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003974}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003975#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003976
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003977#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003978PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003979"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003980Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003981
3982static PyObject *
3983posix_killpg(PyObject *self, PyObject *args)
3984{
3985 int pgid, sig;
3986 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3987 return NULL;
3988 if (killpg(pgid, sig) == -1)
3989 return posix_error();
3990 Py_INCREF(Py_None);
3991 return Py_None;
3992}
3993#endif
3994
Guido van Rossumc0125471996-06-28 18:55:32 +00003995#ifdef HAVE_PLOCK
3996
3997#ifdef HAVE_SYS_LOCK_H
3998#include <sys/lock.h>
3999#endif
4000
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004001PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004002"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004003Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004004
Barry Warsaw53699e91996-12-10 23:23:01 +00004005static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004006posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004007{
4008 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004009 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00004010 return NULL;
4011 if (plock(op) == -1)
4012 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004013 Py_INCREF(Py_None);
4014 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004015}
4016#endif
4017
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004018
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004019#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004020PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004021"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004022Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004023
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004024#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004025#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004026static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004027async_system(const char *command)
4028{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004029 char errormsg[256], args[1024];
4030 RESULTCODES rcodes;
4031 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004032
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004033 char *shell = getenv("COMSPEC");
4034 if (!shell)
4035 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004036
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004037 /* avoid overflowing the argument buffer */
4038 if (strlen(shell) + 3 + strlen(command) >= 1024)
4039 return ERROR_NOT_ENOUGH_MEMORY
4040
4041 args[0] = '\0';
4042 strcat(args, shell);
4043 strcat(args, "/c ");
4044 strcat(args, command);
4045
4046 /* execute asynchronously, inheriting the environment */
4047 rc = DosExecPgm(errormsg,
4048 sizeof(errormsg),
4049 EXEC_ASYNC,
4050 args,
4051 NULL,
4052 &rcodes,
4053 shell);
4054 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004055}
4056
Guido van Rossumd48f2521997-12-05 22:19:34 +00004057static FILE *
4058popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004059{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004060 int oldfd, tgtfd;
4061 HFILE pipeh[2];
4062 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004063
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004064 /* mode determines which of stdin or stdout is reconnected to
4065 * the pipe to the child
4066 */
4067 if (strchr(mode, 'r') != NULL) {
4068 tgt_fd = 1; /* stdout */
4069 } else if (strchr(mode, 'w')) {
4070 tgt_fd = 0; /* stdin */
4071 } else {
4072 *err = ERROR_INVALID_ACCESS;
4073 return NULL;
4074 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004075
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00004076 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004077 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4078 *err = rc;
4079 return NULL;
4080 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004081
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004082 /* prevent other threads accessing stdio */
4083 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004084
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004085 /* reconnect stdio and execute child */
4086 oldfd = dup(tgtfd);
4087 close(tgtfd);
4088 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4089 DosClose(pipeh[tgtfd]);
4090 rc = async_system(command);
4091 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004092
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004093 /* restore stdio */
4094 dup2(oldfd, tgtfd);
4095 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004096
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004097 /* allow other threads access to stdio */
4098 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004099
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004100 /* if execution of child was successful return file stream */
4101 if (rc == NO_ERROR)
4102 return fdopen(pipeh[1 - tgtfd], mode);
4103 else {
4104 DosClose(pipeh[1 - tgtfd]);
4105 *err = rc;
4106 return NULL;
4107 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004108}
4109
4110static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004111posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004112{
4113 char *name;
4114 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00004115 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004116 FILE *fp;
4117 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004118 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004119 return NULL;
4120 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00004121 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004122 Py_END_ALLOW_THREADS
4123 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004124 return os2_error(err);
4125
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004126 f = PyFile_FromFile(fp, name, mode, fclose);
4127 if (f != NULL)
4128 PyFile_SetBufSize(f, bufsize);
4129 return f;
4130}
4131
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004132#elif defined(PYCC_GCC)
4133
4134/* standard posix version of popen() support */
4135static PyObject *
4136posix_popen(PyObject *self, PyObject *args)
4137{
4138 char *name;
4139 char *mode = "r";
4140 int bufsize = -1;
4141 FILE *fp;
4142 PyObject *f;
4143 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4144 return NULL;
4145 Py_BEGIN_ALLOW_THREADS
4146 fp = popen(name, mode);
4147 Py_END_ALLOW_THREADS
4148 if (fp == NULL)
4149 return posix_error();
4150 f = PyFile_FromFile(fp, name, mode, pclose);
4151 if (f != NULL)
4152 PyFile_SetBufSize(f, bufsize);
4153 return f;
4154}
4155
4156/* fork() under OS/2 has lots'o'warts
4157 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4158 * most of this code is a ripoff of the win32 code, but using the
4159 * capabilities of EMX's C library routines
4160 */
4161
4162/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4163#define POPEN_1 1
4164#define POPEN_2 2
4165#define POPEN_3 3
4166#define POPEN_4 4
4167
4168static PyObject *_PyPopen(char *, int, int, int);
4169static int _PyPclose(FILE *file);
4170
4171/*
4172 * Internal dictionary mapping popen* file pointers to process handles,
4173 * for use when retrieving the process exit code. See _PyPclose() below
4174 * for more information on this dictionary's use.
4175 */
4176static PyObject *_PyPopenProcs = NULL;
4177
4178/* os2emx version of popen2()
4179 *
4180 * The result of this function is a pipe (file) connected to the
4181 * process's stdin, and a pipe connected to the process's stdout.
4182 */
4183
4184static PyObject *
4185os2emx_popen2(PyObject *self, PyObject *args)
4186{
4187 PyObject *f;
4188 int tm=0;
4189
4190 char *cmdstring;
4191 char *mode = "t";
4192 int bufsize = -1;
4193 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4194 return NULL;
4195
4196 if (*mode == 't')
4197 tm = O_TEXT;
4198 else if (*mode != 'b') {
4199 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4200 return NULL;
4201 } else
4202 tm = O_BINARY;
4203
4204 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
4205
4206 return f;
4207}
4208
4209/*
4210 * Variation on os2emx.popen2
4211 *
4212 * The result of this function is 3 pipes - the process's stdin,
4213 * stdout and stderr
4214 */
4215
4216static PyObject *
4217os2emx_popen3(PyObject *self, PyObject *args)
4218{
4219 PyObject *f;
4220 int tm = 0;
4221
4222 char *cmdstring;
4223 char *mode = "t";
4224 int bufsize = -1;
4225 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4226 return NULL;
4227
4228 if (*mode == 't')
4229 tm = O_TEXT;
4230 else if (*mode != 'b') {
4231 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4232 return NULL;
4233 } else
4234 tm = O_BINARY;
4235
4236 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
4237
4238 return f;
4239}
4240
4241/*
4242 * Variation on os2emx.popen2
4243 *
Tim Peters11b23062003-04-23 02:39:17 +00004244 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004245 * and stdout+stderr combined as a single pipe.
4246 */
4247
4248static PyObject *
4249os2emx_popen4(PyObject *self, PyObject *args)
4250{
4251 PyObject *f;
4252 int tm = 0;
4253
4254 char *cmdstring;
4255 char *mode = "t";
4256 int bufsize = -1;
4257 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4258 return NULL;
4259
4260 if (*mode == 't')
4261 tm = O_TEXT;
4262 else if (*mode != 'b') {
4263 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4264 return NULL;
4265 } else
4266 tm = O_BINARY;
4267
4268 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
4269
4270 return f;
4271}
4272
4273/* a couple of structures for convenient handling of multiple
4274 * file handles and pipes
4275 */
4276struct file_ref
4277{
4278 int handle;
4279 int flags;
4280};
4281
4282struct pipe_ref
4283{
4284 int rd;
4285 int wr;
4286};
4287
4288/* The following code is derived from the win32 code */
4289
4290static PyObject *
4291_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4292{
4293 struct file_ref stdio[3];
4294 struct pipe_ref p_fd[3];
4295 FILE *p_s[3];
Christian Heimesd491d712008-02-01 18:49:26 +00004296 int file_count, i, pipe_err;
4297 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004298 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4299 PyObject *f, *p_f[3];
4300
4301 /* file modes for subsequent fdopen's on pipe handles */
4302 if (mode == O_TEXT)
4303 {
4304 rd_mode = "rt";
4305 wr_mode = "wt";
4306 }
4307 else
4308 {
4309 rd_mode = "rb";
4310 wr_mode = "wb";
4311 }
4312
4313 /* prepare shell references */
4314 if ((shell = getenv("EMXSHELL")) == NULL)
4315 if ((shell = getenv("COMSPEC")) == NULL)
4316 {
4317 errno = ENOENT;
4318 return posix_error();
4319 }
4320
4321 sh_name = _getname(shell);
4322 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4323 opt = "/c";
4324 else
4325 opt = "-c";
4326
4327 /* save current stdio fds + their flags, and set not inheritable */
4328 i = pipe_err = 0;
4329 while (pipe_err >= 0 && i < 3)
4330 {
4331 pipe_err = stdio[i].handle = dup(i);
4332 stdio[i].flags = fcntl(i, F_GETFD, 0);
4333 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4334 i++;
4335 }
4336 if (pipe_err < 0)
4337 {
4338 /* didn't get them all saved - clean up and bail out */
4339 int saved_err = errno;
4340 while (i-- > 0)
4341 {
4342 close(stdio[i].handle);
4343 }
4344 errno = saved_err;
4345 return posix_error();
4346 }
4347
4348 /* create pipe ends */
4349 file_count = 2;
4350 if (n == POPEN_3)
4351 file_count = 3;
4352 i = pipe_err = 0;
4353 while ((pipe_err == 0) && (i < file_count))
4354 pipe_err = pipe((int *)&p_fd[i++]);
4355 if (pipe_err < 0)
4356 {
4357 /* didn't get them all made - clean up and bail out */
4358 while (i-- > 0)
4359 {
4360 close(p_fd[i].wr);
4361 close(p_fd[i].rd);
4362 }
4363 errno = EPIPE;
4364 return posix_error();
4365 }
4366
4367 /* change the actual standard IO streams over temporarily,
4368 * making the retained pipe ends non-inheritable
4369 */
4370 pipe_err = 0;
4371
4372 /* - stdin */
4373 if (dup2(p_fd[0].rd, 0) == 0)
4374 {
4375 close(p_fd[0].rd);
4376 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4377 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4378 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4379 {
4380 close(p_fd[0].wr);
4381 pipe_err = -1;
4382 }
4383 }
4384 else
4385 {
4386 pipe_err = -1;
4387 }
4388
4389 /* - stdout */
4390 if (pipe_err == 0)
4391 {
4392 if (dup2(p_fd[1].wr, 1) == 1)
4393 {
4394 close(p_fd[1].wr);
4395 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4396 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4397 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4398 {
4399 close(p_fd[1].rd);
4400 pipe_err = -1;
4401 }
4402 }
4403 else
4404 {
4405 pipe_err = -1;
4406 }
4407 }
4408
4409 /* - stderr, as required */
4410 if (pipe_err == 0)
4411 switch (n)
4412 {
4413 case POPEN_3:
4414 {
4415 if (dup2(p_fd[2].wr, 2) == 2)
4416 {
4417 close(p_fd[2].wr);
4418 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4419 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4420 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4421 {
4422 close(p_fd[2].rd);
4423 pipe_err = -1;
4424 }
4425 }
4426 else
4427 {
4428 pipe_err = -1;
4429 }
4430 break;
4431 }
4432
4433 case POPEN_4:
4434 {
4435 if (dup2(1, 2) != 2)
4436 {
4437 pipe_err = -1;
4438 }
4439 break;
4440 }
4441 }
4442
4443 /* spawn the child process */
4444 if (pipe_err == 0)
4445 {
4446 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4447 if (pipe_pid == -1)
4448 {
4449 pipe_err = -1;
4450 }
4451 else
4452 {
4453 /* save the PID into the FILE structure
4454 * NOTE: this implementation doesn't actually
4455 * take advantage of this, but do it for
4456 * completeness - AIM Apr01
4457 */
4458 for (i = 0; i < file_count; i++)
4459 p_s[i]->_pid = pipe_pid;
4460 }
4461 }
4462
4463 /* reset standard IO to normal */
4464 for (i = 0; i < 3; i++)
4465 {
4466 dup2(stdio[i].handle, i);
4467 fcntl(i, F_SETFD, stdio[i].flags);
4468 close(stdio[i].handle);
4469 }
4470
4471 /* if any remnant problems, clean up and bail out */
4472 if (pipe_err < 0)
4473 {
4474 for (i = 0; i < 3; i++)
4475 {
4476 close(p_fd[i].rd);
4477 close(p_fd[i].wr);
4478 }
4479 errno = EPIPE;
4480 return posix_error_with_filename(cmdstring);
4481 }
4482
4483 /* build tuple of file objects to return */
4484 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4485 PyFile_SetBufSize(p_f[0], bufsize);
4486 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4487 PyFile_SetBufSize(p_f[1], bufsize);
4488 if (n == POPEN_3)
4489 {
4490 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4491 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004492 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004493 }
4494 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004495 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004496
4497 /*
4498 * Insert the files we've created into the process dictionary
4499 * all referencing the list with the process handle and the
4500 * initial number of files (see description below in _PyPclose).
4501 * Since if _PyPclose later tried to wait on a process when all
4502 * handles weren't closed, it could create a deadlock with the
4503 * child, we spend some energy here to try to ensure that we
4504 * either insert all file handles into the dictionary or none
4505 * at all. It's a little clumsy with the various popen modes
4506 * and variable number of files involved.
4507 */
4508 if (!_PyPopenProcs)
4509 {
4510 _PyPopenProcs = PyDict_New();
4511 }
4512
4513 if (_PyPopenProcs)
4514 {
4515 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4516 int ins_rc[3];
4517
4518 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4519 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4520
4521 procObj = PyList_New(2);
4522 pidObj = PyInt_FromLong((long) pipe_pid);
4523 intObj = PyInt_FromLong((long) file_count);
4524
4525 if (procObj && pidObj && intObj)
4526 {
4527 PyList_SetItem(procObj, 0, pidObj);
4528 PyList_SetItem(procObj, 1, intObj);
4529
4530 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4531 if (fileObj[0])
4532 {
4533 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4534 fileObj[0],
4535 procObj);
4536 }
4537 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4538 if (fileObj[1])
4539 {
4540 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4541 fileObj[1],
4542 procObj);
4543 }
4544 if (file_count >= 3)
4545 {
4546 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4547 if (fileObj[2])
4548 {
4549 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4550 fileObj[2],
4551 procObj);
4552 }
4553 }
4554
4555 if (ins_rc[0] < 0 || !fileObj[0] ||
4556 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4557 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4558 {
4559 /* Something failed - remove any dictionary
4560 * entries that did make it.
4561 */
4562 if (!ins_rc[0] && fileObj[0])
4563 {
4564 PyDict_DelItem(_PyPopenProcs,
4565 fileObj[0]);
4566 }
4567 if (!ins_rc[1] && fileObj[1])
4568 {
4569 PyDict_DelItem(_PyPopenProcs,
4570 fileObj[1]);
4571 }
4572 if (!ins_rc[2] && fileObj[2])
4573 {
4574 PyDict_DelItem(_PyPopenProcs,
4575 fileObj[2]);
4576 }
4577 }
4578 }
Tim Peters11b23062003-04-23 02:39:17 +00004579
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004580 /*
4581 * Clean up our localized references for the dictionary keys
4582 * and value since PyDict_SetItem will Py_INCREF any copies
4583 * that got placed in the dictionary.
4584 */
4585 Py_XDECREF(procObj);
4586 Py_XDECREF(fileObj[0]);
4587 Py_XDECREF(fileObj[1]);
4588 Py_XDECREF(fileObj[2]);
4589 }
4590
4591 /* Child is launched. */
4592 return f;
4593}
4594
4595/*
4596 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4597 * exit code for the child process and return as a result of the close.
4598 *
4599 * This function uses the _PyPopenProcs dictionary in order to map the
4600 * input file pointer to information about the process that was
4601 * originally created by the popen* call that created the file pointer.
4602 * The dictionary uses the file pointer as a key (with one entry
4603 * inserted for each file returned by the original popen* call) and a
4604 * single list object as the value for all files from a single call.
4605 * The list object contains the Win32 process handle at [0], and a file
4606 * count at [1], which is initialized to the total number of file
4607 * handles using that list.
4608 *
4609 * This function closes whichever handle it is passed, and decrements
4610 * the file count in the dictionary for the process handle pointed to
4611 * by this file. On the last close (when the file count reaches zero),
4612 * this function will wait for the child process and then return its
4613 * exit code as the result of the close() operation. This permits the
4614 * files to be closed in any order - it is always the close() of the
4615 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004616 *
4617 * NOTE: This function is currently called with the GIL released.
4618 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004619 */
4620
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004621static int _PyPclose(FILE *file)
4622{
4623 int result;
4624 int exit_code;
Christian Heimesd491d712008-02-01 18:49:26 +00004625 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004626 PyObject *procObj, *pidObj, *intObj, *fileObj;
4627 int file_count;
4628#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004629 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004630#endif
4631
4632 /* Close the file handle first, to ensure it can't block the
4633 * child from exiting if it's the last handle.
4634 */
4635 result = fclose(file);
4636
4637#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004638 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004639#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004640 if (_PyPopenProcs)
4641 {
4642 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4643 (procObj = PyDict_GetItem(_PyPopenProcs,
4644 fileObj)) != NULL &&
4645 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4646 (intObj = PyList_GetItem(procObj,1)) != NULL)
4647 {
4648 pipe_pid = (int) PyInt_AsLong(pidObj);
4649 file_count = (int) PyInt_AsLong(intObj);
4650
4651 if (file_count > 1)
4652 {
4653 /* Still other files referencing process */
4654 file_count--;
4655 PyList_SetItem(procObj,1,
4656 PyInt_FromLong((long) file_count));
4657 }
4658 else
4659 {
4660 /* Last file for this process */
4661 if (result != EOF &&
4662 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4663 {
4664 /* extract exit status */
4665 if (WIFEXITED(exit_code))
4666 {
4667 result = WEXITSTATUS(exit_code);
4668 }
4669 else
4670 {
4671 errno = EPIPE;
4672 result = -1;
4673 }
4674 }
4675 else
4676 {
4677 /* Indicate failure - this will cause the file object
4678 * to raise an I/O error and translate the last
4679 * error code from errno. We do have a problem with
4680 * last errors that overlap the normal errno table,
4681 * but that's a consistent problem with the file object.
4682 */
4683 result = -1;
4684 }
4685 }
4686
4687 /* Remove this file pointer from dictionary */
4688 PyDict_DelItem(_PyPopenProcs, fileObj);
4689
4690 if (PyDict_Size(_PyPopenProcs) == 0)
4691 {
4692 Py_DECREF(_PyPopenProcs);
4693 _PyPopenProcs = NULL;
4694 }
4695
4696 } /* if object retrieval ok */
4697
4698 Py_XDECREF(fileObj);
4699 } /* if _PyPopenProcs */
4700
4701#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004702 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004703#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004704 return result;
4705}
4706
4707#endif /* PYCC_??? */
4708
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004709#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004710
4711/*
4712 * Portable 'popen' replacement for Win32.
4713 *
4714 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4715 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004716 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004717 */
4718
4719#include <malloc.h>
4720#include <io.h>
4721#include <fcntl.h>
4722
4723/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4724#define POPEN_1 1
4725#define POPEN_2 2
4726#define POPEN_3 3
4727#define POPEN_4 4
4728
4729static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004730static int _PyPclose(FILE *file);
4731
4732/*
4733 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004734 * for use when retrieving the process exit code. See _PyPclose() below
4735 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004736 */
4737static PyObject *_PyPopenProcs = NULL;
4738
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004739
4740/* popen that works from a GUI.
4741 *
4742 * The result of this function is a pipe (file) connected to the
4743 * processes stdin or stdout, depending on the requested mode.
4744 */
4745
4746static PyObject *
4747posix_popen(PyObject *self, PyObject *args)
4748{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004749 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004750 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004751
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004752 char *cmdstring;
4753 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004754 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004755 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004756 return NULL;
4757
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004758 if (*mode == 'r')
4759 tm = _O_RDONLY;
4760 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004761 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004762 return NULL;
4763 } else
4764 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004765
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004766 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004767 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004768 return NULL;
4769 }
4770
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004771 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004772 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004773 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004774 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004775 else
4776 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4777
4778 return f;
4779}
4780
4781/* Variation on win32pipe.popen
4782 *
4783 * The result of this function is a pipe (file) connected to the
4784 * process's stdin, and a pipe connected to the process's stdout.
4785 */
4786
4787static PyObject *
4788win32_popen2(PyObject *self, PyObject *args)
4789{
4790 PyObject *f;
4791 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004792
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004793 char *cmdstring;
4794 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004795 int bufsize = -1;
4796 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004797 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004798
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004799 if (*mode == 't')
4800 tm = _O_TEXT;
4801 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004802 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004803 return NULL;
4804 } else
4805 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004806
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004807 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004808 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004809 return NULL;
4810 }
4811
4812 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004813
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004814 return f;
4815}
4816
4817/*
4818 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004819 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004820 * The result of this function is 3 pipes - the process's stdin,
4821 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004822 */
4823
4824static PyObject *
4825win32_popen3(PyObject *self, PyObject *args)
4826{
4827 PyObject *f;
4828 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004829
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004830 char *cmdstring;
4831 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004832 int bufsize = -1;
4833 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004834 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004835
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004836 if (*mode == 't')
4837 tm = _O_TEXT;
4838 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004839 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004840 return NULL;
4841 } else
4842 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004843
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004844 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004845 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004846 return NULL;
4847 }
4848
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004849 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004850
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004851 return f;
4852}
4853
4854/*
4855 * Variation on win32pipe.popen
4856 *
Tim Peters5aa91602002-01-30 05:46:57 +00004857 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004858 * and stdout+stderr combined as a single pipe.
4859 */
4860
4861static PyObject *
4862win32_popen4(PyObject *self, PyObject *args)
4863{
4864 PyObject *f;
4865 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004866
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004867 char *cmdstring;
4868 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004869 int bufsize = -1;
4870 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004871 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004872
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004873 if (*mode == 't')
4874 tm = _O_TEXT;
4875 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004876 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004877 return NULL;
4878 } else
4879 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004880
4881 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004882 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004883 return NULL;
4884 }
4885
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004886 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004887
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004888 return f;
4889}
4890
Mark Hammond08501372001-01-31 07:30:29 +00004891static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004892_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004893 HANDLE hStdin,
4894 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004895 HANDLE hStderr,
4896 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004897{
4898 PROCESS_INFORMATION piProcInfo;
4899 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004900 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004901 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004902 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004903 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004904 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004905
4906 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004907 char *comshell;
4908
Tim Peters92e4dd82002-10-05 01:47:34 +00004909 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004910 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004911 /* x < i, so x fits into an integer */
4912 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004913
4914 /* Explicitly check if we are using COMMAND.COM. If we are
4915 * then use the w9xpopen hack.
4916 */
4917 comshell = s1 + x;
4918 while (comshell >= s1 && *comshell != '\\')
4919 --comshell;
4920 ++comshell;
4921
4922 if (GetVersion() < 0x80000000 &&
4923 _stricmp(comshell, "command.com") != 0) {
4924 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004925 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004926 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004927 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004928 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004929 }
4930 else {
4931 /*
Tim Peters402d5982001-08-27 06:37:48 +00004932 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4933 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004934 */
Mark Hammond08501372001-01-31 07:30:29 +00004935 char modulepath[_MAX_PATH];
4936 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004937 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Martin v. Löwis26fd9602006-04-22 11:15:41 +00004938 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004939 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004940 x = i+1;
4941 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004942 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004943 strncat(modulepath,
4944 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004945 (sizeof(modulepath)/sizeof(modulepath[0]))
4946 -strlen(modulepath));
4947 if (stat(modulepath, &statinfo) != 0) {
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00004948 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
Tim Peters5aa91602002-01-30 05:46:57 +00004949 /* Eeek - file-not-found - possibly an embedding
4950 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004951 */
Tim Peters5aa91602002-01-30 05:46:57 +00004952 strncpy(modulepath,
4953 Py_GetExecPrefix(),
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00004954 mplen);
4955 modulepath[mplen-1] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004956 if (modulepath[strlen(modulepath)-1] != '\\')
4957 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004958 strncat(modulepath,
4959 szConsoleSpawn,
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00004960 mplen-strlen(modulepath));
Mark Hammond08501372001-01-31 07:30:29 +00004961 /* No where else to look - raise an easily identifiable
4962 error, rather than leaving Windows to report
4963 "file not found" - as the user is probably blissfully
4964 unaware this shim EXE is used, and it will confuse them.
4965 (well, it confused me for a while ;-)
4966 */
4967 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004968 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004969 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004970 "for popen to work with your shell "
4971 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004972 szConsoleSpawn);
4973 return FALSE;
4974 }
4975 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004976 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004977 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004978 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004979
Tim Peters92e4dd82002-10-05 01:47:34 +00004980 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004981 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004982 /* To maintain correct argument passing semantics,
4983 we pass the command-line as it stands, and allow
4984 quoting to be applied. w9xpopen.exe will then
4985 use its argv vector, and re-quote the necessary
4986 args for the ultimate child process.
4987 */
Tim Peters75cdad52001-11-28 22:07:30 +00004988 PyOS_snprintf(
4989 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004990 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004991 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004992 s1,
4993 s3,
4994 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004995 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004996 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004997 dialog:
4998 "Your program accessed mem currently in use at xxx"
4999 and a hopeful warning about the stability of your
5000 system.
5001 Cost is Ctrl+C wont kill children, but anyone
5002 who cares can have a go!
5003 */
5004 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005005 }
5006 }
5007
5008 /* Could be an else here to try cmd.exe / command.com in the path
5009 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00005010 else {
Tim Peters402d5982001-08-27 06:37:48 +00005011 PyErr_SetString(PyExc_RuntimeError,
5012 "Cannot locate a COMSPEC environment variable to "
5013 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00005014 return FALSE;
5015 }
Tim Peters5aa91602002-01-30 05:46:57 +00005016
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005017 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5018 siStartInfo.cb = sizeof(STARTUPINFO);
5019 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5020 siStartInfo.hStdInput = hStdin;
5021 siStartInfo.hStdOutput = hStdout;
5022 siStartInfo.hStdError = hStderr;
5023 siStartInfo.wShowWindow = SW_HIDE;
5024
5025 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005026 s2,
5027 NULL,
5028 NULL,
5029 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005030 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005031 NULL,
5032 NULL,
5033 &siStartInfo,
5034 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005035 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005036 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005037
Mark Hammondb37a3732000-08-14 04:47:33 +00005038 /* Return process handle */
5039 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005040 return TRUE;
5041 }
Tim Peters402d5982001-08-27 06:37:48 +00005042 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005043 return FALSE;
5044}
5045
5046/* The following code is based off of KB: Q190351 */
5047
5048static PyObject *
5049_PyPopen(char *cmdstring, int mode, int n)
5050{
5051 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5052 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00005053 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005054
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005055 SECURITY_ATTRIBUTES saAttr;
5056 BOOL fSuccess;
5057 int fd1, fd2, fd3;
5058 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00005059 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005060 PyObject *f;
5061
5062 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5063 saAttr.bInheritHandle = TRUE;
5064 saAttr.lpSecurityDescriptor = NULL;
5065
5066 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5067 return win32_error("CreatePipe", NULL);
5068
5069 /* Create new output read handle and the input write handle. Set
5070 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005071 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005072 * being created. */
5073 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005074 GetCurrentProcess(), &hChildStdinWrDup, 0,
5075 FALSE,
5076 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005077 if (!fSuccess)
5078 return win32_error("DuplicateHandle", NULL);
5079
5080 /* Close the inheritable version of ChildStdin
5081 that we're using. */
5082 CloseHandle(hChildStdinWr);
5083
5084 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5085 return win32_error("CreatePipe", NULL);
5086
5087 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005088 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5089 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005090 if (!fSuccess)
5091 return win32_error("DuplicateHandle", NULL);
5092
5093 /* Close the inheritable version of ChildStdout
5094 that we're using. */
5095 CloseHandle(hChildStdoutRd);
5096
5097 if (n != POPEN_4) {
5098 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5099 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005100 fSuccess = DuplicateHandle(GetCurrentProcess(),
5101 hChildStderrRd,
5102 GetCurrentProcess(),
5103 &hChildStderrRdDup, 0,
5104 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005105 if (!fSuccess)
5106 return win32_error("DuplicateHandle", NULL);
5107 /* Close the inheritable version of ChildStdErr that we're using. */
5108 CloseHandle(hChildStderrRd);
5109 }
Tim Peters5aa91602002-01-30 05:46:57 +00005110
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005111 switch (n) {
5112 case POPEN_1:
5113 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5114 case _O_WRONLY | _O_TEXT:
5115 /* Case for writing to child Stdin in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005116 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005117 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005118 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005119 PyFile_SetBufSize(f, 0);
5120 /* We don't care about these pipes anymore, so close them. */
5121 CloseHandle(hChildStdoutRdDup);
5122 CloseHandle(hChildStderrRdDup);
5123 break;
5124
5125 case _O_RDONLY | _O_TEXT:
5126 /* Case for reading from child Stdout in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005127 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005128 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005129 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005130 PyFile_SetBufSize(f, 0);
5131 /* We don't care about these pipes anymore, so close them. */
5132 CloseHandle(hChildStdinWrDup);
5133 CloseHandle(hChildStderrRdDup);
5134 break;
5135
5136 case _O_RDONLY | _O_BINARY:
5137 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005138 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005139 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005140 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005141 PyFile_SetBufSize(f, 0);
5142 /* We don't care about these pipes anymore, so close them. */
5143 CloseHandle(hChildStdinWrDup);
5144 CloseHandle(hChildStderrRdDup);
5145 break;
5146
5147 case _O_WRONLY | _O_BINARY:
5148 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005149 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005150 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005151 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005152 PyFile_SetBufSize(f, 0);
5153 /* We don't care about these pipes anymore, so close them. */
5154 CloseHandle(hChildStdoutRdDup);
5155 CloseHandle(hChildStderrRdDup);
5156 break;
5157 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005158 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005159 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005160
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005161 case POPEN_2:
5162 case POPEN_4:
5163 {
5164 char *m1, *m2;
5165 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005166
Tim Peters7dca21e2002-08-19 00:42:29 +00005167 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005168 m1 = "r";
5169 m2 = "w";
5170 } else {
5171 m1 = "rb";
5172 m2 = "wb";
5173 }
5174
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005175 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005176 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005177 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005178 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005179 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005180 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00005181 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005182 PyFile_SetBufSize(p2, 0);
5183
5184 if (n != 4)
5185 CloseHandle(hChildStderrRdDup);
5186
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005187 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00005188 Py_XDECREF(p1);
5189 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00005190 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005191 break;
5192 }
Tim Peters5aa91602002-01-30 05:46:57 +00005193
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005194 case POPEN_3:
5195 {
5196 char *m1, *m2;
5197 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005198
Tim Peters7dca21e2002-08-19 00:42:29 +00005199 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005200 m1 = "r";
5201 m2 = "w";
5202 } else {
5203 m1 = "rb";
5204 m2 = "wb";
5205 }
5206
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005207 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005208 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005209 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005210 f2 = _fdopen(fd2, m1);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005211 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005212 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005213 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00005214 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5215 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005216 PyFile_SetBufSize(p1, 0);
5217 PyFile_SetBufSize(p2, 0);
5218 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005219 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00005220 Py_XDECREF(p1);
5221 Py_XDECREF(p2);
5222 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00005223 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005224 break;
5225 }
5226 }
5227
5228 if (n == POPEN_4) {
5229 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005230 hChildStdinRd,
5231 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005232 hChildStdoutWr,
5233 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005234 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005235 }
5236 else {
5237 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005238 hChildStdinRd,
5239 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005240 hChildStderrWr,
5241 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005242 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005243 }
5244
Mark Hammondb37a3732000-08-14 04:47:33 +00005245 /*
5246 * Insert the files we've created into the process dictionary
5247 * all referencing the list with the process handle and the
5248 * initial number of files (see description below in _PyPclose).
5249 * Since if _PyPclose later tried to wait on a process when all
5250 * handles weren't closed, it could create a deadlock with the
5251 * child, we spend some energy here to try to ensure that we
5252 * either insert all file handles into the dictionary or none
5253 * at all. It's a little clumsy with the various popen modes
5254 * and variable number of files involved.
5255 */
5256 if (!_PyPopenProcs) {
5257 _PyPopenProcs = PyDict_New();
5258 }
5259
5260 if (_PyPopenProcs) {
5261 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5262 int ins_rc[3];
5263
5264 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5265 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
5266
5267 procObj = PyList_New(2);
5268 hProcessObj = PyLong_FromVoidPtr(hProcess);
5269 intObj = PyInt_FromLong(file_count);
5270
5271 if (procObj && hProcessObj && intObj) {
5272 PyList_SetItem(procObj,0,hProcessObj);
5273 PyList_SetItem(procObj,1,intObj);
5274
5275 fileObj[0] = PyLong_FromVoidPtr(f1);
5276 if (fileObj[0]) {
5277 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5278 fileObj[0],
5279 procObj);
5280 }
5281 if (file_count >= 2) {
5282 fileObj[1] = PyLong_FromVoidPtr(f2);
5283 if (fileObj[1]) {
5284 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5285 fileObj[1],
5286 procObj);
5287 }
5288 }
5289 if (file_count >= 3) {
5290 fileObj[2] = PyLong_FromVoidPtr(f3);
5291 if (fileObj[2]) {
5292 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5293 fileObj[2],
5294 procObj);
5295 }
5296 }
5297
5298 if (ins_rc[0] < 0 || !fileObj[0] ||
5299 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5300 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5301 /* Something failed - remove any dictionary
5302 * entries that did make it.
5303 */
5304 if (!ins_rc[0] && fileObj[0]) {
5305 PyDict_DelItem(_PyPopenProcs,
5306 fileObj[0]);
5307 }
5308 if (!ins_rc[1] && fileObj[1]) {
5309 PyDict_DelItem(_PyPopenProcs,
5310 fileObj[1]);
5311 }
5312 if (!ins_rc[2] && fileObj[2]) {
5313 PyDict_DelItem(_PyPopenProcs,
5314 fileObj[2]);
5315 }
5316 }
5317 }
Tim Peters5aa91602002-01-30 05:46:57 +00005318
Mark Hammondb37a3732000-08-14 04:47:33 +00005319 /*
5320 * Clean up our localized references for the dictionary keys
5321 * and value since PyDict_SetItem will Py_INCREF any copies
5322 * that got placed in the dictionary.
5323 */
5324 Py_XDECREF(procObj);
5325 Py_XDECREF(fileObj[0]);
5326 Py_XDECREF(fileObj[1]);
5327 Py_XDECREF(fileObj[2]);
5328 }
5329
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005330 /* Child is launched. Close the parents copy of those pipe
5331 * handles that only the child should have open. You need to
5332 * make sure that no handles to the write end of the output pipe
5333 * are maintained in this process or else the pipe will not close
5334 * when the child process exits and the ReadFile will hang. */
5335
5336 if (!CloseHandle(hChildStdinRd))
5337 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005338
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005339 if (!CloseHandle(hChildStdoutWr))
5340 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005341
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005342 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5343 return win32_error("CloseHandle", NULL);
5344
5345 return f;
5346}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005347
5348/*
5349 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5350 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005351 *
5352 * This function uses the _PyPopenProcs dictionary in order to map the
5353 * input file pointer to information about the process that was
5354 * originally created by the popen* call that created the file pointer.
5355 * The dictionary uses the file pointer as a key (with one entry
5356 * inserted for each file returned by the original popen* call) and a
5357 * single list object as the value for all files from a single call.
5358 * The list object contains the Win32 process handle at [0], and a file
5359 * count at [1], which is initialized to the total number of file
5360 * handles using that list.
5361 *
5362 * This function closes whichever handle it is passed, and decrements
5363 * the file count in the dictionary for the process handle pointed to
5364 * by this file. On the last close (when the file count reaches zero),
5365 * this function will wait for the child process and then return its
5366 * exit code as the result of the close() operation. This permits the
5367 * files to be closed in any order - it is always the close() of the
5368 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005369 *
5370 * NOTE: This function is currently called with the GIL released.
5371 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005372 */
Tim Peters736aa322000-09-01 06:51:24 +00005373
Fredrik Lundh56055a42000-07-23 19:47:12 +00005374static int _PyPclose(FILE *file)
5375{
Fredrik Lundh20318932000-07-26 17:29:12 +00005376 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005377 DWORD exit_code;
5378 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00005379 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5380 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005381#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005382 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005383#endif
5384
Fredrik Lundh20318932000-07-26 17:29:12 +00005385 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00005386 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00005387 */
5388 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005389#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005390 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005391#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005392 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005393 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5394 (procObj = PyDict_GetItem(_PyPopenProcs,
5395 fileObj)) != NULL &&
5396 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5397 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5398
5399 hProcess = PyLong_AsVoidPtr(hProcessObj);
5400 file_count = PyInt_AsLong(intObj);
5401
5402 if (file_count > 1) {
5403 /* Still other files referencing process */
5404 file_count--;
5405 PyList_SetItem(procObj,1,
5406 PyInt_FromLong(file_count));
5407 } else {
5408 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00005409 if (result != EOF &&
5410 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5411 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00005412 /* Possible truncation here in 16-bit environments, but
5413 * real exit codes are just the lower byte in any event.
5414 */
5415 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005416 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00005417 /* Indicate failure - this will cause the file object
5418 * to raise an I/O error and translate the last Win32
5419 * error code from errno. We do have a problem with
5420 * last errors that overlap the normal errno table,
5421 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005422 */
Fredrik Lundh20318932000-07-26 17:29:12 +00005423 if (result != EOF) {
5424 /* If the error wasn't from the fclose(), then
5425 * set errno for the file object error handling.
5426 */
5427 errno = GetLastError();
5428 }
5429 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005430 }
5431
5432 /* Free up the native handle at this point */
5433 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00005434 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005435
Mark Hammondb37a3732000-08-14 04:47:33 +00005436 /* Remove this file pointer from dictionary */
5437 PyDict_DelItem(_PyPopenProcs, fileObj);
5438
5439 if (PyDict_Size(_PyPopenProcs) == 0) {
5440 Py_DECREF(_PyPopenProcs);
5441 _PyPopenProcs = NULL;
5442 }
5443
5444 } /* if object retrieval ok */
5445
5446 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005447 } /* if _PyPopenProcs */
5448
Tim Peters736aa322000-09-01 06:51:24 +00005449#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005450 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005451#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005452 return result;
5453}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005454
5455#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005456static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005457posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005458{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005459 char *name;
5460 char *mode = "r";
5461 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00005462 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005463 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005464 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00005465 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00005466 /* Strip mode of binary or text modifiers */
5467 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5468 mode = "r";
5469 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5470 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00005471 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005472 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005473 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00005474 if (fp == NULL)
5475 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005476 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005477 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005478 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005479 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005480}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005481
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005482#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005483#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005484
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005485
Guido van Rossumb6775db1994-08-01 11:34:53 +00005486#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005487PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005488"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005489Set the current process's user id.");
5490
Barry Warsaw53699e91996-12-10 23:23:01 +00005491static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005492posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005493{
5494 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005495 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005496 return NULL;
5497 if (setuid(uid) < 0)
5498 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005499 Py_INCREF(Py_None);
5500 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005501}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005502#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005503
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005504
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005505#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005506PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005507"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005508Set the current process's effective user id.");
5509
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005510static PyObject *
5511posix_seteuid (PyObject *self, PyObject *args)
5512{
5513 int euid;
5514 if (!PyArg_ParseTuple(args, "i", &euid)) {
5515 return NULL;
5516 } else if (seteuid(euid) < 0) {
5517 return posix_error();
5518 } else {
5519 Py_INCREF(Py_None);
5520 return Py_None;
5521 }
5522}
5523#endif /* HAVE_SETEUID */
5524
5525#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005526PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005527"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005528Set the current process's effective group id.");
5529
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005530static PyObject *
5531posix_setegid (PyObject *self, PyObject *args)
5532{
5533 int egid;
5534 if (!PyArg_ParseTuple(args, "i", &egid)) {
5535 return NULL;
5536 } else if (setegid(egid) < 0) {
5537 return posix_error();
5538 } else {
5539 Py_INCREF(Py_None);
5540 return Py_None;
5541 }
5542}
5543#endif /* HAVE_SETEGID */
5544
5545#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005546PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005547"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005548Set the current process's real and effective user ids.");
5549
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005550static PyObject *
5551posix_setreuid (PyObject *self, PyObject *args)
5552{
5553 int ruid, euid;
5554 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
5555 return NULL;
5556 } else if (setreuid(ruid, euid) < 0) {
5557 return posix_error();
5558 } else {
5559 Py_INCREF(Py_None);
5560 return Py_None;
5561 }
5562}
5563#endif /* HAVE_SETREUID */
5564
5565#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005566PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005567"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005568Set the current process's real and effective group ids.");
5569
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005570static PyObject *
5571posix_setregid (PyObject *self, PyObject *args)
5572{
5573 int rgid, egid;
5574 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
5575 return NULL;
5576 } else if (setregid(rgid, egid) < 0) {
5577 return posix_error();
5578 } else {
5579 Py_INCREF(Py_None);
5580 return Py_None;
5581 }
5582}
5583#endif /* HAVE_SETREGID */
5584
Guido van Rossumb6775db1994-08-01 11:34:53 +00005585#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005586PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005587"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005588Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005589
Barry Warsaw53699e91996-12-10 23:23:01 +00005590static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005591posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005592{
5593 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005594 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005595 return NULL;
5596 if (setgid(gid) < 0)
5597 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005598 Py_INCREF(Py_None);
5599 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005600}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005601#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005602
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005603#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005604PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005605"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005606Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005607
5608static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005609posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005610{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005611 int i, len;
5612 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005613
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005614 if (!PySequence_Check(groups)) {
5615 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5616 return NULL;
5617 }
5618 len = PySequence_Size(groups);
5619 if (len > MAX_GROUPS) {
5620 PyErr_SetString(PyExc_ValueError, "too many groups");
5621 return NULL;
5622 }
5623 for(i = 0; i < len; i++) {
5624 PyObject *elem;
5625 elem = PySequence_GetItem(groups, i);
5626 if (!elem)
5627 return NULL;
5628 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005629 if (!PyLong_Check(elem)) {
5630 PyErr_SetString(PyExc_TypeError,
5631 "groups must be integers");
5632 Py_DECREF(elem);
5633 return NULL;
5634 } else {
5635 unsigned long x = PyLong_AsUnsignedLong(elem);
5636 if (PyErr_Occurred()) {
5637 PyErr_SetString(PyExc_TypeError,
5638 "group id too big");
5639 Py_DECREF(elem);
5640 return NULL;
5641 }
5642 grouplist[i] = x;
5643 /* read back the value to see if it fitted in gid_t */
5644 if (grouplist[i] != x) {
5645 PyErr_SetString(PyExc_TypeError,
5646 "group id too big");
5647 Py_DECREF(elem);
5648 return NULL;
5649 }
5650 }
5651 } else {
5652 long x = PyInt_AsLong(elem);
5653 grouplist[i] = x;
5654 if (grouplist[i] != x) {
5655 PyErr_SetString(PyExc_TypeError,
5656 "group id too big");
5657 Py_DECREF(elem);
5658 return NULL;
5659 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005660 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005661 Py_DECREF(elem);
5662 }
5663
5664 if (setgroups(len, grouplist) < 0)
5665 return posix_error();
5666 Py_INCREF(Py_None);
5667 return Py_None;
5668}
5669#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005670
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005671#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005672static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00005673wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00005674{
5675 PyObject *result;
5676 static PyObject *struct_rusage;
5677
5678 if (pid == -1)
5679 return posix_error();
5680
5681 if (struct_rusage == NULL) {
Christian Heimes000a0742008-01-03 22:16:32 +00005682 PyObject *m = PyImport_ImportModuleNoBlock("resource");
Neal Norwitz05a45592006-03-20 06:30:08 +00005683 if (m == NULL)
5684 return NULL;
5685 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5686 Py_DECREF(m);
5687 if (struct_rusage == NULL)
5688 return NULL;
5689 }
5690
5691 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5692 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5693 if (!result)
5694 return NULL;
5695
5696#ifndef doubletime
5697#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5698#endif
5699
5700 PyStructSequence_SET_ITEM(result, 0,
5701 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5702 PyStructSequence_SET_ITEM(result, 1,
5703 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5704#define SET_INT(result, index, value)\
5705 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5706 SET_INT(result, 2, ru->ru_maxrss);
5707 SET_INT(result, 3, ru->ru_ixrss);
5708 SET_INT(result, 4, ru->ru_idrss);
5709 SET_INT(result, 5, ru->ru_isrss);
5710 SET_INT(result, 6, ru->ru_minflt);
5711 SET_INT(result, 7, ru->ru_majflt);
5712 SET_INT(result, 8, ru->ru_nswap);
5713 SET_INT(result, 9, ru->ru_inblock);
5714 SET_INT(result, 10, ru->ru_oublock);
5715 SET_INT(result, 11, ru->ru_msgsnd);
5716 SET_INT(result, 12, ru->ru_msgrcv);
5717 SET_INT(result, 13, ru->ru_nsignals);
5718 SET_INT(result, 14, ru->ru_nvcsw);
5719 SET_INT(result, 15, ru->ru_nivcsw);
5720#undef SET_INT
5721
5722 if (PyErr_Occurred()) {
5723 Py_DECREF(result);
5724 return NULL;
5725 }
5726
Neal Norwitz9b00a562006-03-20 08:47:12 +00005727 return Py_BuildValue("iiN", pid, status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005728}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005729#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005730
5731#ifdef HAVE_WAIT3
5732PyDoc_STRVAR(posix_wait3__doc__,
5733"wait3(options) -> (pid, status, rusage)\n\n\
5734Wait for completion of a child process.");
5735
5736static PyObject *
5737posix_wait3(PyObject *self, PyObject *args)
5738{
Christian Heimesd491d712008-02-01 18:49:26 +00005739 pid_t pid;
5740 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005741 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005742 WAIT_TYPE status;
5743 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005744
5745 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5746 return NULL;
5747
5748 Py_BEGIN_ALLOW_THREADS
5749 pid = wait3(&status, options, &ru);
5750 Py_END_ALLOW_THREADS
5751
Neal Norwitzd5a37542006-03-20 06:48:34 +00005752 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005753}
5754#endif /* HAVE_WAIT3 */
5755
5756#ifdef HAVE_WAIT4
5757PyDoc_STRVAR(posix_wait4__doc__,
5758"wait4(pid, options) -> (pid, status, rusage)\n\n\
5759Wait for completion of a given child process.");
5760
5761static PyObject *
5762posix_wait4(PyObject *self, PyObject *args)
5763{
Christian Heimesd491d712008-02-01 18:49:26 +00005764 pid_t pid;
5765 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005766 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005767 WAIT_TYPE status;
5768 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005769
5770 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5771 return NULL;
5772
5773 Py_BEGIN_ALLOW_THREADS
5774 pid = wait4(pid, &status, options, &ru);
5775 Py_END_ALLOW_THREADS
5776
Neal Norwitzd5a37542006-03-20 06:48:34 +00005777 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005778}
5779#endif /* HAVE_WAIT4 */
5780
Guido van Rossumb6775db1994-08-01 11:34:53 +00005781#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005782PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005783"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005784Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005785
Barry Warsaw53699e91996-12-10 23:23:01 +00005786static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005787posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005788{
Christian Heimesd491d712008-02-01 18:49:26 +00005789 pid_t pid;
5790 int options;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005791 WAIT_TYPE status;
5792 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005793
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005794 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005795 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005796 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005797 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005798 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005799 if (pid == -1)
5800 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005801
5802 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005803}
5804
Tim Petersab034fa2002-02-01 11:27:43 +00005805#elif defined(HAVE_CWAIT)
5806
5807/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005808PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005809"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005810"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005811
5812static PyObject *
5813posix_waitpid(PyObject *self, PyObject *args)
5814{
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005815 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005816 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005817
5818 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5819 return NULL;
5820 Py_BEGIN_ALLOW_THREADS
5821 pid = _cwait(&status, pid, options);
5822 Py_END_ALLOW_THREADS
5823 if (pid == -1)
5824 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005825
5826 /* shift the status left a byte so this is more like the POSIX waitpid */
5827 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005828}
5829#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005830
Guido van Rossumad0ee831995-03-01 10:34:45 +00005831#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005832PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005833"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005834Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005835
Barry Warsaw53699e91996-12-10 23:23:01 +00005836static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005837posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005838{
Christian Heimesd491d712008-02-01 18:49:26 +00005839 pid_t pid;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005840 WAIT_TYPE status;
5841 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005842
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005843 Py_BEGIN_ALLOW_THREADS
5844 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005845 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005846 if (pid == -1)
5847 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005848
5849 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005850}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005851#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005852
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005853
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005854PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005855"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005856Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005857
Barry Warsaw53699e91996-12-10 23:23:01 +00005858static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005859posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005860{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005861#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005862 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005863#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005864#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005865 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005866#else
5867 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5868#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005869#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005870}
5871
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005872
Guido van Rossumb6775db1994-08-01 11:34:53 +00005873#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005874PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005875"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005876Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005877
Barry Warsaw53699e91996-12-10 23:23:01 +00005878static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005879posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005880{
Ronald Oussoren10168f22006-10-22 10:45:18 +00005881 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005882 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005883 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005884 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00005885#ifdef Py_USING_UNICODE
5886 int arg_is_unicode = 0;
5887#endif
5888
5889 if (!PyArg_ParseTuple(args, "et:readlink",
5890 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005891 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00005892#ifdef Py_USING_UNICODE
5893 v = PySequence_GetItem(args, 0);
Neal Norwitz91a57212007-08-12 17:11:13 +00005894 if (v == NULL) {
5895 PyMem_Free(path);
5896 return NULL;
5897 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00005898
5899 if (PyUnicode_Check(v)) {
5900 arg_is_unicode = 1;
5901 }
5902 Py_DECREF(v);
5903#endif
5904
Barry Warsaw53699e91996-12-10 23:23:01 +00005905 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005906 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005907 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005908 if (n < 0)
Neal Norwitz91a57212007-08-12 17:11:13 +00005909 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00005910
Neal Norwitz91a57212007-08-12 17:11:13 +00005911 PyMem_Free(path);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00005912 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00005913#ifdef Py_USING_UNICODE
5914 if (arg_is_unicode) {
5915 PyObject *w;
5916
5917 w = PyUnicode_FromEncodedObject(v,
5918 Py_FileSystemDefaultEncoding,
5919 "strict");
5920 if (w != NULL) {
5921 Py_DECREF(v);
5922 v = w;
5923 }
5924 else {
5925 /* fall back to the original byte string, as
5926 discussed in patch #683592 */
5927 PyErr_Clear();
5928 }
5929 }
5930#endif
5931 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005932}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005933#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005934
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005935
Guido van Rossumb6775db1994-08-01 11:34:53 +00005936#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005937PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005938"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005939Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005940
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005941static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005942posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005943{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00005944 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005945}
5946#endif /* HAVE_SYMLINK */
5947
5948
5949#ifdef HAVE_TIMES
5950#ifndef HZ
5951#define HZ 60 /* Universal constant :-) */
5952#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005953
Guido van Rossumd48f2521997-12-05 22:19:34 +00005954#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5955static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005956system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005957{
5958 ULONG value = 0;
5959
5960 Py_BEGIN_ALLOW_THREADS
5961 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5962 Py_END_ALLOW_THREADS
5963
5964 return value;
5965}
5966
5967static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005968posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005969{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005970 /* Currently Only Uptime is Provided -- Others Later */
5971 return Py_BuildValue("ddddd",
5972 (double)0 /* t.tms_utime / HZ */,
5973 (double)0 /* t.tms_stime / HZ */,
5974 (double)0 /* t.tms_cutime / HZ */,
5975 (double)0 /* t.tms_cstime / HZ */,
5976 (double)system_uptime() / 1000);
5977}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005978#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005979static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005980posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005981{
5982 struct tms t;
5983 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005984 errno = 0;
5985 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005986 if (c == (clock_t) -1)
5987 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005988 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005989 (double)t.tms_utime / HZ,
5990 (double)t.tms_stime / HZ,
5991 (double)t.tms_cutime / HZ,
5992 (double)t.tms_cstime / HZ,
5993 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005994}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005995#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005996#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005997
5998
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005999#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006000#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006001static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006002posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006003{
6004 FILETIME create, exit, kernel, user;
6005 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006006 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006007 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6008 /* The fields of a FILETIME structure are the hi and lo part
6009 of a 64-bit value expressed in 100 nanosecond units.
6010 1e7 is one second in such units; 1e-7 the inverse.
6011 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6012 */
Barry Warsaw53699e91996-12-10 23:23:01 +00006013 return Py_BuildValue(
6014 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006015 (double)(user.dwHighDateTime*429.4967296 +
6016 user.dwLowDateTime*1e-7),
Georg Brandl0a40ffb2008-02-13 07:20:22 +00006017 (double)(kernel.dwHighDateTime*429.4967296 +
6018 kernel.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00006019 (double)0,
6020 (double)0,
6021 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006022}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006023#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006024
6025#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006026PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006027"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006028Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006029#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006030
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006031
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006032#ifdef HAVE_GETSID
6033PyDoc_STRVAR(posix_getsid__doc__,
6034"getsid(pid) -> sid\n\n\
6035Call the system call getsid().");
6036
6037static PyObject *
6038posix_getsid(PyObject *self, PyObject *args)
6039{
Christian Heimesd491d712008-02-01 18:49:26 +00006040 pid_t pid;
6041 int sid;
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006042 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
6043 return NULL;
6044 sid = getsid(pid);
6045 if (sid < 0)
6046 return posix_error();
6047 return PyInt_FromLong((long)sid);
6048}
6049#endif /* HAVE_GETSID */
6050
6051
Guido van Rossumb6775db1994-08-01 11:34:53 +00006052#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006053PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006054"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006055Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006056
Barry Warsaw53699e91996-12-10 23:23:01 +00006057static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006058posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006059{
Guido van Rossum687dd131993-05-17 08:34:16 +00006060 if (setsid() < 0)
6061 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006062 Py_INCREF(Py_None);
6063 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006064}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006065#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006066
Guido van Rossumb6775db1994-08-01 11:34:53 +00006067#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006068PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006069"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006070Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006071
Barry Warsaw53699e91996-12-10 23:23:01 +00006072static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006073posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006074{
Christian Heimesd491d712008-02-01 18:49:26 +00006075 pid_t pid;
6076 int pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006077 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00006078 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006079 if (setpgid(pid, pgrp) < 0)
6080 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006081 Py_INCREF(Py_None);
6082 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006083}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006084#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006085
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006086
Guido van Rossumb6775db1994-08-01 11:34:53 +00006087#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006088PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006089"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006090Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006091
Barry Warsaw53699e91996-12-10 23:23:01 +00006092static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006093posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006094{
Christian Heimese6a80742008-02-03 19:51:13 +00006095 int fd;
6096 pid_t pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006097 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006098 return NULL;
6099 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006100 if (pgid < 0)
6101 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006102 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006103}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006104#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006105
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006106
Guido van Rossumb6775db1994-08-01 11:34:53 +00006107#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006108PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006109"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006110Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006111
Barry Warsaw53699e91996-12-10 23:23:01 +00006112static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006113posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006114{
6115 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006116 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006117 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006118 if (tcsetpgrp(fd, pgid) < 0)
6119 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00006120 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00006121 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006122}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006123#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006124
Guido van Rossum687dd131993-05-17 08:34:16 +00006125/* Functions acting on file descriptors */
6126
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006127PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006128"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006129Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006130
Barry Warsaw53699e91996-12-10 23:23:01 +00006131static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006132posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006133{
Mark Hammondef8b6542001-05-13 08:04:26 +00006134 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006135 int flag;
6136 int mode = 0777;
6137 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006138
6139#ifdef MS_WINDOWS
6140 if (unicode_file_names()) {
6141 PyUnicodeObject *po;
6142 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6143 Py_BEGIN_ALLOW_THREADS
6144 /* PyUnicode_AS_UNICODE OK without thread
6145 lock as it is a simple dereference. */
6146 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6147 Py_END_ALLOW_THREADS
6148 if (fd < 0)
6149 return posix_error();
6150 return PyInt_FromLong((long)fd);
6151 }
6152 /* Drop the argument parsing error as narrow strings
6153 are also valid. */
6154 PyErr_Clear();
6155 }
6156#endif
6157
Tim Peters5aa91602002-01-30 05:46:57 +00006158 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00006159 Py_FileSystemDefaultEncoding, &file,
6160 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00006161 return NULL;
6162
Barry Warsaw53699e91996-12-10 23:23:01 +00006163 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006164 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00006165 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006166 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00006167 return posix_error_with_allocated_filename(file);
6168 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00006169 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006170}
6171
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006172
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006173PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006174"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006175Close a file descriptor (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_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006179{
6180 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006181 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006182 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006183 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006184 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006185 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006186 if (res < 0)
6187 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006188 Py_INCREF(Py_None);
6189 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006190}
6191
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006192
Georg Brandl309501a2008-01-19 20:22:13 +00006193PyDoc_STRVAR(posix_closerange__doc__,
6194"closerange(fd_low, fd_high)\n\n\
6195Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6196
6197static PyObject *
6198posix_closerange(PyObject *self, PyObject *args)
6199{
6200 int fd_from, fd_to, i;
6201 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6202 return NULL;
6203 Py_BEGIN_ALLOW_THREADS
6204 for (i = fd_from; i < fd_to; i++)
6205 close(i);
6206 Py_END_ALLOW_THREADS
6207 Py_RETURN_NONE;
6208}
6209
6210
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006211PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006212"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006213Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006214
Barry Warsaw53699e91996-12-10 23:23:01 +00006215static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006216posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006217{
6218 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006219 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006220 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006221 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006222 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006223 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006224 if (fd < 0)
6225 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006226 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006227}
6228
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006229
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006230PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006231"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006232Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006233
Barry Warsaw53699e91996-12-10 23:23:01 +00006234static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006235posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006236{
6237 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006238 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00006239 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006240 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006241 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00006242 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006243 if (res < 0)
6244 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006245 Py_INCREF(Py_None);
6246 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006247}
6248
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006249
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006250PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006251"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006252Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006253
Barry Warsaw53699e91996-12-10 23:23:01 +00006254static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006255posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006256{
6257 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006258#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006259 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006260#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00006261 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006262#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006263 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006264 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00006265 return NULL;
6266#ifdef SEEK_SET
6267 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6268 switch (how) {
6269 case 0: how = SEEK_SET; break;
6270 case 1: how = SEEK_CUR; break;
6271 case 2: how = SEEK_END; break;
6272 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006273#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006274
6275#if !defined(HAVE_LARGEFILE_SUPPORT)
6276 pos = PyInt_AsLong(posobj);
6277#else
6278 pos = PyLong_Check(posobj) ?
6279 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
6280#endif
6281 if (PyErr_Occurred())
6282 return NULL;
6283
Barry Warsaw53699e91996-12-10 23:23:01 +00006284 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006285#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00006286 res = _lseeki64(fd, pos, how);
6287#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006288 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006289#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006290 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006291 if (res < 0)
6292 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006293
6294#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00006295 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006296#else
6297 return PyLong_FromLongLong(res);
6298#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006299}
6300
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006301
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006302PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006303"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006304Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006305
Barry Warsaw53699e91996-12-10 23:23:01 +00006306static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006307posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006308{
Guido van Rossum8bac5461996-06-11 18:38:48 +00006309 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00006310 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006311 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00006312 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00006313 if (size < 0) {
6314 errno = EINVAL;
6315 return posix_error();
6316 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006317 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006318 if (buffer == NULL)
6319 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006320 Py_BEGIN_ALLOW_THREADS
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006321 n = read(fd, PyString_AsString(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00006322 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00006323 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006324 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00006325 return posix_error();
6326 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00006327 if (n != size)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006328 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00006329 return buffer;
6330}
6331
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006332
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006333PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006334"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006335Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006336
Barry Warsaw53699e91996-12-10 23:23:01 +00006337static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006338posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006339{
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006340 Py_buffer pbuf;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006341 int fd;
6342 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006343
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006344 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
Guido van Rossum687dd131993-05-17 08:34:16 +00006345 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006346 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006347 size = write(fd, pbuf.buf, (size_t)pbuf.len);
Barry Warsaw53699e91996-12-10 23:23:01 +00006348 Py_END_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006349 PyBuffer_Release(&pbuf);
Guido van Rossum687dd131993-05-17 08:34:16 +00006350 if (size < 0)
6351 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006352 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006353}
6354
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006355
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006356PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006357"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006358Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006359
Barry Warsaw53699e91996-12-10 23:23:01 +00006360static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006361posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006362{
6363 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00006364 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00006365 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006366 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006367 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006368#ifdef __VMS
6369 /* on OpenVMS we must ensure that all bytes are written to the file */
6370 fsync(fd);
6371#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006372 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00006373 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00006374 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00006375 if (res != 0) {
6376#ifdef MS_WINDOWS
6377 return win32_error("fstat", NULL);
6378#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006379 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006380#endif
6381 }
Tim Peters5aa91602002-01-30 05:46:57 +00006382
Martin v. Löwis14694662006-02-03 12:54:16 +00006383 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006384}
6385
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006386
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006387PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006388"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006389Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006390
Barry Warsaw53699e91996-12-10 23:23:01 +00006391static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006392posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006393{
Guido van Rossum687dd131993-05-17 08:34:16 +00006394 int fd;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006395 char *orgmode = "r";
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006396 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00006397 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00006398 PyObject *f;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006399 char *mode;
6400 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00006401 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006402
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006403 /* Sanitize mode. See fileobject.c */
6404 mode = PyMem_MALLOC(strlen(orgmode)+3);
6405 if (!mode) {
6406 PyErr_NoMemory();
6407 return NULL;
6408 }
6409 strcpy(mode, orgmode);
6410 if (_PyFile_SanitizeMode(mode)) {
6411 PyMem_FREE(mode);
Thomas Heller1f043e22002-11-07 16:00:59 +00006412 return NULL;
6413 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006414 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006415#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Georg Brandl54a188a2006-03-31 20:00:11 +00006416 if (mode[0] == 'a') {
6417 /* try to make sure the O_APPEND flag is set */
6418 int flags;
6419 flags = fcntl(fd, F_GETFL);
6420 if (flags != -1)
6421 fcntl(fd, F_SETFL, flags | O_APPEND);
6422 fp = fdopen(fd, mode);
Thomas Wouters2a9a6b02006-03-31 22:38:19 +00006423 if (fp == NULL && flags != -1)
Georg Brandl54a188a2006-03-31 20:00:11 +00006424 /* restore old mode if fdopen failed */
6425 fcntl(fd, F_SETFL, flags);
6426 } else {
6427 fp = fdopen(fd, mode);
6428 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006429#else
6430 fp = fdopen(fd, mode);
6431#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006432 Py_END_ALLOW_THREADS
Neal Norwitzd83eb312007-05-02 04:47:55 +00006433 PyMem_FREE(mode);
Guido van Rossum687dd131993-05-17 08:34:16 +00006434 if (fp == NULL)
6435 return posix_error();
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006436 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006437 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00006438 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006439 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006440}
6441
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006442PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006443"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006444Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006445connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006446
6447static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006448posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006449{
6450 int fd;
6451 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6452 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006453 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006454}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006455
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006456#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006457PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006458"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006459Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006460
Barry Warsaw53699e91996-12-10 23:23:01 +00006461static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006462posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006463{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006464#if defined(PYOS_OS2)
6465 HFILE read, write;
6466 APIRET rc;
6467
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006468 Py_BEGIN_ALLOW_THREADS
6469 rc = DosCreatePipe( &read, &write, 4096);
6470 Py_END_ALLOW_THREADS
6471 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006472 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006473
6474 return Py_BuildValue("(ii)", read, write);
6475#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006476#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00006477 int fds[2];
6478 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00006479 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006480 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00006481 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006482 if (res != 0)
6483 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006484 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006485#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00006486 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006487 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00006488 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00006489 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006490 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00006491 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00006492 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006493 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00006494 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6495 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006496 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006497#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006498#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006499}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006500#endif /* HAVE_PIPE */
6501
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006502
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006503#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006504PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006505"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006506Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006507
Barry Warsaw53699e91996-12-10 23:23:01 +00006508static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006509posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006510{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006511 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006512 int mode = 0666;
6513 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006514 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006515 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006516 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006517 res = mkfifo(filename, mode);
6518 Py_END_ALLOW_THREADS
6519 if (res < 0)
6520 return posix_error();
6521 Py_INCREF(Py_None);
6522 return Py_None;
6523}
6524#endif
6525
6526
Neal Norwitz11690112002-07-30 01:08:28 +00006527#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006528PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006529"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006530Create a filesystem node (file, device special file or named pipe)\n\
6531named filename. mode specifies both the permissions to use and the\n\
6532type of node to be created, being combined (bitwise OR) with one of\n\
6533S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006534device defines the newly created device special file (probably using\n\
6535os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006536
6537
6538static PyObject *
6539posix_mknod(PyObject *self, PyObject *args)
6540{
6541 char *filename;
6542 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006543 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006544 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00006545 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006546 return NULL;
6547 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006548 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00006549 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006550 if (res < 0)
6551 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006552 Py_INCREF(Py_None);
6553 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006554}
6555#endif
6556
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006557#ifdef HAVE_DEVICE_MACROS
6558PyDoc_STRVAR(posix_major__doc__,
6559"major(device) -> major number\n\
6560Extracts a device major number from a raw device number.");
6561
6562static PyObject *
6563posix_major(PyObject *self, PyObject *args)
6564{
6565 int device;
6566 if (!PyArg_ParseTuple(args, "i:major", &device))
6567 return NULL;
6568 return PyInt_FromLong((long)major(device));
6569}
6570
6571PyDoc_STRVAR(posix_minor__doc__,
6572"minor(device) -> minor number\n\
6573Extracts a device minor number from a raw device number.");
6574
6575static PyObject *
6576posix_minor(PyObject *self, PyObject *args)
6577{
6578 int device;
6579 if (!PyArg_ParseTuple(args, "i:minor", &device))
6580 return NULL;
6581 return PyInt_FromLong((long)minor(device));
6582}
6583
6584PyDoc_STRVAR(posix_makedev__doc__,
6585"makedev(major, minor) -> device number\n\
6586Composes a raw device number from the major and minor device numbers.");
6587
6588static PyObject *
6589posix_makedev(PyObject *self, PyObject *args)
6590{
6591 int major, minor;
6592 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6593 return NULL;
6594 return PyInt_FromLong((long)makedev(major, minor));
6595}
6596#endif /* device macros */
6597
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006598
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006599#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006600PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006601"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006602Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006603
Barry Warsaw53699e91996-12-10 23:23:01 +00006604static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006605posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006606{
6607 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006608 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006609 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006610 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006611
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006612 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006613 return NULL;
6614
6615#if !defined(HAVE_LARGEFILE_SUPPORT)
6616 length = PyInt_AsLong(lenobj);
6617#else
6618 length = PyLong_Check(lenobj) ?
6619 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6620#endif
6621 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006622 return NULL;
6623
Barry Warsaw53699e91996-12-10 23:23:01 +00006624 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006625 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006626 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006627 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006628 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006629 return NULL;
6630 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006631 Py_INCREF(Py_None);
6632 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006633}
6634#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006635
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006636#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006637PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006638"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006639Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006640
Fred Drake762e2061999-08-26 17:23:54 +00006641/* Save putenv() parameters as values here, so we can collect them when they
6642 * get re-set with another call for the same key. */
6643static PyObject *posix_putenv_garbage;
6644
Tim Peters5aa91602002-01-30 05:46:57 +00006645static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006646posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006647{
6648 char *s1, *s2;
Anthony Baxter64182fe2006-04-11 12:14:09 +00006649 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006650 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006651 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006652
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006653 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006654 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006655
6656#if defined(PYOS_OS2)
6657 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6658 APIRET rc;
6659
Guido van Rossumd48f2521997-12-05 22:19:34 +00006660 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6661 if (rc != NO_ERROR)
6662 return os2_error(rc);
6663
6664 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6665 APIRET rc;
6666
Guido van Rossumd48f2521997-12-05 22:19:34 +00006667 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6668 if (rc != NO_ERROR)
6669 return os2_error(rc);
6670 } else {
6671#endif
6672
Fred Drake762e2061999-08-26 17:23:54 +00006673 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006674 len = strlen(s1) + strlen(s2) + 2;
6675 /* len includes space for a trailing \0; the size arg to
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006676 PyString_FromStringAndSize does not count that */
6677 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006678 if (newstr == NULL)
6679 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006680 newenv = PyString_AS_STRING(newstr);
Anthony Baxter64182fe2006-04-11 12:14:09 +00006681 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6682 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006683 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006684 posix_error();
6685 return NULL;
6686 }
Fred Drake762e2061999-08-26 17:23:54 +00006687 /* Install the first arg and newstr in posix_putenv_garbage;
6688 * this will cause previous value to be collected. This has to
6689 * happen after the real putenv() call because the old value
6690 * was still accessible until then. */
6691 if (PyDict_SetItem(posix_putenv_garbage,
6692 PyTuple_GET_ITEM(args, 0), newstr)) {
6693 /* really not much we can do; just leak */
6694 PyErr_Clear();
6695 }
6696 else {
6697 Py_DECREF(newstr);
6698 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006699
6700#if defined(PYOS_OS2)
6701 }
6702#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006703 Py_INCREF(Py_None);
6704 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006705}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006706#endif /* putenv */
6707
Guido van Rossumc524d952001-10-19 01:31:59 +00006708#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006709PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006710"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006711Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006712
6713static PyObject *
6714posix_unsetenv(PyObject *self, PyObject *args)
6715{
6716 char *s1;
6717
6718 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6719 return NULL;
6720
6721 unsetenv(s1);
6722
6723 /* Remove the key from posix_putenv_garbage;
6724 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006725 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006726 * old value was still accessible until then.
6727 */
6728 if (PyDict_DelItem(posix_putenv_garbage,
6729 PyTuple_GET_ITEM(args, 0))) {
6730 /* really not much we can do; just leak */
6731 PyErr_Clear();
6732 }
6733
6734 Py_INCREF(Py_None);
6735 return Py_None;
6736}
6737#endif /* unsetenv */
6738
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006739PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006740"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006741Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006742
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006743static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006744posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006745{
6746 int code;
6747 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006748 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006749 return NULL;
6750 message = strerror(code);
6751 if (message == NULL) {
6752 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006753 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006754 return NULL;
6755 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006756 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006757}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006758
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006759
Guido van Rossumc9641791998-08-04 15:26:23 +00006760#ifdef HAVE_SYS_WAIT_H
6761
Fred Drake106c1a02002-04-23 15:58:02 +00006762#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006763PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006764"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006765Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006766
6767static PyObject *
6768posix_WCOREDUMP(PyObject *self, PyObject *args)
6769{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006770 WAIT_TYPE status;
6771 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006772
Neal Norwitzd5a37542006-03-20 06:48:34 +00006773 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006774 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006775
6776 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006777}
6778#endif /* WCOREDUMP */
6779
6780#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006781PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006782"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006783Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006784job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006785
6786static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006787posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006788{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006789 WAIT_TYPE status;
6790 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006791
Neal Norwitzd5a37542006-03-20 06:48:34 +00006792 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006793 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006794
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006795 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006796}
6797#endif /* WIFCONTINUED */
6798
Guido van Rossumc9641791998-08-04 15:26:23 +00006799#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006800PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006801"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006802Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006803
6804static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006805posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006806{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006807 WAIT_TYPE status;
6808 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006809
Neal Norwitzd5a37542006-03-20 06:48:34 +00006810 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006811 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006812
Fred Drake106c1a02002-04-23 15:58:02 +00006813 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006814}
6815#endif /* WIFSTOPPED */
6816
6817#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006818PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006819"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006820Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006821
6822static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006823posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006824{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006825 WAIT_TYPE status;
6826 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006827
Neal Norwitzd5a37542006-03-20 06:48:34 +00006828 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006829 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006830
Fred Drake106c1a02002-04-23 15:58:02 +00006831 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006832}
6833#endif /* WIFSIGNALED */
6834
6835#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006836PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006837"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006838Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006839system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006840
6841static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006842posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006843{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006844 WAIT_TYPE status;
6845 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006846
Neal Norwitzd5a37542006-03-20 06:48:34 +00006847 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006848 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006849
Fred Drake106c1a02002-04-23 15:58:02 +00006850 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006851}
6852#endif /* WIFEXITED */
6853
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006854#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006855PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006856"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006857Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006858
6859static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006860posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006861{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006862 WAIT_TYPE status;
6863 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006864
Neal Norwitzd5a37542006-03-20 06:48:34 +00006865 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006866 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006867
Guido van Rossumc9641791998-08-04 15:26:23 +00006868 return Py_BuildValue("i", WEXITSTATUS(status));
6869}
6870#endif /* WEXITSTATUS */
6871
6872#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006873PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006874"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006875Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006876value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006877
6878static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006879posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006880{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006881 WAIT_TYPE status;
6882 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006883
Neal Norwitzd5a37542006-03-20 06:48:34 +00006884 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006885 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006886
Guido van Rossumc9641791998-08-04 15:26:23 +00006887 return Py_BuildValue("i", WTERMSIG(status));
6888}
6889#endif /* WTERMSIG */
6890
6891#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006892PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006893"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006894Return the signal that stopped the process that provided\n\
6895the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006896
6897static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006898posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006899{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006900 WAIT_TYPE status;
6901 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006902
Neal Norwitzd5a37542006-03-20 06:48:34 +00006903 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006904 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006905
Guido van Rossumc9641791998-08-04 15:26:23 +00006906 return Py_BuildValue("i", WSTOPSIG(status));
6907}
6908#endif /* WSTOPSIG */
6909
6910#endif /* HAVE_SYS_WAIT_H */
6911
6912
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006913#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006914#ifdef _SCO_DS
6915/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6916 needed definitions in sys/statvfs.h */
6917#define _SVID3
6918#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006919#include <sys/statvfs.h>
6920
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006921static PyObject*
6922_pystatvfs_fromstructstatvfs(struct statvfs st) {
6923 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6924 if (v == NULL)
6925 return NULL;
6926
6927#if !defined(HAVE_LARGEFILE_SUPPORT)
6928 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6929 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6930 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6931 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6932 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6933 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6934 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6935 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6936 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6937 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6938#else
6939 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6940 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006941 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006942 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006943 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006944 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006945 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006946 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006947 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006948 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006949 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006950 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006951 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006952 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006953 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6954 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6955#endif
6956
6957 return v;
6958}
6959
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006960PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006961"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006962Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006963
6964static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006965posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006966{
6967 int fd, res;
6968 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006969
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006970 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006971 return NULL;
6972 Py_BEGIN_ALLOW_THREADS
6973 res = fstatvfs(fd, &st);
6974 Py_END_ALLOW_THREADS
6975 if (res != 0)
6976 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006977
6978 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006979}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006980#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006981
6982
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006983#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006984#include <sys/statvfs.h>
6985
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006986PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006987"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006988Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006989
6990static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006991posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006992{
6993 char *path;
6994 int res;
6995 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006996 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006997 return NULL;
6998 Py_BEGIN_ALLOW_THREADS
6999 res = statvfs(path, &st);
7000 Py_END_ALLOW_THREADS
7001 if (res != 0)
7002 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007003
7004 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007005}
7006#endif /* HAVE_STATVFS */
7007
7008
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007009#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007010PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007011"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007012Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007013The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007014or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007015
7016static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007017posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007018{
7019 PyObject *result = NULL;
7020 char *dir = NULL;
7021 char *pfx = NULL;
7022 char *name;
7023
7024 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
7025 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007026
7027 if (PyErr_Warn(PyExc_RuntimeWarning,
7028 "tempnam is a potential security risk to your program") < 0)
7029 return NULL;
7030
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007031#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007032 name = _tempnam(dir, pfx);
7033#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007034 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007035#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007036 if (name == NULL)
7037 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007038 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007039 free(name);
7040 return result;
7041}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007042#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007043
7044
7045#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007046PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007047"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007048Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007049
7050static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007051posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007052{
7053 FILE *fp;
7054
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007055 fp = tmpfile();
7056 if (fp == NULL)
7057 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007058 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007059}
7060#endif
7061
7062
7063#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007064PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007065"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007066Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007067
7068static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007069posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007070{
7071 char buffer[L_tmpnam];
7072 char *name;
7073
Skip Montanaro95618b52001-08-18 18:52:10 +00007074 if (PyErr_Warn(PyExc_RuntimeWarning,
7075 "tmpnam is a potential security risk to your program") < 0)
7076 return NULL;
7077
Greg Wardb48bc172000-03-01 21:51:56 +00007078#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007079 name = tmpnam_r(buffer);
7080#else
7081 name = tmpnam(buffer);
7082#endif
7083 if (name == NULL) {
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007084 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007085#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007086 "unexpected NULL from tmpnam_r"
7087#else
7088 "unexpected NULL from tmpnam"
7089#endif
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007090 );
7091 PyErr_SetObject(PyExc_OSError, err);
7092 Py_XDECREF(err);
7093 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007094 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007095 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007096}
7097#endif
7098
7099
Fred Drakec9680921999-12-13 16:37:25 +00007100/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7101 * It maps strings representing configuration variable names to
7102 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007103 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007104 * rarely-used constants. There are three separate tables that use
7105 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007106 *
7107 * This code is always included, even if none of the interfaces that
7108 * need it are included. The #if hackery needed to avoid it would be
7109 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007110 */
7111struct constdef {
7112 char *name;
7113 long value;
7114};
7115
Fred Drake12c6e2d1999-12-14 21:25:03 +00007116static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007117conv_confname(PyObject *arg, int *valuep, struct constdef *table,
7118 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007119{
7120 if (PyInt_Check(arg)) {
7121 *valuep = PyInt_AS_LONG(arg);
7122 return 1;
7123 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007124 if (PyString_Check(arg)) {
Fred Drake12c6e2d1999-12-14 21:25:03 +00007125 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00007126 size_t lo = 0;
7127 size_t mid;
7128 size_t hi = tablesize;
7129 int cmp;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007130 char *confname = PyString_AS_STRING(arg);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007131 while (lo < hi) {
7132 mid = (lo + hi) / 2;
7133 cmp = strcmp(confname, table[mid].name);
7134 if (cmp < 0)
7135 hi = mid;
7136 else if (cmp > 0)
7137 lo = mid + 1;
7138 else {
7139 *valuep = table[mid].value;
7140 return 1;
7141 }
7142 }
7143 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
7144 }
7145 else
7146 PyErr_SetString(PyExc_TypeError,
7147 "configuration names must be strings or integers");
7148 return 0;
7149}
7150
7151
7152#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7153static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007154#ifdef _PC_ABI_AIO_XFER_MAX
7155 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
7156#endif
7157#ifdef _PC_ABI_ASYNC_IO
7158 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
7159#endif
Fred Drakec9680921999-12-13 16:37:25 +00007160#ifdef _PC_ASYNC_IO
7161 {"PC_ASYNC_IO", _PC_ASYNC_IO},
7162#endif
7163#ifdef _PC_CHOWN_RESTRICTED
7164 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
7165#endif
7166#ifdef _PC_FILESIZEBITS
7167 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
7168#endif
7169#ifdef _PC_LAST
7170 {"PC_LAST", _PC_LAST},
7171#endif
7172#ifdef _PC_LINK_MAX
7173 {"PC_LINK_MAX", _PC_LINK_MAX},
7174#endif
7175#ifdef _PC_MAX_CANON
7176 {"PC_MAX_CANON", _PC_MAX_CANON},
7177#endif
7178#ifdef _PC_MAX_INPUT
7179 {"PC_MAX_INPUT", _PC_MAX_INPUT},
7180#endif
7181#ifdef _PC_NAME_MAX
7182 {"PC_NAME_MAX", _PC_NAME_MAX},
7183#endif
7184#ifdef _PC_NO_TRUNC
7185 {"PC_NO_TRUNC", _PC_NO_TRUNC},
7186#endif
7187#ifdef _PC_PATH_MAX
7188 {"PC_PATH_MAX", _PC_PATH_MAX},
7189#endif
7190#ifdef _PC_PIPE_BUF
7191 {"PC_PIPE_BUF", _PC_PIPE_BUF},
7192#endif
7193#ifdef _PC_PRIO_IO
7194 {"PC_PRIO_IO", _PC_PRIO_IO},
7195#endif
7196#ifdef _PC_SOCK_MAXBUF
7197 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
7198#endif
7199#ifdef _PC_SYNC_IO
7200 {"PC_SYNC_IO", _PC_SYNC_IO},
7201#endif
7202#ifdef _PC_VDISABLE
7203 {"PC_VDISABLE", _PC_VDISABLE},
7204#endif
7205};
7206
Fred Drakec9680921999-12-13 16:37:25 +00007207static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007208conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007209{
7210 return conv_confname(arg, valuep, posix_constants_pathconf,
7211 sizeof(posix_constants_pathconf)
7212 / sizeof(struct constdef));
7213}
7214#endif
7215
7216#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007217PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007218"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007219Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007220If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007221
7222static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007223posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007224{
7225 PyObject *result = NULL;
7226 int name, fd;
7227
Fred Drake12c6e2d1999-12-14 21:25:03 +00007228 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7229 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00007230 long limit;
7231
7232 errno = 0;
7233 limit = fpathconf(fd, name);
7234 if (limit == -1 && errno != 0)
7235 posix_error();
7236 else
7237 result = PyInt_FromLong(limit);
7238 }
7239 return result;
7240}
7241#endif
7242
7243
7244#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007245PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007246"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007247Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007248If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007249
7250static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007251posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007252{
7253 PyObject *result = NULL;
7254 int name;
7255 char *path;
7256
7257 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7258 conv_path_confname, &name)) {
7259 long limit;
7260
7261 errno = 0;
7262 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007263 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00007264 if (errno == EINVAL)
7265 /* could be a path or name problem */
7266 posix_error();
7267 else
7268 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007269 }
Fred Drakec9680921999-12-13 16:37:25 +00007270 else
7271 result = PyInt_FromLong(limit);
7272 }
7273 return result;
7274}
7275#endif
7276
7277#ifdef HAVE_CONFSTR
7278static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007279#ifdef _CS_ARCHITECTURE
7280 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
7281#endif
7282#ifdef _CS_HOSTNAME
7283 {"CS_HOSTNAME", _CS_HOSTNAME},
7284#endif
7285#ifdef _CS_HW_PROVIDER
7286 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
7287#endif
7288#ifdef _CS_HW_SERIAL
7289 {"CS_HW_SERIAL", _CS_HW_SERIAL},
7290#endif
7291#ifdef _CS_INITTAB_NAME
7292 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
7293#endif
Fred Drakec9680921999-12-13 16:37:25 +00007294#ifdef _CS_LFS64_CFLAGS
7295 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
7296#endif
7297#ifdef _CS_LFS64_LDFLAGS
7298 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
7299#endif
7300#ifdef _CS_LFS64_LIBS
7301 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
7302#endif
7303#ifdef _CS_LFS64_LINTFLAGS
7304 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
7305#endif
7306#ifdef _CS_LFS_CFLAGS
7307 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
7308#endif
7309#ifdef _CS_LFS_LDFLAGS
7310 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
7311#endif
7312#ifdef _CS_LFS_LIBS
7313 {"CS_LFS_LIBS", _CS_LFS_LIBS},
7314#endif
7315#ifdef _CS_LFS_LINTFLAGS
7316 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
7317#endif
Fred Draked86ed291999-12-15 15:34:33 +00007318#ifdef _CS_MACHINE
7319 {"CS_MACHINE", _CS_MACHINE},
7320#endif
Fred Drakec9680921999-12-13 16:37:25 +00007321#ifdef _CS_PATH
7322 {"CS_PATH", _CS_PATH},
7323#endif
Fred Draked86ed291999-12-15 15:34:33 +00007324#ifdef _CS_RELEASE
7325 {"CS_RELEASE", _CS_RELEASE},
7326#endif
7327#ifdef _CS_SRPC_DOMAIN
7328 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
7329#endif
7330#ifdef _CS_SYSNAME
7331 {"CS_SYSNAME", _CS_SYSNAME},
7332#endif
7333#ifdef _CS_VERSION
7334 {"CS_VERSION", _CS_VERSION},
7335#endif
Fred Drakec9680921999-12-13 16:37:25 +00007336#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
7337 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
7338#endif
7339#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
7340 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
7341#endif
7342#ifdef _CS_XBS5_ILP32_OFF32_LIBS
7343 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
7344#endif
7345#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
7346 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
7347#endif
7348#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
7349 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
7350#endif
7351#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
7352 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
7353#endif
7354#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
7355 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
7356#endif
7357#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
7358 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
7359#endif
7360#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7361 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
7362#endif
7363#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7364 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7365#endif
7366#ifdef _CS_XBS5_LP64_OFF64_LIBS
7367 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7368#endif
7369#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7370 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7371#endif
7372#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7373 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7374#endif
7375#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7376 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7377#endif
7378#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7379 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7380#endif
7381#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7382 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7383#endif
Fred Draked86ed291999-12-15 15:34:33 +00007384#ifdef _MIPS_CS_AVAIL_PROCESSORS
7385 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7386#endif
7387#ifdef _MIPS_CS_BASE
7388 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7389#endif
7390#ifdef _MIPS_CS_HOSTID
7391 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7392#endif
7393#ifdef _MIPS_CS_HW_NAME
7394 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7395#endif
7396#ifdef _MIPS_CS_NUM_PROCESSORS
7397 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7398#endif
7399#ifdef _MIPS_CS_OSREL_MAJ
7400 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7401#endif
7402#ifdef _MIPS_CS_OSREL_MIN
7403 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7404#endif
7405#ifdef _MIPS_CS_OSREL_PATCH
7406 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7407#endif
7408#ifdef _MIPS_CS_OS_NAME
7409 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7410#endif
7411#ifdef _MIPS_CS_OS_PROVIDER
7412 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7413#endif
7414#ifdef _MIPS_CS_PROCESSORS
7415 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7416#endif
7417#ifdef _MIPS_CS_SERIAL
7418 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7419#endif
7420#ifdef _MIPS_CS_VENDOR
7421 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7422#endif
Fred Drakec9680921999-12-13 16:37:25 +00007423};
7424
7425static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007426conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007427{
7428 return conv_confname(arg, valuep, posix_constants_confstr,
7429 sizeof(posix_constants_confstr)
7430 / sizeof(struct constdef));
7431}
7432
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007433PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007434"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007435Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007436
7437static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007438posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007439{
7440 PyObject *result = NULL;
7441 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007442 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007443
7444 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Skip Montanarodd527fc2006-04-18 00:49:49 +00007445 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007446
Fred Drakec9680921999-12-13 16:37:25 +00007447 errno = 0;
Skip Montanarodd527fc2006-04-18 00:49:49 +00007448 len = confstr(name, buffer, sizeof(buffer));
Skip Montanaro94785ef2006-04-20 01:29:48 +00007449 if (len == 0) {
7450 if (errno) {
7451 posix_error();
7452 }
7453 else {
7454 result = Py_None;
7455 Py_INCREF(Py_None);
7456 }
Fred Drakec9680921999-12-13 16:37:25 +00007457 }
7458 else {
Neal Norwitz0d21b1e2006-04-20 06:44:42 +00007459 if ((unsigned int)len >= sizeof(buffer)) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007460 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007461 if (result != NULL)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007462 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00007463 }
7464 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007465 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007466 }
7467 }
7468 return result;
7469}
7470#endif
7471
7472
7473#ifdef HAVE_SYSCONF
7474static struct constdef posix_constants_sysconf[] = {
7475#ifdef _SC_2_CHAR_TERM
7476 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7477#endif
7478#ifdef _SC_2_C_BIND
7479 {"SC_2_C_BIND", _SC_2_C_BIND},
7480#endif
7481#ifdef _SC_2_C_DEV
7482 {"SC_2_C_DEV", _SC_2_C_DEV},
7483#endif
7484#ifdef _SC_2_C_VERSION
7485 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7486#endif
7487#ifdef _SC_2_FORT_DEV
7488 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7489#endif
7490#ifdef _SC_2_FORT_RUN
7491 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7492#endif
7493#ifdef _SC_2_LOCALEDEF
7494 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7495#endif
7496#ifdef _SC_2_SW_DEV
7497 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7498#endif
7499#ifdef _SC_2_UPE
7500 {"SC_2_UPE", _SC_2_UPE},
7501#endif
7502#ifdef _SC_2_VERSION
7503 {"SC_2_VERSION", _SC_2_VERSION},
7504#endif
Fred Draked86ed291999-12-15 15:34:33 +00007505#ifdef _SC_ABI_ASYNCHRONOUS_IO
7506 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7507#endif
7508#ifdef _SC_ACL
7509 {"SC_ACL", _SC_ACL},
7510#endif
Fred Drakec9680921999-12-13 16:37:25 +00007511#ifdef _SC_AIO_LISTIO_MAX
7512 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7513#endif
Fred Drakec9680921999-12-13 16:37:25 +00007514#ifdef _SC_AIO_MAX
7515 {"SC_AIO_MAX", _SC_AIO_MAX},
7516#endif
7517#ifdef _SC_AIO_PRIO_DELTA_MAX
7518 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7519#endif
7520#ifdef _SC_ARG_MAX
7521 {"SC_ARG_MAX", _SC_ARG_MAX},
7522#endif
7523#ifdef _SC_ASYNCHRONOUS_IO
7524 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7525#endif
7526#ifdef _SC_ATEXIT_MAX
7527 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7528#endif
Fred Draked86ed291999-12-15 15:34:33 +00007529#ifdef _SC_AUDIT
7530 {"SC_AUDIT", _SC_AUDIT},
7531#endif
Fred Drakec9680921999-12-13 16:37:25 +00007532#ifdef _SC_AVPHYS_PAGES
7533 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7534#endif
7535#ifdef _SC_BC_BASE_MAX
7536 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7537#endif
7538#ifdef _SC_BC_DIM_MAX
7539 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7540#endif
7541#ifdef _SC_BC_SCALE_MAX
7542 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7543#endif
7544#ifdef _SC_BC_STRING_MAX
7545 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7546#endif
Fred Draked86ed291999-12-15 15:34:33 +00007547#ifdef _SC_CAP
7548 {"SC_CAP", _SC_CAP},
7549#endif
Fred Drakec9680921999-12-13 16:37:25 +00007550#ifdef _SC_CHARCLASS_NAME_MAX
7551 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7552#endif
7553#ifdef _SC_CHAR_BIT
7554 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7555#endif
7556#ifdef _SC_CHAR_MAX
7557 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7558#endif
7559#ifdef _SC_CHAR_MIN
7560 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7561#endif
7562#ifdef _SC_CHILD_MAX
7563 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7564#endif
7565#ifdef _SC_CLK_TCK
7566 {"SC_CLK_TCK", _SC_CLK_TCK},
7567#endif
7568#ifdef _SC_COHER_BLKSZ
7569 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7570#endif
7571#ifdef _SC_COLL_WEIGHTS_MAX
7572 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7573#endif
7574#ifdef _SC_DCACHE_ASSOC
7575 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7576#endif
7577#ifdef _SC_DCACHE_BLKSZ
7578 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7579#endif
7580#ifdef _SC_DCACHE_LINESZ
7581 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7582#endif
7583#ifdef _SC_DCACHE_SZ
7584 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7585#endif
7586#ifdef _SC_DCACHE_TBLKSZ
7587 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7588#endif
7589#ifdef _SC_DELAYTIMER_MAX
7590 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7591#endif
7592#ifdef _SC_EQUIV_CLASS_MAX
7593 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7594#endif
7595#ifdef _SC_EXPR_NEST_MAX
7596 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7597#endif
7598#ifdef _SC_FSYNC
7599 {"SC_FSYNC", _SC_FSYNC},
7600#endif
7601#ifdef _SC_GETGR_R_SIZE_MAX
7602 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7603#endif
7604#ifdef _SC_GETPW_R_SIZE_MAX
7605 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7606#endif
7607#ifdef _SC_ICACHE_ASSOC
7608 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7609#endif
7610#ifdef _SC_ICACHE_BLKSZ
7611 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7612#endif
7613#ifdef _SC_ICACHE_LINESZ
7614 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7615#endif
7616#ifdef _SC_ICACHE_SZ
7617 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7618#endif
Fred Draked86ed291999-12-15 15:34:33 +00007619#ifdef _SC_INF
7620 {"SC_INF", _SC_INF},
7621#endif
Fred Drakec9680921999-12-13 16:37:25 +00007622#ifdef _SC_INT_MAX
7623 {"SC_INT_MAX", _SC_INT_MAX},
7624#endif
7625#ifdef _SC_INT_MIN
7626 {"SC_INT_MIN", _SC_INT_MIN},
7627#endif
7628#ifdef _SC_IOV_MAX
7629 {"SC_IOV_MAX", _SC_IOV_MAX},
7630#endif
Fred Draked86ed291999-12-15 15:34:33 +00007631#ifdef _SC_IP_SECOPTS
7632 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7633#endif
Fred Drakec9680921999-12-13 16:37:25 +00007634#ifdef _SC_JOB_CONTROL
7635 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7636#endif
Fred Draked86ed291999-12-15 15:34:33 +00007637#ifdef _SC_KERN_POINTERS
7638 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7639#endif
7640#ifdef _SC_KERN_SIM
7641 {"SC_KERN_SIM", _SC_KERN_SIM},
7642#endif
Fred Drakec9680921999-12-13 16:37:25 +00007643#ifdef _SC_LINE_MAX
7644 {"SC_LINE_MAX", _SC_LINE_MAX},
7645#endif
7646#ifdef _SC_LOGIN_NAME_MAX
7647 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7648#endif
7649#ifdef _SC_LOGNAME_MAX
7650 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7651#endif
7652#ifdef _SC_LONG_BIT
7653 {"SC_LONG_BIT", _SC_LONG_BIT},
7654#endif
Fred Draked86ed291999-12-15 15:34:33 +00007655#ifdef _SC_MAC
7656 {"SC_MAC", _SC_MAC},
7657#endif
Fred Drakec9680921999-12-13 16:37:25 +00007658#ifdef _SC_MAPPED_FILES
7659 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7660#endif
7661#ifdef _SC_MAXPID
7662 {"SC_MAXPID", _SC_MAXPID},
7663#endif
7664#ifdef _SC_MB_LEN_MAX
7665 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7666#endif
7667#ifdef _SC_MEMLOCK
7668 {"SC_MEMLOCK", _SC_MEMLOCK},
7669#endif
7670#ifdef _SC_MEMLOCK_RANGE
7671 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7672#endif
7673#ifdef _SC_MEMORY_PROTECTION
7674 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7675#endif
7676#ifdef _SC_MESSAGE_PASSING
7677 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7678#endif
Fred Draked86ed291999-12-15 15:34:33 +00007679#ifdef _SC_MMAP_FIXED_ALIGNMENT
7680 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7681#endif
Fred Drakec9680921999-12-13 16:37:25 +00007682#ifdef _SC_MQ_OPEN_MAX
7683 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7684#endif
7685#ifdef _SC_MQ_PRIO_MAX
7686 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7687#endif
Fred Draked86ed291999-12-15 15:34:33 +00007688#ifdef _SC_NACLS_MAX
7689 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7690#endif
Fred Drakec9680921999-12-13 16:37:25 +00007691#ifdef _SC_NGROUPS_MAX
7692 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7693#endif
7694#ifdef _SC_NL_ARGMAX
7695 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7696#endif
7697#ifdef _SC_NL_LANGMAX
7698 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7699#endif
7700#ifdef _SC_NL_MSGMAX
7701 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7702#endif
7703#ifdef _SC_NL_NMAX
7704 {"SC_NL_NMAX", _SC_NL_NMAX},
7705#endif
7706#ifdef _SC_NL_SETMAX
7707 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7708#endif
7709#ifdef _SC_NL_TEXTMAX
7710 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7711#endif
7712#ifdef _SC_NPROCESSORS_CONF
7713 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7714#endif
7715#ifdef _SC_NPROCESSORS_ONLN
7716 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7717#endif
Fred Draked86ed291999-12-15 15:34:33 +00007718#ifdef _SC_NPROC_CONF
7719 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7720#endif
7721#ifdef _SC_NPROC_ONLN
7722 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7723#endif
Fred Drakec9680921999-12-13 16:37:25 +00007724#ifdef _SC_NZERO
7725 {"SC_NZERO", _SC_NZERO},
7726#endif
7727#ifdef _SC_OPEN_MAX
7728 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7729#endif
7730#ifdef _SC_PAGESIZE
7731 {"SC_PAGESIZE", _SC_PAGESIZE},
7732#endif
7733#ifdef _SC_PAGE_SIZE
7734 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7735#endif
7736#ifdef _SC_PASS_MAX
7737 {"SC_PASS_MAX", _SC_PASS_MAX},
7738#endif
7739#ifdef _SC_PHYS_PAGES
7740 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7741#endif
7742#ifdef _SC_PII
7743 {"SC_PII", _SC_PII},
7744#endif
7745#ifdef _SC_PII_INTERNET
7746 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7747#endif
7748#ifdef _SC_PII_INTERNET_DGRAM
7749 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7750#endif
7751#ifdef _SC_PII_INTERNET_STREAM
7752 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7753#endif
7754#ifdef _SC_PII_OSI
7755 {"SC_PII_OSI", _SC_PII_OSI},
7756#endif
7757#ifdef _SC_PII_OSI_CLTS
7758 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7759#endif
7760#ifdef _SC_PII_OSI_COTS
7761 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7762#endif
7763#ifdef _SC_PII_OSI_M
7764 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7765#endif
7766#ifdef _SC_PII_SOCKET
7767 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7768#endif
7769#ifdef _SC_PII_XTI
7770 {"SC_PII_XTI", _SC_PII_XTI},
7771#endif
7772#ifdef _SC_POLL
7773 {"SC_POLL", _SC_POLL},
7774#endif
7775#ifdef _SC_PRIORITIZED_IO
7776 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7777#endif
7778#ifdef _SC_PRIORITY_SCHEDULING
7779 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7780#endif
7781#ifdef _SC_REALTIME_SIGNALS
7782 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7783#endif
7784#ifdef _SC_RE_DUP_MAX
7785 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7786#endif
7787#ifdef _SC_RTSIG_MAX
7788 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7789#endif
7790#ifdef _SC_SAVED_IDS
7791 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7792#endif
7793#ifdef _SC_SCHAR_MAX
7794 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7795#endif
7796#ifdef _SC_SCHAR_MIN
7797 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7798#endif
7799#ifdef _SC_SELECT
7800 {"SC_SELECT", _SC_SELECT},
7801#endif
7802#ifdef _SC_SEMAPHORES
7803 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7804#endif
7805#ifdef _SC_SEM_NSEMS_MAX
7806 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7807#endif
7808#ifdef _SC_SEM_VALUE_MAX
7809 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7810#endif
7811#ifdef _SC_SHARED_MEMORY_OBJECTS
7812 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7813#endif
7814#ifdef _SC_SHRT_MAX
7815 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7816#endif
7817#ifdef _SC_SHRT_MIN
7818 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7819#endif
7820#ifdef _SC_SIGQUEUE_MAX
7821 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7822#endif
7823#ifdef _SC_SIGRT_MAX
7824 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7825#endif
7826#ifdef _SC_SIGRT_MIN
7827 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7828#endif
Fred Draked86ed291999-12-15 15:34:33 +00007829#ifdef _SC_SOFTPOWER
7830 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7831#endif
Fred Drakec9680921999-12-13 16:37:25 +00007832#ifdef _SC_SPLIT_CACHE
7833 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7834#endif
7835#ifdef _SC_SSIZE_MAX
7836 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7837#endif
7838#ifdef _SC_STACK_PROT
7839 {"SC_STACK_PROT", _SC_STACK_PROT},
7840#endif
7841#ifdef _SC_STREAM_MAX
7842 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7843#endif
7844#ifdef _SC_SYNCHRONIZED_IO
7845 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7846#endif
7847#ifdef _SC_THREADS
7848 {"SC_THREADS", _SC_THREADS},
7849#endif
7850#ifdef _SC_THREAD_ATTR_STACKADDR
7851 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7852#endif
7853#ifdef _SC_THREAD_ATTR_STACKSIZE
7854 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7855#endif
7856#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7857 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7858#endif
7859#ifdef _SC_THREAD_KEYS_MAX
7860 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7861#endif
7862#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7863 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7864#endif
7865#ifdef _SC_THREAD_PRIO_INHERIT
7866 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7867#endif
7868#ifdef _SC_THREAD_PRIO_PROTECT
7869 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7870#endif
7871#ifdef _SC_THREAD_PROCESS_SHARED
7872 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7873#endif
7874#ifdef _SC_THREAD_SAFE_FUNCTIONS
7875 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7876#endif
7877#ifdef _SC_THREAD_STACK_MIN
7878 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7879#endif
7880#ifdef _SC_THREAD_THREADS_MAX
7881 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7882#endif
7883#ifdef _SC_TIMERS
7884 {"SC_TIMERS", _SC_TIMERS},
7885#endif
7886#ifdef _SC_TIMER_MAX
7887 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7888#endif
7889#ifdef _SC_TTY_NAME_MAX
7890 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7891#endif
7892#ifdef _SC_TZNAME_MAX
7893 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7894#endif
7895#ifdef _SC_T_IOV_MAX
7896 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7897#endif
7898#ifdef _SC_UCHAR_MAX
7899 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7900#endif
7901#ifdef _SC_UINT_MAX
7902 {"SC_UINT_MAX", _SC_UINT_MAX},
7903#endif
7904#ifdef _SC_UIO_MAXIOV
7905 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7906#endif
7907#ifdef _SC_ULONG_MAX
7908 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7909#endif
7910#ifdef _SC_USHRT_MAX
7911 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7912#endif
7913#ifdef _SC_VERSION
7914 {"SC_VERSION", _SC_VERSION},
7915#endif
7916#ifdef _SC_WORD_BIT
7917 {"SC_WORD_BIT", _SC_WORD_BIT},
7918#endif
7919#ifdef _SC_XBS5_ILP32_OFF32
7920 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7921#endif
7922#ifdef _SC_XBS5_ILP32_OFFBIG
7923 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7924#endif
7925#ifdef _SC_XBS5_LP64_OFF64
7926 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7927#endif
7928#ifdef _SC_XBS5_LPBIG_OFFBIG
7929 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7930#endif
7931#ifdef _SC_XOPEN_CRYPT
7932 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7933#endif
7934#ifdef _SC_XOPEN_ENH_I18N
7935 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7936#endif
7937#ifdef _SC_XOPEN_LEGACY
7938 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7939#endif
7940#ifdef _SC_XOPEN_REALTIME
7941 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7942#endif
7943#ifdef _SC_XOPEN_REALTIME_THREADS
7944 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7945#endif
7946#ifdef _SC_XOPEN_SHM
7947 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7948#endif
7949#ifdef _SC_XOPEN_UNIX
7950 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7951#endif
7952#ifdef _SC_XOPEN_VERSION
7953 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7954#endif
7955#ifdef _SC_XOPEN_XCU_VERSION
7956 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7957#endif
7958#ifdef _SC_XOPEN_XPG2
7959 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7960#endif
7961#ifdef _SC_XOPEN_XPG3
7962 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7963#endif
7964#ifdef _SC_XOPEN_XPG4
7965 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7966#endif
7967};
7968
7969static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007970conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007971{
7972 return conv_confname(arg, valuep, posix_constants_sysconf,
7973 sizeof(posix_constants_sysconf)
7974 / sizeof(struct constdef));
7975}
7976
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007977PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007978"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007979Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007980
7981static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007982posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007983{
7984 PyObject *result = NULL;
7985 int name;
7986
7987 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7988 int value;
7989
7990 errno = 0;
7991 value = sysconf(name);
7992 if (value == -1 && errno != 0)
7993 posix_error();
7994 else
7995 result = PyInt_FromLong(value);
7996 }
7997 return result;
7998}
7999#endif
8000
8001
Fred Drakebec628d1999-12-15 18:31:10 +00008002/* This code is used to ensure that the tables of configuration value names
8003 * are in sorted order as required by conv_confname(), and also to build the
8004 * the exported dictionaries that are used to publish information about the
8005 * names available on the host platform.
8006 *
8007 * Sorting the table at runtime ensures that the table is properly ordered
8008 * when used, even for platforms we're not able to test on. It also makes
8009 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008010 */
Fred Drakebec628d1999-12-15 18:31:10 +00008011
8012static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008013cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008014{
8015 const struct constdef *c1 =
8016 (const struct constdef *) v1;
8017 const struct constdef *c2 =
8018 (const struct constdef *) v2;
8019
8020 return strcmp(c1->name, c2->name);
8021}
8022
8023static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008024setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008025 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008026{
Fred Drakebec628d1999-12-15 18:31:10 +00008027 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008028 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008029
8030 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8031 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008032 if (d == NULL)
8033 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008034
Barry Warsaw3155db32000-04-13 15:20:40 +00008035 for (i=0; i < tablesize; ++i) {
8036 PyObject *o = PyInt_FromLong(table[i].value);
8037 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8038 Py_XDECREF(o);
8039 Py_DECREF(d);
8040 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008041 }
Barry Warsaw3155db32000-04-13 15:20:40 +00008042 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008043 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008044 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008045}
8046
Fred Drakebec628d1999-12-15 18:31:10 +00008047/* Return -1 on failure, 0 on success. */
8048static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008049setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008050{
8051#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008052 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008053 sizeof(posix_constants_pathconf)
8054 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008055 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008056 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008057#endif
8058#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008059 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008060 sizeof(posix_constants_confstr)
8061 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008062 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008063 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008064#endif
8065#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008066 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008067 sizeof(posix_constants_sysconf)
8068 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008069 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008070 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008071#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008072 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008073}
Fred Draked86ed291999-12-15 15:34:33 +00008074
8075
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008076PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008077"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008078Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008079in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008080
8081static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008082posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008083{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008084 abort();
8085 /*NOTREACHED*/
8086 Py_FatalError("abort() called from Python code didn't abort!");
8087 return NULL;
8088}
Fred Drakebec628d1999-12-15 18:31:10 +00008089
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008090#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008091PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008092"startfile(filepath [, operation]) - Start a file with its associated\n\
8093application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008094\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008095When \"operation\" is not specified or \"open\", this acts like\n\
8096double-clicking the file in Explorer, or giving the file name as an\n\
8097argument to the DOS \"start\" command: the file is opened with whatever\n\
8098application (if any) its extension is associated.\n\
8099When another \"operation\" is given, it specifies what should be done with\n\
8100the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008101\n\
8102startfile returns as soon as the associated application is launched.\n\
8103There is no option to wait for the application to close, and no way\n\
8104to retrieve the application's exit status.\n\
8105\n\
8106The filepath is relative to the current directory. If you want to use\n\
8107an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008108the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008109
8110static PyObject *
8111win32_startfile(PyObject *self, PyObject *args)
8112{
8113 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00008114 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008115 HINSTANCE rc;
Georg Brandlad89dc82006-04-03 12:26:26 +00008116#ifdef Py_WIN_WIDE_FILENAMES
8117 if (unicode_file_names()) {
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008118 PyObject *unipath, *woperation = NULL;
Georg Brandlad89dc82006-04-03 12:26:26 +00008119 if (!PyArg_ParseTuple(args, "U|s:startfile",
8120 &unipath, &operation)) {
8121 PyErr_Clear();
8122 goto normal;
8123 }
8124
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008125
8126 if (operation) {
8127 woperation = PyUnicode_DecodeASCII(operation,
8128 strlen(operation), NULL);
8129 if (!woperation) {
8130 PyErr_Clear();
8131 operation = NULL;
8132 goto normal;
8133 }
Georg Brandlad89dc82006-04-03 12:26:26 +00008134 }
8135
8136 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008137 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Georg Brandlad89dc82006-04-03 12:26:26 +00008138 PyUnicode_AS_UNICODE(unipath),
Georg Brandlad89dc82006-04-03 12:26:26 +00008139 NULL, NULL, SW_SHOWNORMAL);
8140 Py_END_ALLOW_THREADS
8141
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008142 Py_XDECREF(woperation);
Georg Brandlad89dc82006-04-03 12:26:26 +00008143 if (rc <= (HINSTANCE)32) {
8144 PyObject *errval = win32_error_unicode("startfile",
8145 PyUnicode_AS_UNICODE(unipath));
8146 return errval;
8147 }
8148 Py_INCREF(Py_None);
8149 return Py_None;
8150 }
8151#endif
8152
8153normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00008154 if (!PyArg_ParseTuple(args, "et|s:startfile",
8155 Py_FileSystemDefaultEncoding, &filepath,
8156 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00008157 return NULL;
8158 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00008159 rc = ShellExecute((HWND)0, operation, filepath,
8160 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008161 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00008162 if (rc <= (HINSTANCE)32) {
8163 PyObject *errval = win32_error("startfile", filepath);
8164 PyMem_Free(filepath);
8165 return errval;
8166 }
8167 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008168 Py_INCREF(Py_None);
8169 return Py_None;
8170}
8171#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008172
Martin v. Löwis438b5342002-12-27 10:16:42 +00008173#ifdef HAVE_GETLOADAVG
8174PyDoc_STRVAR(posix_getloadavg__doc__,
8175"getloadavg() -> (float, float, float)\n\n\
8176Return the number of processes in the system run queue averaged over\n\
8177the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8178was unobtainable");
8179
8180static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008181posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008182{
8183 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008184 if (getloadavg(loadavg, 3)!=3) {
8185 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8186 return NULL;
8187 } else
8188 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
8189}
8190#endif
8191
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008192#ifdef MS_WINDOWS
8193
8194PyDoc_STRVAR(win32_urandom__doc__,
8195"urandom(n) -> str\n\n\
8196Return a string of n random bytes suitable for cryptographic use.");
8197
8198typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8199 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8200 DWORD dwFlags );
8201typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8202 BYTE *pbBuffer );
8203
8204static CRYPTGENRANDOM pCryptGenRandom = NULL;
Martin v. Löwisaf699dd2007-09-04 09:51:57 +00008205/* This handle is never explicitly released. Instead, the operating
8206 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008207static HCRYPTPROV hCryptProv = 0;
8208
Tim Peters4ad82172004-08-30 17:02:04 +00008209static PyObject*
8210win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008211{
Tim Petersd3115382004-08-30 17:36:46 +00008212 int howMany;
8213 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008214
Tim Peters4ad82172004-08-30 17:02:04 +00008215 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00008216 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00008217 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00008218 if (howMany < 0)
8219 return PyErr_Format(PyExc_ValueError,
8220 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008221
Tim Peters4ad82172004-08-30 17:02:04 +00008222 if (hCryptProv == 0) {
8223 HINSTANCE hAdvAPI32 = NULL;
8224 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008225
Tim Peters4ad82172004-08-30 17:02:04 +00008226 /* Obtain handle to the DLL containing CryptoAPI
8227 This should not fail */
8228 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8229 if(hAdvAPI32 == NULL)
8230 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008231
Tim Peters4ad82172004-08-30 17:02:04 +00008232 /* Obtain pointers to the CryptoAPI functions
8233 This will fail on some early versions of Win95 */
8234 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8235 hAdvAPI32,
8236 "CryptAcquireContextA");
8237 if (pCryptAcquireContext == NULL)
8238 return PyErr_Format(PyExc_NotImplementedError,
8239 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008240
Tim Peters4ad82172004-08-30 17:02:04 +00008241 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8242 hAdvAPI32, "CryptGenRandom");
Georg Brandl74bb7832006-09-06 06:03:59 +00008243 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00008244 return PyErr_Format(PyExc_NotImplementedError,
8245 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008246
Tim Peters4ad82172004-08-30 17:02:04 +00008247 /* Acquire context */
8248 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8249 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8250 return win32_error("CryptAcquireContext", NULL);
8251 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008252
Tim Peters4ad82172004-08-30 17:02:04 +00008253 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008254 result = PyString_FromStringAndSize(NULL, howMany);
Tim Petersd3115382004-08-30 17:36:46 +00008255 if (result != NULL) {
8256 /* Get random data */
Amaury Forgeot d'Arc74bd40d2008-07-21 21:06:46 +00008257 memset(PyString_AS_STRING(result), 0, howMany); /* zero seed */
Tim Petersd3115382004-08-30 17:36:46 +00008258 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008259 PyString_AS_STRING(result))) {
Tim Petersd3115382004-08-30 17:36:46 +00008260 Py_DECREF(result);
8261 return win32_error("CryptGenRandom", NULL);
8262 }
Tim Peters4ad82172004-08-30 17:02:04 +00008263 }
Tim Petersd3115382004-08-30 17:36:46 +00008264 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008265}
8266#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008267
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008268#ifdef __VMS
8269/* Use openssl random routine */
8270#include <openssl/rand.h>
8271PyDoc_STRVAR(vms_urandom__doc__,
8272"urandom(n) -> str\n\n\
8273Return a string of n random bytes suitable for cryptographic use.");
8274
8275static PyObject*
8276vms_urandom(PyObject *self, PyObject *args)
8277{
8278 int howMany;
8279 PyObject* result;
8280
8281 /* Read arguments */
8282 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8283 return NULL;
8284 if (howMany < 0)
8285 return PyErr_Format(PyExc_ValueError,
8286 "negative argument not allowed");
8287
8288 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008289 result = PyString_FromStringAndSize(NULL, howMany);
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008290 if (result != NULL) {
8291 /* Get random data */
8292 if (RAND_pseudo_bytes((unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008293 PyString_AS_STRING(result),
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008294 howMany) < 0) {
8295 Py_DECREF(result);
8296 return PyErr_Format(PyExc_ValueError,
8297 "RAND_pseudo_bytes");
8298 }
8299 }
8300 return result;
8301}
8302#endif
8303
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008304static PyMethodDef posix_methods[] = {
8305 {"access", posix_access, METH_VARARGS, posix_access__doc__},
8306#ifdef HAVE_TTYNAME
8307 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
8308#endif
8309 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008310#ifdef HAVE_CHFLAGS
8311 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
8312#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008313 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008314#ifdef HAVE_FCHMOD
8315 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
8316#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008317#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008318 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008319#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008320#ifdef HAVE_LCHMOD
8321 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
8322#endif /* HAVE_LCHMOD */
8323#ifdef HAVE_FCHOWN
8324 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
8325#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008326#ifdef HAVE_LCHFLAGS
8327 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
8328#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008329#ifdef HAVE_LCHOWN
8330 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
8331#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008332#ifdef HAVE_CHROOT
8333 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
8334#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008335#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00008336 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008337#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008338#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00008339 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008340#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00008341 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008342#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008343#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008344#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008345 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008346#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008347 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8348 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8349 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008350#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008351 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008352#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008353#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008354 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008355#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008356 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8357 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8358 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008359 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008360#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008361 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008362#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008363#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008364 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008365#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008366 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008367#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00008368 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008369#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008370 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8371 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8372 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008373#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00008374 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008375#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008376 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008377#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008378 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8379 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008380#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008381#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008382 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8383 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008384#if defined(PYOS_OS2)
8385 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8386 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8387#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008388#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008389#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00008390 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008391#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008392#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00008393 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008394#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008395#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00008396 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008397#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008398#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00008399 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008400#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008401#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008402 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008403#endif /* HAVE_GETEGID */
8404#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008405 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008406#endif /* HAVE_GETEUID */
8407#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008408 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008409#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008410#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00008411 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008412#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008413 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008414#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008415 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008416#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008417#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00008418 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008419#endif /* HAVE_GETPPID */
8420#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008421 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008422#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008423#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00008424 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008425#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008426#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008427 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008428#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008429#ifdef HAVE_KILLPG
8430 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8431#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008432#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008433 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008434#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008435#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008436 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008437#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008438 {"popen2", win32_popen2, METH_VARARGS},
8439 {"popen3", win32_popen3, METH_VARARGS},
8440 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00008441 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008442#else
8443#if defined(PYOS_OS2) && defined(PYCC_GCC)
8444 {"popen2", os2emx_popen2, METH_VARARGS},
8445 {"popen3", os2emx_popen3, METH_VARARGS},
8446 {"popen4", os2emx_popen4, METH_VARARGS},
8447#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008448#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008449#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008450#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008451 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008452#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008453#ifdef HAVE_SETEUID
8454 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8455#endif /* HAVE_SETEUID */
8456#ifdef HAVE_SETEGID
8457 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8458#endif /* HAVE_SETEGID */
8459#ifdef HAVE_SETREUID
8460 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8461#endif /* HAVE_SETREUID */
8462#ifdef HAVE_SETREGID
8463 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8464#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008465#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008466 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008467#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008468#ifdef HAVE_SETGROUPS
Georg Brandl96a8c392006-05-29 21:04:52 +00008469 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008470#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008471#ifdef HAVE_GETPGID
8472 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8473#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008474#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008475 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008476#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008477#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00008478 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008479#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008480#ifdef HAVE_WAIT3
8481 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8482#endif /* HAVE_WAIT3 */
8483#ifdef HAVE_WAIT4
8484 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8485#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008486#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008487 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008488#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008489#ifdef HAVE_GETSID
8490 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8491#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008492#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00008493 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008494#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008495#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008496 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008497#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008498#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008499 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008500#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008501#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008502 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008503#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008504 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8505 {"close", posix_close, METH_VARARGS, posix_close__doc__},
Georg Brandl309501a2008-01-19 20:22:13 +00008506 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008507 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8508 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8509 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8510 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8511 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8512 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8513 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00008514 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008515#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00008516 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008517#endif
8518#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008519 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008520#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008521#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008522 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8523#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008524#ifdef HAVE_DEVICE_MACROS
8525 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8526 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8527 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8528#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008529#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008530 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008531#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008532#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008533 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008534#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008535#ifdef HAVE_UNSETENV
8536 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8537#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008538 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008539#ifdef HAVE_FCHDIR
8540 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8541#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008542#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008543 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008544#endif
8545#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008546 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008547#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008548#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008549#ifdef WCOREDUMP
8550 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8551#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008552#ifdef WIFCONTINUED
8553 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8554#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008555#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008556 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008557#endif /* WIFSTOPPED */
8558#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008559 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008560#endif /* WIFSIGNALED */
8561#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008562 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008563#endif /* WIFEXITED */
8564#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008565 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008566#endif /* WEXITSTATUS */
8567#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008568 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008569#endif /* WTERMSIG */
8570#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008571 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008572#endif /* WSTOPSIG */
8573#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008574#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008575 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008576#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008577#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008578 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008579#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008580#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00008581 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008582#endif
8583#ifdef HAVE_TEMPNAM
8584 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8585#endif
8586#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00008587 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008588#endif
Fred Drakec9680921999-12-13 16:37:25 +00008589#ifdef HAVE_CONFSTR
8590 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8591#endif
8592#ifdef HAVE_SYSCONF
8593 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8594#endif
8595#ifdef HAVE_FPATHCONF
8596 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8597#endif
8598#ifdef HAVE_PATHCONF
8599 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8600#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008601 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008602#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00008603 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8604#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008605#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00008606 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008607#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008608 #ifdef MS_WINDOWS
8609 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8610 #endif
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008611 #ifdef __VMS
8612 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8613 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008614 {NULL, NULL} /* Sentinel */
8615};
8616
8617
Barry Warsaw4a342091996-12-19 23:50:02 +00008618static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008619ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008620{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008621 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008622}
8623
Guido van Rossumd48f2521997-12-05 22:19:34 +00008624#if defined(PYOS_OS2)
8625/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008626static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008627{
8628 APIRET rc;
8629 ULONG values[QSV_MAX+1];
8630 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008631 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008632
8633 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008634 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008635 Py_END_ALLOW_THREADS
8636
8637 if (rc != NO_ERROR) {
8638 os2_error(rc);
8639 return -1;
8640 }
8641
Fred Drake4d1e64b2002-04-15 19:40:07 +00008642 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8643 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8644 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8645 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8646 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8647 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8648 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008649
8650 switch (values[QSV_VERSION_MINOR]) {
8651 case 0: ver = "2.00"; break;
8652 case 10: ver = "2.10"; break;
8653 case 11: ver = "2.11"; break;
8654 case 30: ver = "3.00"; break;
8655 case 40: ver = "4.00"; break;
8656 case 50: ver = "5.00"; break;
8657 default:
Tim Peters885d4572001-11-28 20:27:42 +00008658 PyOS_snprintf(tmp, sizeof(tmp),
8659 "%d-%d", values[QSV_VERSION_MAJOR],
8660 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008661 ver = &tmp[0];
8662 }
8663
8664 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008665 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008666 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008667
8668 /* Add Indicator of Which Drive was Used to Boot the System */
8669 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8670 tmp[1] = ':';
8671 tmp[2] = '\0';
8672
Fred Drake4d1e64b2002-04-15 19:40:07 +00008673 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008674}
8675#endif
8676
Barry Warsaw4a342091996-12-19 23:50:02 +00008677static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008678all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008679{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008680#ifdef F_OK
8681 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008682#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008683#ifdef R_OK
8684 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008685#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008686#ifdef W_OK
8687 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008688#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008689#ifdef X_OK
8690 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008691#endif
Fred Drakec9680921999-12-13 16:37:25 +00008692#ifdef NGROUPS_MAX
8693 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8694#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008695#ifdef TMP_MAX
8696 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8697#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008698#ifdef WCONTINUED
8699 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8700#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008701#ifdef WNOHANG
8702 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008703#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008704#ifdef WUNTRACED
8705 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8706#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008707#ifdef O_RDONLY
8708 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8709#endif
8710#ifdef O_WRONLY
8711 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8712#endif
8713#ifdef O_RDWR
8714 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8715#endif
8716#ifdef O_NDELAY
8717 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8718#endif
8719#ifdef O_NONBLOCK
8720 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8721#endif
8722#ifdef O_APPEND
8723 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8724#endif
8725#ifdef O_DSYNC
8726 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8727#endif
8728#ifdef O_RSYNC
8729 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8730#endif
8731#ifdef O_SYNC
8732 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8733#endif
8734#ifdef O_NOCTTY
8735 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8736#endif
8737#ifdef O_CREAT
8738 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8739#endif
8740#ifdef O_EXCL
8741 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8742#endif
8743#ifdef O_TRUNC
8744 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8745#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008746#ifdef O_BINARY
8747 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8748#endif
8749#ifdef O_TEXT
8750 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8751#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008752#ifdef O_LARGEFILE
8753 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8754#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008755#ifdef O_SHLOCK
8756 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8757#endif
8758#ifdef O_EXLOCK
8759 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8760#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008761
Tim Peters5aa91602002-01-30 05:46:57 +00008762/* MS Windows */
8763#ifdef O_NOINHERIT
8764 /* Don't inherit in child processes. */
8765 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8766#endif
8767#ifdef _O_SHORT_LIVED
8768 /* Optimize for short life (keep in memory). */
8769 /* MS forgot to define this one with a non-underscore form too. */
8770 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8771#endif
8772#ifdef O_TEMPORARY
8773 /* Automatically delete when last handle is closed. */
8774 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8775#endif
8776#ifdef O_RANDOM
8777 /* Optimize for random access. */
8778 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8779#endif
8780#ifdef O_SEQUENTIAL
8781 /* Optimize for sequential access. */
8782 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8783#endif
8784
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008785/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00008786#ifdef O_ASYNC
8787 /* Send a SIGIO signal whenever input or output
8788 becomes available on file descriptor */
8789 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
8790#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008791#ifdef O_DIRECT
8792 /* Direct disk access. */
8793 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8794#endif
8795#ifdef O_DIRECTORY
8796 /* Must be a directory. */
8797 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8798#endif
8799#ifdef O_NOFOLLOW
8800 /* Do not follow links. */
8801 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8802#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00008803#ifdef O_NOATIME
8804 /* Do not update the access time. */
8805 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
8806#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008807
Barry Warsaw5676bd12003-01-07 20:57:09 +00008808 /* These come from sysexits.h */
8809#ifdef EX_OK
8810 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008811#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008812#ifdef EX_USAGE
8813 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008814#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008815#ifdef EX_DATAERR
8816 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008817#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008818#ifdef EX_NOINPUT
8819 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008820#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008821#ifdef EX_NOUSER
8822 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008823#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008824#ifdef EX_NOHOST
8825 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008826#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008827#ifdef EX_UNAVAILABLE
8828 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008829#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008830#ifdef EX_SOFTWARE
8831 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008832#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008833#ifdef EX_OSERR
8834 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008835#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008836#ifdef EX_OSFILE
8837 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008838#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008839#ifdef EX_CANTCREAT
8840 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008841#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008842#ifdef EX_IOERR
8843 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008844#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008845#ifdef EX_TEMPFAIL
8846 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008847#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008848#ifdef EX_PROTOCOL
8849 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008850#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008851#ifdef EX_NOPERM
8852 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008853#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008854#ifdef EX_CONFIG
8855 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008856#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008857#ifdef EX_NOTFOUND
8858 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008859#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008860
Guido van Rossum246bc171999-02-01 23:54:31 +00008861#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008862#if defined(PYOS_OS2) && defined(PYCC_GCC)
8863 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8864 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8865 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8866 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8867 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8868 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8869 if (ins(d, "P_PM", (long)P_PM)) return -1;
8870 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8871 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8872 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8873 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8874 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8875 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8876 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8877 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8878 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8879 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8880 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8881 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8882 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8883#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008884 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8885 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8886 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8887 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8888 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008889#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008890#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008891
Guido van Rossumd48f2521997-12-05 22:19:34 +00008892#if defined(PYOS_OS2)
8893 if (insertvalues(d)) return -1;
8894#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008895 return 0;
8896}
8897
8898
Tim Peters5aa91602002-01-30 05:46:57 +00008899#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008900#define INITFUNC initnt
8901#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008902
8903#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008904#define INITFUNC initos2
8905#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008906
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008907#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008908#define INITFUNC initposix
8909#define MODNAME "posix"
8910#endif
8911
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008912PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008913INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008914{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008915 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008916
Fred Drake4d1e64b2002-04-15 19:40:07 +00008917 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008918 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008919 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008920 if (m == NULL)
8921 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008922
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008923 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008924 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008925 Py_XINCREF(v);
8926 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008927 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008928 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008929
Fred Drake4d1e64b2002-04-15 19:40:07 +00008930 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008931 return;
8932
Fred Drake4d1e64b2002-04-15 19:40:07 +00008933 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008934 return;
8935
Fred Drake4d1e64b2002-04-15 19:40:07 +00008936 Py_INCREF(PyExc_OSError);
8937 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008938
Guido van Rossumb3d39562000-01-31 18:41:26 +00008939#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008940 if (posix_putenv_garbage == NULL)
8941 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008942#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008943
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00008944 if (!initialized) {
8945 stat_result_desc.name = MODNAME ".stat_result";
8946 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8947 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8948 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8949 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8950 structseq_new = StatResultType.tp_new;
8951 StatResultType.tp_new = statresult_new;
8952
8953 statvfs_result_desc.name = MODNAME ".statvfs_result";
8954 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
8955 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008956 Py_INCREF((PyObject*) &StatResultType);
8957 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008958 Py_INCREF((PyObject*) &StatVFSResultType);
8959 PyModule_AddObject(m, "statvfs_result",
8960 (PyObject*) &StatVFSResultType);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00008961 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00008962
8963#ifdef __APPLE__
8964 /*
8965 * Step 2 of weak-linking support on Mac OS X.
8966 *
8967 * The code below removes functions that are not available on the
8968 * currently active platform.
8969 *
8970 * This block allow one to use a python binary that was build on
8971 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8972 * OSX 10.4.
8973 */
8974#ifdef HAVE_FSTATVFS
8975 if (fstatvfs == NULL) {
8976 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8977 return;
8978 }
8979 }
8980#endif /* HAVE_FSTATVFS */
8981
8982#ifdef HAVE_STATVFS
8983 if (statvfs == NULL) {
8984 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8985 return;
8986 }
8987 }
8988#endif /* HAVE_STATVFS */
8989
8990# ifdef HAVE_LCHOWN
8991 if (lchown == NULL) {
8992 if (PyObject_DelAttrString(m, "lchown") == -1) {
8993 return;
8994 }
8995 }
8996#endif /* HAVE_LCHOWN */
8997
8998
8999#endif /* __APPLE__ */
9000
Guido van Rossumb6775db1994-08-01 11:34:53 +00009001}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009002
9003#ifdef __cplusplus
9004}
9005#endif
9006
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009007