blob: 39387a92be1ccfd751360b44e132a5bd3b7db212 [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
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000477static int
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000478convert_to_unicode(PyObject **param)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000479{
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000480 if (PyUnicode_CheckExact(*param))
481 Py_INCREF(*param);
482 else if (PyUnicode_Check(*param))
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000483 /* For a Unicode subtype that's not a Unicode object,
484 return a true Unicode object with the same data. */
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000485 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
486 PyUnicode_GET_SIZE(*param));
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000487 else
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000488 *param = PyUnicode_FromEncodedObject(*param,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000489 Py_FileSystemDefaultEncoding,
490 "strict");
491 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000492}
493
494#endif /* Py_WIN_WIDE_FILENAMES */
495
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000496#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000497
Guido van Rossumd48f2521997-12-05 22:19:34 +0000498#if defined(PYOS_OS2)
499/**********************************************************************
500 * Helper Function to Trim and Format OS/2 Messages
501 **********************************************************************/
502 static void
503os2_formatmsg(char *msgbuf, int msglen, char *reason)
504{
505 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
506
507 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
508 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
509
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000510 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000511 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
512 }
513
514 /* Add Optional Reason Text */
515 if (reason) {
516 strcat(msgbuf, " : ");
517 strcat(msgbuf, reason);
518 }
519}
520
521/**********************************************************************
522 * Decode an OS/2 Operating System Error Code
523 *
524 * A convenience function to lookup an OS/2 error code and return a
525 * text message we can use to raise a Python exception.
526 *
527 * Notes:
528 * The messages for errors returned from the OS/2 kernel reside in
529 * the file OSO001.MSG in the \OS2 directory hierarchy.
530 *
531 **********************************************************************/
532 static char *
533os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
534{
535 APIRET rc;
536 ULONG msglen;
537
538 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
539 Py_BEGIN_ALLOW_THREADS
540 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
541 errorcode, "oso001.msg", &msglen);
542 Py_END_ALLOW_THREADS
543
544 if (rc == NO_ERROR)
545 os2_formatmsg(msgbuf, msglen, reason);
546 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000547 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000548 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000549
550 return msgbuf;
551}
552
553/* Set an OS/2-specific error and return NULL. OS/2 kernel
554 errors are not in a global variable e.g. 'errno' nor are
555 they congruent with posix error numbers. */
556
557static PyObject * os2_error(int code)
558{
559 char text[1024];
560 PyObject *v;
561
562 os2_strerror(text, sizeof(text), code, "");
563
564 v = Py_BuildValue("(is)", code, text);
565 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000566 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000567 Py_DECREF(v);
568 }
569 return NULL; /* Signal to Python that an Exception is Pending */
570}
571
572#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000573
574/* POSIX generic methods */
575
Barry Warsaw53699e91996-12-10 23:23:01 +0000576static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000577posix_fildes(PyObject *fdobj, int (*func)(int))
578{
579 int fd;
580 int res;
581 fd = PyObject_AsFileDescriptor(fdobj);
582 if (fd < 0)
583 return NULL;
584 Py_BEGIN_ALLOW_THREADS
585 res = (*func)(fd);
586 Py_END_ALLOW_THREADS
587 if (res < 0)
588 return posix_error();
589 Py_INCREF(Py_None);
590 return Py_None;
591}
Guido van Rossum21142a01999-01-08 21:05:37 +0000592
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000593#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000594static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000595unicode_file_names(void)
596{
597 static int canusewide = -1;
598 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000599 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000600 the Windows NT family. */
601 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
602 }
603 return canusewide;
604}
605#endif
Tim Peters11b23062003-04-23 02:39:17 +0000606
Guido van Rossum21142a01999-01-08 21:05:37 +0000607static PyObject *
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000608posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000609{
Mark Hammondef8b6542001-05-13 08:04:26 +0000610 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000611 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000612 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000613 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000614 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000615 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000616 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000617 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000618 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000619 return posix_error_with_allocated_filename(path1);
620 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000621 Py_INCREF(Py_None);
622 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000623}
624
Barry Warsaw53699e91996-12-10 23:23:01 +0000625static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000626posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000627 char *format,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000628 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000629{
Mark Hammondef8b6542001-05-13 08:04:26 +0000630 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000631 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000632 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000633 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000634 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000635 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000636 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000637 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000638 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000639 PyMem_Free(path1);
640 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000641 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000642 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000643 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000644 Py_INCREF(Py_None);
645 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000646}
647
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000648#ifdef Py_WIN_WIDE_FILENAMES
649static PyObject*
650win32_1str(PyObject* args, char* func,
651 char* format, BOOL (__stdcall *funcA)(LPCSTR),
652 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
653{
654 PyObject *uni;
655 char *ansi;
656 BOOL result;
657 if (unicode_file_names()) {
658 if (!PyArg_ParseTuple(args, wformat, &uni))
659 PyErr_Clear();
660 else {
661 Py_BEGIN_ALLOW_THREADS
662 result = funcW(PyUnicode_AsUnicode(uni));
663 Py_END_ALLOW_THREADS
664 if (!result)
665 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
666 Py_INCREF(Py_None);
667 return Py_None;
668 }
669 }
670 if (!PyArg_ParseTuple(args, format, &ansi))
671 return NULL;
672 Py_BEGIN_ALLOW_THREADS
673 result = funcA(ansi);
674 Py_END_ALLOW_THREADS
675 if (!result)
676 return win32_error(func, ansi);
677 Py_INCREF(Py_None);
678 return Py_None;
679
680}
681
682/* This is a reimplementation of the C library's chdir function,
683 but one that produces Win32 errors instead of DOS error codes.
684 chdir is essentially a wrapper around SetCurrentDirectory; however,
685 it also needs to set "magic" environment variables indicating
686 the per-drive current directory, which are of the form =<drive>: */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000687static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000688win32_chdir(LPCSTR path)
689{
690 char new_path[MAX_PATH+1];
691 int result;
692 char env[4] = "=x:";
693
694 if(!SetCurrentDirectoryA(path))
695 return FALSE;
696 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
697 if (!result)
698 return FALSE;
699 /* In the ANSI API, there should not be any paths longer
700 than MAX_PATH. */
701 assert(result <= MAX_PATH+1);
702 if (strncmp(new_path, "\\\\", 2) == 0 ||
703 strncmp(new_path, "//", 2) == 0)
704 /* UNC path, nothing to do. */
705 return TRUE;
706 env[1] = new_path[0];
707 return SetEnvironmentVariableA(env, new_path);
708}
709
710/* The Unicode version differs from the ANSI version
711 since the current directory might exceed MAX_PATH characters */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000712static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000713win32_wchdir(LPCWSTR path)
714{
715 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
716 int result;
717 wchar_t env[4] = L"=x:";
718
719 if(!SetCurrentDirectoryW(path))
720 return FALSE;
721 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
722 if (!result)
723 return FALSE;
724 if (result > MAX_PATH+1) {
Hirokazu Yamamoto10a018c2008-10-09 10:00:30 +0000725 new_path = malloc(result * sizeof(wchar_t));
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000726 if (!new_path) {
727 SetLastError(ERROR_OUTOFMEMORY);
728 return FALSE;
729 }
Hirokazu Yamamoto10a018c2008-10-09 10:00:30 +0000730 result = GetCurrentDirectoryW(result, new_path);
Hirokazu Yamamoto6c75a302008-10-09 10:11:21 +0000731 if (!result) {
732 free(new_path);
Hirokazu Yamamoto10a018c2008-10-09 10:00:30 +0000733 return FALSE;
Hirokazu Yamamoto6c75a302008-10-09 10:11:21 +0000734 }
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000735 }
736 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
737 wcsncmp(new_path, L"//", 2) == 0)
738 /* UNC path, nothing to do. */
739 return TRUE;
740 env[1] = new_path[0];
741 result = SetEnvironmentVariableW(env, new_path);
742 if (new_path != _new_path)
743 free(new_path);
744 return result;
745}
746#endif
747
Martin v. Löwis14694662006-02-03 12:54:16 +0000748#ifdef MS_WINDOWS
749/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
750 - time stamps are restricted to second resolution
751 - file modification times suffer from forth-and-back conversions between
752 UTC and local time
753 Therefore, we implement our own stat, based on the Win32 API directly.
754*/
755#define HAVE_STAT_NSEC 1
756
757struct win32_stat{
758 int st_dev;
759 __int64 st_ino;
760 unsigned short st_mode;
761 int st_nlink;
762 int st_uid;
763 int st_gid;
764 int st_rdev;
765 __int64 st_size;
766 int st_atime;
767 int st_atime_nsec;
768 int st_mtime;
769 int st_mtime_nsec;
770 int st_ctime;
771 int st_ctime_nsec;
772};
773
774static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
775
776static void
777FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
778{
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000779 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
780 /* Cannot simply cast and dereference in_ptr,
781 since it might not be aligned properly */
782 __int64 in;
783 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000784 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
785 /* XXX Win32 supports time stamps past 2038; we currently don't */
786 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
787}
788
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000789static void
790time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
791{
792 /* XXX endianness */
793 __int64 out;
794 out = time_in + secs_between_epochs;
Martin v. Löwisf43893a2006-10-09 20:44:25 +0000795 out = out * 10000000 + nsec_in / 100;
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000796 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000797}
798
Martin v. Löwis14694662006-02-03 12:54:16 +0000799/* Below, we *know* that ugo+r is 0444 */
800#if _S_IREAD != 0400
801#error Unsupported C library
802#endif
803static int
804attributes_to_mode(DWORD attr)
805{
806 int m = 0;
807 if (attr & FILE_ATTRIBUTE_DIRECTORY)
808 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
809 else
810 m |= _S_IFREG;
811 if (attr & FILE_ATTRIBUTE_READONLY)
812 m |= 0444;
813 else
814 m |= 0666;
815 return m;
816}
817
818static int
819attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
820{
821 memset(result, 0, sizeof(*result));
822 result->st_mode = attributes_to_mode(info->dwFileAttributes);
823 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
824 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
825 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
826 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
827
828 return 0;
829}
830
Martin v. Löwis012bc722006-10-15 09:43:39 +0000831/* Emulate GetFileAttributesEx[AW] on Windows 95 */
832static int checked = 0;
833static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
834static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
835static void
836check_gfax()
837{
838 HINSTANCE hKernel32;
839 if (checked)
840 return;
841 checked = 1;
842 hKernel32 = GetModuleHandle("KERNEL32");
843 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
844 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
845}
846
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000847static BOOL
848attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
849{
850 HANDLE hFindFile;
851 WIN32_FIND_DATAA FileData;
852 hFindFile = FindFirstFileA(pszFile, &FileData);
853 if (hFindFile == INVALID_HANDLE_VALUE)
854 return FALSE;
855 FindClose(hFindFile);
856 pfad->dwFileAttributes = FileData.dwFileAttributes;
857 pfad->ftCreationTime = FileData.ftCreationTime;
858 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
859 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
860 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
861 pfad->nFileSizeLow = FileData.nFileSizeLow;
862 return TRUE;
863}
864
865static BOOL
866attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
867{
868 HANDLE hFindFile;
869 WIN32_FIND_DATAW FileData;
870 hFindFile = FindFirstFileW(pszFile, &FileData);
871 if (hFindFile == INVALID_HANDLE_VALUE)
872 return FALSE;
873 FindClose(hFindFile);
874 pfad->dwFileAttributes = FileData.dwFileAttributes;
875 pfad->ftCreationTime = FileData.ftCreationTime;
876 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
877 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
878 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
879 pfad->nFileSizeLow = FileData.nFileSizeLow;
880 return TRUE;
881}
882
Martin v. Löwis012bc722006-10-15 09:43:39 +0000883static BOOL WINAPI
884Py_GetFileAttributesExA(LPCSTR pszFile,
885 GET_FILEEX_INFO_LEVELS level,
886 LPVOID pv)
887{
888 BOOL result;
Martin v. Löwis012bc722006-10-15 09:43:39 +0000889 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
890 /* First try to use the system's implementation, if that is
891 available and either succeeds to gives an error other than
892 that it isn't implemented. */
893 check_gfax();
894 if (gfaxa) {
895 result = gfaxa(pszFile, level, pv);
896 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
897 return result;
898 }
899 /* It's either not present, or not implemented.
900 Emulate using FindFirstFile. */
901 if (level != GetFileExInfoStandard) {
902 SetLastError(ERROR_INVALID_PARAMETER);
903 return FALSE;
904 }
905 /* Use GetFileAttributes to validate that the file name
906 does not contain wildcards (which FindFirstFile would
907 accept). */
908 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
909 return FALSE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000910 return attributes_from_dir(pszFile, pfad);
Martin v. Löwis012bc722006-10-15 09:43:39 +0000911}
912
913static BOOL WINAPI
914Py_GetFileAttributesExW(LPCWSTR pszFile,
915 GET_FILEEX_INFO_LEVELS level,
916 LPVOID pv)
917{
918 BOOL result;
Martin v. Löwis012bc722006-10-15 09:43:39 +0000919 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
920 /* First try to use the system's implementation, if that is
921 available and either succeeds to gives an error other than
922 that it isn't implemented. */
923 check_gfax();
924 if (gfaxa) {
925 result = gfaxw(pszFile, level, pv);
926 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
927 return result;
928 }
929 /* It's either not present, or not implemented.
930 Emulate using FindFirstFile. */
931 if (level != GetFileExInfoStandard) {
932 SetLastError(ERROR_INVALID_PARAMETER);
933 return FALSE;
934 }
935 /* Use GetFileAttributes to validate that the file name
936 does not contain wildcards (which FindFirstFile would
937 accept). */
938 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
939 return FALSE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000940 return attributes_from_dir_w(pszFile, pfad);
Martin v. Löwis012bc722006-10-15 09:43:39 +0000941}
942
Martin v. Löwis14694662006-02-03 12:54:16 +0000943static int
944win32_stat(const char* path, struct win32_stat *result)
945{
946 WIN32_FILE_ATTRIBUTE_DATA info;
947 int code;
948 char *dot;
949 /* XXX not supported on Win95 and NT 3.x */
Martin v. Löwis012bc722006-10-15 09:43:39 +0000950 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000951 if (GetLastError() != ERROR_SHARING_VIOLATION) {
952 /* Protocol violation: we explicitly clear errno, instead of
953 setting it to a POSIX error. Callers should use GetLastError. */
954 errno = 0;
955 return -1;
956 } else {
957 /* Could not get attributes on open file. Fall back to
958 reading the directory. */
959 if (!attributes_from_dir(path, &info)) {
960 /* Very strange. This should not fail now */
961 errno = 0;
962 return -1;
963 }
964 }
Martin v. Löwis14694662006-02-03 12:54:16 +0000965 }
966 code = attribute_data_to_stat(&info, result);
967 if (code != 0)
968 return code;
969 /* Set S_IFEXEC if it is an .exe, .bat, ... */
970 dot = strrchr(path, '.');
971 if (dot) {
972 if (stricmp(dot, ".bat") == 0 ||
973 stricmp(dot, ".cmd") == 0 ||
974 stricmp(dot, ".exe") == 0 ||
975 stricmp(dot, ".com") == 0)
976 result->st_mode |= 0111;
977 }
978 return code;
979}
980
981static int
982win32_wstat(const wchar_t* path, struct win32_stat *result)
983{
984 int code;
985 const wchar_t *dot;
986 WIN32_FILE_ATTRIBUTE_DATA info;
987 /* XXX not supported on Win95 and NT 3.x */
Martin v. Löwis012bc722006-10-15 09:43:39 +0000988 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000989 if (GetLastError() != ERROR_SHARING_VIOLATION) {
990 /* Protocol violation: we explicitly clear errno, instead of
991 setting it to a POSIX error. Callers should use GetLastError. */
992 errno = 0;
993 return -1;
994 } else {
995 /* Could not get attributes on open file. Fall back to
996 reading the directory. */
997 if (!attributes_from_dir_w(path, &info)) {
998 /* Very strange. This should not fail now */
999 errno = 0;
1000 return -1;
1001 }
1002 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001003 }
1004 code = attribute_data_to_stat(&info, result);
1005 if (code < 0)
1006 return code;
1007 /* Set IFEXEC if it is an .exe, .bat, ... */
1008 dot = wcsrchr(path, '.');
1009 if (dot) {
1010 if (_wcsicmp(dot, L".bat") == 0 ||
1011 _wcsicmp(dot, L".cmd") == 0 ||
1012 _wcsicmp(dot, L".exe") == 0 ||
1013 _wcsicmp(dot, L".com") == 0)
1014 result->st_mode |= 0111;
1015 }
1016 return code;
1017}
1018
1019static int
1020win32_fstat(int file_number, struct win32_stat *result)
1021{
1022 BY_HANDLE_FILE_INFORMATION info;
1023 HANDLE h;
1024 int type;
1025
1026 h = (HANDLE)_get_osfhandle(file_number);
1027
1028 /* Protocol violation: we explicitly clear errno, instead of
1029 setting it to a POSIX error. Callers should use GetLastError. */
1030 errno = 0;
1031
1032 if (h == INVALID_HANDLE_VALUE) {
1033 /* This is really a C library error (invalid file handle).
1034 We set the Win32 error to the closes one matching. */
1035 SetLastError(ERROR_INVALID_HANDLE);
1036 return -1;
1037 }
1038 memset(result, 0, sizeof(*result));
1039
1040 type = GetFileType(h);
1041 if (type == FILE_TYPE_UNKNOWN) {
1042 DWORD error = GetLastError();
1043 if (error != 0) {
1044 return -1;
1045 }
1046 /* else: valid but unknown file */
1047 }
1048
1049 if (type != FILE_TYPE_DISK) {
1050 if (type == FILE_TYPE_CHAR)
1051 result->st_mode = _S_IFCHR;
1052 else if (type == FILE_TYPE_PIPE)
1053 result->st_mode = _S_IFIFO;
1054 return 0;
1055 }
1056
1057 if (!GetFileInformationByHandle(h, &info)) {
1058 return -1;
1059 }
1060
1061 /* similar to stat() */
1062 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1063 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1064 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1065 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1066 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1067 /* specific to fstat() */
1068 result->st_nlink = info.nNumberOfLinks;
1069 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1070 return 0;
1071}
1072
1073#endif /* MS_WINDOWS */
1074
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001075PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001076"stat_result: Result from stat or lstat.\n\n\
1077This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001078 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001079or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1080\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001081Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1082or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001083\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001084See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001085
1086static PyStructSequence_Field stat_result_fields[] = {
1087 {"st_mode", "protection bits"},
1088 {"st_ino", "inode"},
1089 {"st_dev", "device"},
1090 {"st_nlink", "number of hard links"},
1091 {"st_uid", "user ID of owner"},
1092 {"st_gid", "group ID of owner"},
1093 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001094 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1095 {NULL, "integer time of last access"},
1096 {NULL, "integer time of last modification"},
1097 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001098 {"st_atime", "time of last access"},
1099 {"st_mtime", "time of last modification"},
1100 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001101#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001102 {"st_blksize", "blocksize for filesystem I/O"},
1103#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001104#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001105 {"st_blocks", "number of blocks allocated"},
1106#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001107#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001108 {"st_rdev", "device type (if inode device)"},
1109#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001110#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1111 {"st_flags", "user defined flags for file"},
1112#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001113#ifdef HAVE_STRUCT_STAT_ST_GEN
1114 {"st_gen", "generation number"},
1115#endif
1116#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1117 {"st_birthtime", "time of creation"},
1118#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001119 {0}
1120};
1121
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001122#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001123#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001124#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001125#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001126#endif
1127
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001128#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001129#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1130#else
1131#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1132#endif
1133
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001134#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001135#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1136#else
1137#define ST_RDEV_IDX ST_BLOCKS_IDX
1138#endif
1139
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001140#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1141#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1142#else
1143#define ST_FLAGS_IDX ST_RDEV_IDX
1144#endif
1145
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001146#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001147#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001148#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001149#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001150#endif
1151
1152#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1153#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1154#else
1155#define ST_BIRTHTIME_IDX ST_GEN_IDX
1156#endif
1157
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001158static PyStructSequence_Desc stat_result_desc = {
1159 "stat_result", /* name */
1160 stat_result__doc__, /* doc */
1161 stat_result_fields,
1162 10
1163};
1164
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001165PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001166"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1167This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001168 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001169or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001170\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001171See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001172
1173static PyStructSequence_Field statvfs_result_fields[] = {
1174 {"f_bsize", },
1175 {"f_frsize", },
1176 {"f_blocks", },
1177 {"f_bfree", },
1178 {"f_bavail", },
1179 {"f_files", },
1180 {"f_ffree", },
1181 {"f_favail", },
1182 {"f_flag", },
1183 {"f_namemax",},
1184 {0}
1185};
1186
1187static PyStructSequence_Desc statvfs_result_desc = {
1188 "statvfs_result", /* name */
1189 statvfs_result__doc__, /* doc */
1190 statvfs_result_fields,
1191 10
1192};
1193
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001194static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001195static PyTypeObject StatResultType;
1196static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001197static newfunc structseq_new;
1198
1199static PyObject *
1200statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1201{
1202 PyStructSequence *result;
1203 int i;
1204
1205 result = (PyStructSequence*)structseq_new(type, args, kwds);
1206 if (!result)
1207 return NULL;
1208 /* If we have been initialized from a tuple,
1209 st_?time might be set to None. Initialize it
1210 from the int slots. */
1211 for (i = 7; i <= 9; i++) {
1212 if (result->ob_item[i+3] == Py_None) {
1213 Py_DECREF(Py_None);
1214 Py_INCREF(result->ob_item[i]);
1215 result->ob_item[i+3] = result->ob_item[i];
1216 }
1217 }
1218 return (PyObject*)result;
1219}
1220
1221
1222
1223/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001224static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001225
1226PyDoc_STRVAR(stat_float_times__doc__,
1227"stat_float_times([newval]) -> oldval\n\n\
1228Determine whether os.[lf]stat represents time stamps as float objects.\n\
1229If newval is True, future calls to stat() return floats, if it is False,\n\
1230future calls return ints. \n\
1231If newval is omitted, return the current setting.\n");
1232
1233static PyObject*
1234stat_float_times(PyObject* self, PyObject *args)
1235{
1236 int newval = -1;
1237 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1238 return NULL;
1239 if (newval == -1)
1240 /* Return old value */
1241 return PyBool_FromLong(_stat_float_times);
1242 _stat_float_times = newval;
1243 Py_INCREF(Py_None);
1244 return Py_None;
1245}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001246
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001247static void
1248fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1249{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001250 PyObject *fval,*ival;
1251#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001252 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001253#else
1254 ival = PyInt_FromLong((long)sec);
1255#endif
Neal Norwitze0a81af2006-08-12 01:50:38 +00001256 if (!ival)
1257 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001258 if (_stat_float_times) {
1259 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1260 } else {
1261 fval = ival;
1262 Py_INCREF(fval);
1263 }
1264 PyStructSequence_SET_ITEM(v, index, ival);
1265 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001266}
1267
Tim Peters5aa91602002-01-30 05:46:57 +00001268/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001269 (used by posix_stat() and posix_fstat()) */
1270static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001271_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001272{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001273 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001274 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001275 if (v == NULL)
1276 return NULL;
1277
Martin v. Löwis14694662006-02-03 12:54:16 +00001278 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001279#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001280 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001281 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001282#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001283 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001284#endif
1285#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001286 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001287 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001288#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001289 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001290#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001291 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1292 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1293 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001294#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001295 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001296 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001297#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001298 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001299#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001300
Martin v. Löwis14694662006-02-03 12:54:16 +00001301#if defined(HAVE_STAT_TV_NSEC)
1302 ansec = st->st_atim.tv_nsec;
1303 mnsec = st->st_mtim.tv_nsec;
1304 cnsec = st->st_ctim.tv_nsec;
1305#elif defined(HAVE_STAT_TV_NSEC2)
1306 ansec = st->st_atimespec.tv_nsec;
1307 mnsec = st->st_mtimespec.tv_nsec;
1308 cnsec = st->st_ctimespec.tv_nsec;
1309#elif defined(HAVE_STAT_NSEC)
1310 ansec = st->st_atime_nsec;
1311 mnsec = st->st_mtime_nsec;
1312 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001313#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001314 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001315#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001316 fill_time(v, 7, st->st_atime, ansec);
1317 fill_time(v, 8, st->st_mtime, mnsec);
1318 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001319
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001320#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001321 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001322 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001323#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001324#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001325 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001326 PyInt_FromLong((long)st->st_blocks));
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_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001329 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001330 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001331#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001332#ifdef HAVE_STRUCT_STAT_ST_GEN
1333 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001334 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001335#endif
1336#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1337 {
1338 PyObject *val;
1339 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001340 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001341#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001342 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001343#else
1344 bnsec = 0;
1345#endif
1346 if (_stat_float_times) {
1347 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1348 } else {
1349 val = PyInt_FromLong((long)bsec);
1350 }
1351 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1352 val);
1353 }
1354#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001355#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1356 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001357 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001358#endif
Fred Drake699f3522000-06-29 21:12:41 +00001359
1360 if (PyErr_Occurred()) {
1361 Py_DECREF(v);
1362 return NULL;
1363 }
1364
1365 return v;
1366}
1367
Martin v. Löwisd8948722004-06-02 09:57:56 +00001368#ifdef MS_WINDOWS
1369
1370/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1371 where / can be used in place of \ and the trailing slash is optional.
1372 Both SERVER and SHARE must have at least one character.
1373*/
1374
1375#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1376#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001377#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001378#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001379#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001380
Tim Peters4ad82172004-08-30 17:02:04 +00001381static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001382IsUNCRootA(char *path, int pathlen)
1383{
1384 #define ISSLASH ISSLASHA
1385
1386 int i, share;
1387
1388 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1389 /* minimum UNCRoot is \\x\y */
1390 return FALSE;
1391 for (i = 2; i < pathlen ; i++)
1392 if (ISSLASH(path[i])) break;
1393 if (i == 2 || i == pathlen)
1394 /* do not allow \\\SHARE or \\SERVER */
1395 return FALSE;
1396 share = i+1;
1397 for (i = share; i < pathlen; i++)
1398 if (ISSLASH(path[i])) break;
1399 return (i != share && (i == pathlen || i == pathlen-1));
1400
1401 #undef ISSLASH
1402}
1403
1404#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001405static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001406IsUNCRootW(Py_UNICODE *path, int pathlen)
1407{
1408 #define ISSLASH ISSLASHW
1409
1410 int i, share;
1411
1412 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1413 /* minimum UNCRoot is \\x\y */
1414 return FALSE;
1415 for (i = 2; i < pathlen ; i++)
1416 if (ISSLASH(path[i])) break;
1417 if (i == 2 || i == pathlen)
1418 /* do not allow \\\SHARE or \\SERVER */
1419 return FALSE;
1420 share = i+1;
1421 for (i = share; i < pathlen; i++)
1422 if (ISSLASH(path[i])) break;
1423 return (i != share && (i == pathlen || i == pathlen-1));
1424
1425 #undef ISSLASH
1426}
1427#endif /* Py_WIN_WIDE_FILENAMES */
1428#endif /* MS_WINDOWS */
1429
Barry Warsaw53699e91996-12-10 23:23:01 +00001430static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001431posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001432 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001433#ifdef __VMS
1434 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1435#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001436 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001437#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001438 char *wformat,
1439 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001440{
Fred Drake699f3522000-06-29 21:12:41 +00001441 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001442 char *path = NULL; /* pass this to stat; do not free() it */
1443 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001444 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001445 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001446
1447#ifdef Py_WIN_WIDE_FILENAMES
1448 /* If on wide-character-capable OS see if argument
1449 is Unicode and if so use wide API. */
1450 if (unicode_file_names()) {
1451 PyUnicodeObject *po;
1452 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001453 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1454
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001455 Py_BEGIN_ALLOW_THREADS
1456 /* PyUnicode_AS_UNICODE result OK without
1457 thread lock as it is a simple dereference. */
1458 res = wstatfunc(wpath, &st);
1459 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001460
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001461 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001462 return win32_error_unicode("stat", wpath);
1463 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001464 }
1465 /* Drop the argument parsing error as narrow strings
1466 are also valid. */
1467 PyErr_Clear();
1468 }
1469#endif
1470
Tim Peters5aa91602002-01-30 05:46:57 +00001471 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001472 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001473 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001474 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001475
Barry Warsaw53699e91996-12-10 23:23:01 +00001476 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001477 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001478 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001479
1480 if (res != 0) {
1481#ifdef MS_WINDOWS
1482 result = win32_error("stat", pathfree);
1483#else
1484 result = posix_error_with_filename(pathfree);
1485#endif
1486 }
1487 else
1488 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001489
Tim Peters500bd032001-12-19 19:05:01 +00001490 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001491 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001492}
1493
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001494/* POSIX methods */
1495
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001496PyDoc_STRVAR(posix_access__doc__,
Georg Brandl7a284472007-01-27 19:38:50 +00001497"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001498Use the real uid/gid to test for access to a path. Note that most\n\
1499operations will use the effective uid/gid, therefore this routine can\n\
1500be used in a suid/sgid environment to test if the invoking user has the\n\
1501specified access to the path. The mode argument can be F_OK to test\n\
1502existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001503
1504static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001505posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001506{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001507 char *path;
1508 int mode;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001509
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001510#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001511 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001512 if (unicode_file_names()) {
1513 PyUnicodeObject *po;
1514 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1515 Py_BEGIN_ALLOW_THREADS
1516 /* PyUnicode_AS_UNICODE OK without thread lock as
1517 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001518 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001519 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001520 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001521 }
1522 /* Drop the argument parsing error as narrow strings
1523 are also valid. */
1524 PyErr_Clear();
1525 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001526 if (!PyArg_ParseTuple(args, "eti:access",
1527 Py_FileSystemDefaultEncoding, &path, &mode))
1528 return 0;
1529 Py_BEGIN_ALLOW_THREADS
1530 attr = GetFileAttributesA(path);
1531 Py_END_ALLOW_THREADS
1532 PyMem_Free(path);
1533finish:
1534 if (attr == 0xFFFFFFFF)
1535 /* File does not exist, or cannot read attributes */
1536 return PyBool_FromLong(0);
1537 /* Access is possible if either write access wasn't requested, or
Martin v. Löwis7b3cc062007-12-03 23:09:04 +00001538 the file isn't read-only, or if it's a directory, as there are
1539 no read-only directories on Windows. */
1540 return PyBool_FromLong(!(mode & 2)
1541 || !(attr & FILE_ATTRIBUTE_READONLY)
1542 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001543#else
1544 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001545 if (!PyArg_ParseTuple(args, "eti:access",
1546 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001547 return NULL;
1548 Py_BEGIN_ALLOW_THREADS
1549 res = access(path, mode);
1550 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001551 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001552 return PyBool_FromLong(res == 0);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001553#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001554}
1555
Guido van Rossumd371ff11999-01-25 16:12:23 +00001556#ifndef F_OK
1557#define F_OK 0
1558#endif
1559#ifndef R_OK
1560#define R_OK 4
1561#endif
1562#ifndef W_OK
1563#define W_OK 2
1564#endif
1565#ifndef X_OK
1566#define X_OK 1
1567#endif
1568
1569#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001570PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001571"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001572Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001573
1574static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001575posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001576{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001577 int id;
1578 char *ret;
1579
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001580 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001581 return NULL;
1582
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001583#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001584 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001585 if (id == 0) {
1586 ret = ttyname();
1587 }
1588 else {
1589 ret = NULL;
1590 }
1591#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001592 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001593#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001594 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001595 return posix_error();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001596 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001597}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001598#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001599
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001600#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001601PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001602"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001603Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001604
1605static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001606posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001607{
1608 char *ret;
1609 char buffer[L_ctermid];
1610
Greg Wardb48bc172000-03-01 21:51:56 +00001611#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001612 ret = ctermid_r(buffer);
1613#else
1614 ret = ctermid(buffer);
1615#endif
1616 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001617 return posix_error();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001618 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001619}
1620#endif
1621
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001622PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001623"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001624Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001625
Barry Warsaw53699e91996-12-10 23:23:01 +00001626static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001627posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001628{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001629#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001630 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001631#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001632 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001633#elif defined(__VMS)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001634 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001635#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001636 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001637#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001638}
1639
Fred Drake4d1e64b2002-04-15 19:40:07 +00001640#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001641PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001642"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001643Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001644opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001645
1646static PyObject *
1647posix_fchdir(PyObject *self, PyObject *fdobj)
1648{
1649 return posix_fildes(fdobj, fchdir);
1650}
1651#endif /* HAVE_FCHDIR */
1652
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001653
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001654PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001655"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001656Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001657
Barry Warsaw53699e91996-12-10 23:23:01 +00001658static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001659posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001660{
Mark Hammondef8b6542001-05-13 08:04:26 +00001661 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001662 int i;
1663 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001664#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001665 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001666 if (unicode_file_names()) {
1667 PyUnicodeObject *po;
1668 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1669 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001670 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1671 if (attr != 0xFFFFFFFF) {
1672 if (i & _S_IWRITE)
1673 attr &= ~FILE_ATTRIBUTE_READONLY;
1674 else
1675 attr |= FILE_ATTRIBUTE_READONLY;
1676 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1677 }
1678 else
1679 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001680 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001681 if (!res)
1682 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001683 PyUnicode_AS_UNICODE(po));
1684 Py_INCREF(Py_None);
1685 return Py_None;
1686 }
1687 /* Drop the argument parsing error as narrow strings
1688 are also valid. */
1689 PyErr_Clear();
1690 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001691 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1692 &path, &i))
1693 return NULL;
1694 Py_BEGIN_ALLOW_THREADS
1695 attr = GetFileAttributesA(path);
1696 if (attr != 0xFFFFFFFF) {
1697 if (i & _S_IWRITE)
1698 attr &= ~FILE_ATTRIBUTE_READONLY;
1699 else
1700 attr |= FILE_ATTRIBUTE_READONLY;
1701 res = SetFileAttributesA(path, attr);
1702 }
1703 else
1704 res = 0;
1705 Py_END_ALLOW_THREADS
1706 if (!res) {
1707 win32_error("chmod", path);
1708 PyMem_Free(path);
1709 return NULL;
1710 }
Martin v. Löwis9f485bc2006-05-08 05:25:56 +00001711 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001712 Py_INCREF(Py_None);
1713 return Py_None;
1714#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001715 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001716 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001717 return NULL;
1718 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001719 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001720 Py_END_ALLOW_THREADS
1721 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001722 return posix_error_with_allocated_filename(path);
1723 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001724 Py_INCREF(Py_None);
1725 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001726#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001727}
1728
Christian Heimes36281872007-11-30 21:11:28 +00001729#ifdef HAVE_FCHMOD
1730PyDoc_STRVAR(posix_fchmod__doc__,
1731"fchmod(fd, mode)\n\n\
1732Change the access permissions of the file given by file\n\
1733descriptor fd.");
1734
1735static PyObject *
1736posix_fchmod(PyObject *self, PyObject *args)
1737{
1738 int fd, mode, res;
1739 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1740 return NULL;
1741 Py_BEGIN_ALLOW_THREADS
1742 res = fchmod(fd, mode);
1743 Py_END_ALLOW_THREADS
1744 if (res < 0)
1745 return posix_error();
1746 Py_RETURN_NONE;
1747}
1748#endif /* HAVE_FCHMOD */
1749
1750#ifdef HAVE_LCHMOD
1751PyDoc_STRVAR(posix_lchmod__doc__,
1752"lchmod(path, mode)\n\n\
1753Change the access permissions of a file. If path is a symlink, this\n\
1754affects the link itself rather than the target.");
1755
1756static PyObject *
1757posix_lchmod(PyObject *self, PyObject *args)
1758{
1759 char *path = NULL;
1760 int i;
1761 int res;
1762 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1763 &path, &i))
1764 return NULL;
1765 Py_BEGIN_ALLOW_THREADS
1766 res = lchmod(path, i);
1767 Py_END_ALLOW_THREADS
1768 if (res < 0)
1769 return posix_error_with_allocated_filename(path);
1770 PyMem_Free(path);
1771 Py_RETURN_NONE;
1772}
1773#endif /* HAVE_LCHMOD */
1774
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001775
Martin v. Löwis382abef2007-02-19 10:55:19 +00001776#ifdef HAVE_CHFLAGS
1777PyDoc_STRVAR(posix_chflags__doc__,
1778"chflags(path, flags)\n\n\
1779Set file flags.");
1780
1781static PyObject *
1782posix_chflags(PyObject *self, PyObject *args)
1783{
1784 char *path;
1785 unsigned long flags;
1786 int res;
1787 if (!PyArg_ParseTuple(args, "etk:chflags",
1788 Py_FileSystemDefaultEncoding, &path, &flags))
1789 return NULL;
1790 Py_BEGIN_ALLOW_THREADS
1791 res = chflags(path, flags);
1792 Py_END_ALLOW_THREADS
1793 if (res < 0)
1794 return posix_error_with_allocated_filename(path);
1795 PyMem_Free(path);
1796 Py_INCREF(Py_None);
1797 return Py_None;
1798}
1799#endif /* HAVE_CHFLAGS */
1800
1801#ifdef HAVE_LCHFLAGS
1802PyDoc_STRVAR(posix_lchflags__doc__,
1803"lchflags(path, flags)\n\n\
1804Set file flags.\n\
1805This function will not follow symbolic links.");
1806
1807static PyObject *
1808posix_lchflags(PyObject *self, PyObject *args)
1809{
1810 char *path;
1811 unsigned long flags;
1812 int res;
1813 if (!PyArg_ParseTuple(args, "etk:lchflags",
1814 Py_FileSystemDefaultEncoding, &path, &flags))
1815 return NULL;
1816 Py_BEGIN_ALLOW_THREADS
1817 res = lchflags(path, flags);
1818 Py_END_ALLOW_THREADS
1819 if (res < 0)
1820 return posix_error_with_allocated_filename(path);
1821 PyMem_Free(path);
1822 Py_INCREF(Py_None);
1823 return Py_None;
1824}
1825#endif /* HAVE_LCHFLAGS */
1826
Martin v. Löwis244edc82001-10-04 22:44:26 +00001827#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001828PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001829"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001830Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001831
1832static PyObject *
1833posix_chroot(PyObject *self, PyObject *args)
1834{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001835 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001836}
1837#endif
1838
Guido van Rossum21142a01999-01-08 21:05:37 +00001839#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001840PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001841"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001842force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001843
1844static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001845posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001846{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001847 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001848}
1849#endif /* HAVE_FSYNC */
1850
1851#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001852
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001853#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001854extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1855#endif
1856
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001857PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001858"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001859force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001860 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001861
1862static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001863posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001864{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001865 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001866}
1867#endif /* HAVE_FDATASYNC */
1868
1869
Fredrik Lundh10723342000-07-10 16:38:09 +00001870#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001871PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001872"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001873Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001874
Barry Warsaw53699e91996-12-10 23:23:01 +00001875static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001876posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001877{
Mark Hammondef8b6542001-05-13 08:04:26 +00001878 char *path = NULL;
Gregory P. Smithf48da8f2008-03-18 19:05:32 +00001879 long uid, gid;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001880 int res;
Gregory P. Smithf48da8f2008-03-18 19:05:32 +00001881 if (!PyArg_ParseTuple(args, "etll:chown",
Tim Peters5aa91602002-01-30 05:46:57 +00001882 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001883 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001884 return NULL;
1885 Py_BEGIN_ALLOW_THREADS
1886 res = chown(path, (uid_t) uid, (gid_t) gid);
1887 Py_END_ALLOW_THREADS
1888 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001889 return posix_error_with_allocated_filename(path);
1890 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001891 Py_INCREF(Py_None);
1892 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001893}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001894#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001895
Christian Heimes36281872007-11-30 21:11:28 +00001896#ifdef HAVE_FCHOWN
1897PyDoc_STRVAR(posix_fchown__doc__,
1898"fchown(fd, uid, gid)\n\n\
1899Change the owner and group id of the file given by file descriptor\n\
1900fd to the numeric uid and gid.");
1901
1902static PyObject *
1903posix_fchown(PyObject *self, PyObject *args)
1904{
1905 int fd, uid, gid;
1906 int res;
1907 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
1908 return NULL;
1909 Py_BEGIN_ALLOW_THREADS
1910 res = fchown(fd, (uid_t) uid, (gid_t) gid);
1911 Py_END_ALLOW_THREADS
1912 if (res < 0)
1913 return posix_error();
1914 Py_RETURN_NONE;
1915}
1916#endif /* HAVE_FCHOWN */
1917
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001918#ifdef HAVE_LCHOWN
1919PyDoc_STRVAR(posix_lchown__doc__,
1920"lchown(path, uid, gid)\n\n\
1921Change the owner and group id of path to the numeric uid and gid.\n\
1922This function will not follow symbolic links.");
1923
1924static PyObject *
1925posix_lchown(PyObject *self, PyObject *args)
1926{
1927 char *path = NULL;
1928 int uid, gid;
1929 int res;
1930 if (!PyArg_ParseTuple(args, "etii:lchown",
1931 Py_FileSystemDefaultEncoding, &path,
1932 &uid, &gid))
1933 return NULL;
1934 Py_BEGIN_ALLOW_THREADS
1935 res = lchown(path, (uid_t) uid, (gid_t) gid);
1936 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001937 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001938 return posix_error_with_allocated_filename(path);
1939 PyMem_Free(path);
1940 Py_INCREF(Py_None);
1941 return Py_None;
1942}
1943#endif /* HAVE_LCHOWN */
1944
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001945
Guido van Rossum36bc6801995-06-14 22:54:23 +00001946#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001947PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001948"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001949Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001950
Barry Warsaw53699e91996-12-10 23:23:01 +00001951static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001952posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001953{
Facundo Batista5596b0c2008-06-22 13:36:20 +00001954 int bufsize_incr = 1024;
1955 int bufsize = 0;
1956 char *tmpbuf = NULL;
1957 char *res = NULL;
1958 PyObject *dynamic_return;
Neal Norwitze241ce82003-02-17 18:17:05 +00001959
Barry Warsaw53699e91996-12-10 23:23:01 +00001960 Py_BEGIN_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00001961 do {
1962 bufsize = bufsize + bufsize_incr;
1963 tmpbuf = malloc(bufsize);
1964 if (tmpbuf == NULL) {
1965 break;
1966 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001967#if defined(PYOS_OS2) && defined(PYCC_GCC)
Facundo Batista5596b0c2008-06-22 13:36:20 +00001968 res = _getcwd2(tmpbuf, bufsize);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001969#else
Facundo Batista5596b0c2008-06-22 13:36:20 +00001970 res = getcwd(tmpbuf, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001971#endif
Facundo Batista5596b0c2008-06-22 13:36:20 +00001972
1973 if (res == NULL) {
1974 free(tmpbuf);
1975 }
1976 } while ((res == NULL) && (errno == ERANGE));
Barry Warsaw53699e91996-12-10 23:23:01 +00001977 Py_END_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00001978
Guido van Rossumff4949e1992-08-05 19:58:53 +00001979 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001980 return posix_error();
Facundo Batista5596b0c2008-06-22 13:36:20 +00001981
1982 dynamic_return = PyString_FromString(tmpbuf);
1983 free(tmpbuf);
1984
1985 return dynamic_return;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001986}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001987
Walter Dörwald3b918c32002-11-21 20:18:46 +00001988#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001989PyDoc_STRVAR(posix_getcwdu__doc__,
1990"getcwdu() -> path\n\n\
1991Return a unicode string representing the current working directory.");
1992
1993static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001994posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001995{
1996 char buf[1026];
1997 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001998
1999#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002000 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002001 if (unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002002 wchar_t wbuf[1026];
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002003 wchar_t *wbuf2 = wbuf;
2004 PyObject *resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002005 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002006 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2007 /* If the buffer is large enough, len does not include the
2008 terminating \0. If the buffer is too small, len includes
2009 the space needed for the terminator. */
2010 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2011 wbuf2 = malloc(len * sizeof(wchar_t));
2012 if (wbuf2)
2013 len = GetCurrentDirectoryW(len, wbuf2);
2014 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002015 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002016 if (!wbuf2) {
2017 PyErr_NoMemory();
2018 return NULL;
2019 }
2020 if (!len) {
2021 if (wbuf2 != wbuf) free(wbuf2);
2022 return win32_error("getcwdu", NULL);
2023 }
2024 resobj = PyUnicode_FromWideChar(wbuf2, len);
2025 if (wbuf2 != wbuf) free(wbuf2);
2026 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002027 }
2028#endif
2029
2030 Py_BEGIN_ALLOW_THREADS
2031#if defined(PYOS_OS2) && defined(PYCC_GCC)
2032 res = _getcwd2(buf, sizeof buf);
2033#else
2034 res = getcwd(buf, sizeof buf);
2035#endif
2036 Py_END_ALLOW_THREADS
2037 if (res == NULL)
2038 return posix_error();
2039 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
2040}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002041#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00002042#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002043
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002044
Guido van Rossumb6775db1994-08-01 11:34:53 +00002045#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002046PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002047"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002048Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002049
Barry Warsaw53699e91996-12-10 23:23:01 +00002050static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002051posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002052{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002053 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002054}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002055#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002056
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002057
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002058PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002059"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002060Return a list containing the names of the entries in the directory.\n\
2061\n\
2062 path: path of directory to list\n\
2063\n\
2064The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002065entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002066
Barry Warsaw53699e91996-12-10 23:23:01 +00002067static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002068posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002069{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002070 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002071 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002072#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002073
Barry Warsaw53699e91996-12-10 23:23:01 +00002074 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002075 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002076 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002077 WIN32_FIND_DATA FileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002078 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00002079 char *bufptr = namebuf;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002080 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002081
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002082#ifdef Py_WIN_WIDE_FILENAMES
2083 /* If on wide-character-capable OS see if argument
2084 is Unicode and if so use wide API. */
2085 if (unicode_file_names()) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002086 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002087 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2088 WIN32_FIND_DATAW wFileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002089 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002090 Py_UNICODE wch;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002091 /* Overallocate for \\*.*\0 */
2092 len = PyUnicode_GET_SIZE(po);
2093 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2094 if (!wnamebuf) {
2095 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002096 return NULL;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002097 }
2098 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2099 wch = len > 0 ? wnamebuf[len-1] : '\0';
2100 if (wch != L'/' && wch != L'\\' && wch != L':')
2101 wnamebuf[len++] = L'\\';
2102 wcscpy(wnamebuf + len, L"*.*");
2103 if ((d = PyList_New(0)) == NULL) {
2104 free(wnamebuf);
2105 return NULL;
2106 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002107 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2108 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002109 int error = GetLastError();
2110 if (error == ERROR_FILE_NOT_FOUND) {
2111 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002112 return d;
2113 }
2114 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002115 win32_error_unicode("FindFirstFileW", wnamebuf);
2116 free(wnamebuf);
2117 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002118 }
2119 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002120 /* Skip over . and .. */
2121 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2122 wcscmp(wFileData.cFileName, L"..") != 0) {
2123 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2124 if (v == NULL) {
2125 Py_DECREF(d);
2126 d = NULL;
2127 break;
2128 }
2129 if (PyList_Append(d, v) != 0) {
2130 Py_DECREF(v);
2131 Py_DECREF(d);
2132 d = NULL;
2133 break;
2134 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002135 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002136 }
Georg Brandl622927b2006-03-07 12:48:03 +00002137 Py_BEGIN_ALLOW_THREADS
2138 result = FindNextFileW(hFindFile, &wFileData);
2139 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00002140 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2141 it got to the end of the directory. */
2142 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2143 Py_DECREF(d);
2144 win32_error_unicode("FindNextFileW", wnamebuf);
2145 FindClose(hFindFile);
2146 free(wnamebuf);
2147 return NULL;
2148 }
Georg Brandl622927b2006-03-07 12:48:03 +00002149 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002150
2151 if (FindClose(hFindFile) == FALSE) {
2152 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002153 win32_error_unicode("FindClose", wnamebuf);
2154 free(wnamebuf);
2155 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002156 }
Martin v. Löwise3edaea2006-05-15 05:51:36 +00002157 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002158 return d;
2159 }
2160 /* Drop the argument parsing error as narrow strings
2161 are also valid. */
2162 PyErr_Clear();
2163 }
2164#endif
2165
Tim Peters5aa91602002-01-30 05:46:57 +00002166 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002167 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002168 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002169 if (len > 0) {
2170 char ch = namebuf[len-1];
2171 if (ch != SEP && ch != ALTSEP && ch != ':')
2172 namebuf[len++] = '/';
2173 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002174 strcpy(namebuf + len, "*.*");
2175
Barry Warsaw53699e91996-12-10 23:23:01 +00002176 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002177 return NULL;
2178
2179 hFindFile = FindFirstFile(namebuf, &FileData);
2180 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002181 int error = GetLastError();
2182 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002183 return d;
2184 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002185 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002186 }
2187 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002188 /* Skip over . and .. */
2189 if (strcmp(FileData.cFileName, ".") != 0 &&
2190 strcmp(FileData.cFileName, "..") != 0) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002191 v = PyString_FromString(FileData.cFileName);
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002192 if (v == NULL) {
2193 Py_DECREF(d);
2194 d = NULL;
2195 break;
2196 }
2197 if (PyList_Append(d, v) != 0) {
2198 Py_DECREF(v);
2199 Py_DECREF(d);
2200 d = NULL;
2201 break;
2202 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002203 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002204 }
Georg Brandl622927b2006-03-07 12:48:03 +00002205 Py_BEGIN_ALLOW_THREADS
2206 result = FindNextFile(hFindFile, &FileData);
2207 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00002208 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2209 it got to the end of the directory. */
2210 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2211 Py_DECREF(d);
2212 win32_error("FindNextFile", namebuf);
2213 FindClose(hFindFile);
2214 return NULL;
2215 }
Georg Brandl622927b2006-03-07 12:48:03 +00002216 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002217
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002218 if (FindClose(hFindFile) == FALSE) {
2219 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002220 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002221 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002222
2223 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002224
Tim Peters0bb44a42000-09-15 07:44:49 +00002225#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002226
2227#ifndef MAX_PATH
2228#define MAX_PATH CCHMAXPATH
2229#endif
2230 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002231 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002232 PyObject *d, *v;
2233 char namebuf[MAX_PATH+5];
2234 HDIR hdir = 1;
2235 ULONG srchcnt = 1;
2236 FILEFINDBUF3 ep;
2237 APIRET rc;
2238
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002239 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002240 return NULL;
2241 if (len >= MAX_PATH) {
2242 PyErr_SetString(PyExc_ValueError, "path too long");
2243 return NULL;
2244 }
2245 strcpy(namebuf, name);
2246 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002247 if (*pt == ALTSEP)
2248 *pt = SEP;
2249 if (namebuf[len-1] != SEP)
2250 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002251 strcpy(namebuf + len, "*.*");
2252
2253 if ((d = PyList_New(0)) == NULL)
2254 return NULL;
2255
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002256 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2257 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002258 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002259 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2260 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2261 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002262
2263 if (rc != NO_ERROR) {
2264 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002265 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002266 }
2267
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002268 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002269 do {
2270 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002271 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002272 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002273
2274 strcpy(namebuf, ep.achName);
2275
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002276 /* Leave Case of Name Alone -- In Native Form */
2277 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002278
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002279 v = PyString_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002280 if (v == NULL) {
2281 Py_DECREF(d);
2282 d = NULL;
2283 break;
2284 }
2285 if (PyList_Append(d, v) != 0) {
2286 Py_DECREF(v);
2287 Py_DECREF(d);
2288 d = NULL;
2289 break;
2290 }
2291 Py_DECREF(v);
2292 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2293 }
2294
2295 return d;
2296#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002297
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002298 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002299 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002300 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002301 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002302 int arg_is_unicode = 1;
2303
Georg Brandl05e89b82006-04-11 07:04:06 +00002304 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002305 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2306 arg_is_unicode = 0;
2307 PyErr_Clear();
2308 }
2309 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002310 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002311 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002312 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002313 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002314 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002315 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002316 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002317 return NULL;
2318 }
Georg Brandl622927b2006-03-07 12:48:03 +00002319 for (;;) {
Georg Brandl86cbf812008-07-16 21:31:41 +00002320 errno = 0;
Georg Brandl622927b2006-03-07 12:48:03 +00002321 Py_BEGIN_ALLOW_THREADS
2322 ep = readdir(dirp);
2323 Py_END_ALLOW_THREADS
Georg Brandl86cbf812008-07-16 21:31:41 +00002324 if (ep == NULL) {
2325 if (errno == 0) {
2326 break;
2327 } else {
2328 closedir(dirp);
2329 Py_DECREF(d);
2330 return posix_error_with_allocated_filename(name);
2331 }
2332 }
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002333 if (ep->d_name[0] == '.' &&
2334 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002335 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002336 continue;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002337 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002338 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002339 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002340 d = NULL;
2341 break;
2342 }
Just van Rossum46c97842003-02-25 21:42:15 +00002343#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00002344 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002345 PyObject *w;
2346
2347 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002348 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002349 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002350 if (w != NULL) {
2351 Py_DECREF(v);
2352 v = w;
2353 }
2354 else {
2355 /* fall back to the original byte string, as
2356 discussed in patch #683592 */
2357 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002358 }
Just van Rossum46c97842003-02-25 21:42:15 +00002359 }
2360#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002361 if (PyList_Append(d, v) != 0) {
2362 Py_DECREF(v);
2363 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002364 d = NULL;
2365 break;
2366 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002367 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002368 }
2369 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002370 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002371
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002372 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002373
Tim Peters0bb44a42000-09-15 07:44:49 +00002374#endif /* which OS */
2375} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002376
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002377#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002378/* A helper function for abspath on win32 */
2379static PyObject *
2380posix__getfullpathname(PyObject *self, PyObject *args)
2381{
2382 /* assume encoded strings wont more than double no of chars */
2383 char inbuf[MAX_PATH*2];
2384 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002385 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002386 char outbuf[MAX_PATH*2];
2387 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002388#ifdef Py_WIN_WIDE_FILENAMES
2389 if (unicode_file_names()) {
2390 PyUnicodeObject *po;
2391 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2392 Py_UNICODE woutbuf[MAX_PATH*2];
2393 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00002394 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002395 sizeof(woutbuf)/sizeof(woutbuf[0]),
2396 woutbuf, &wtemp))
2397 return win32_error("GetFullPathName", "");
2398 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
2399 }
2400 /* Drop the argument parsing error as narrow strings
2401 are also valid. */
2402 PyErr_Clear();
2403 }
2404#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002405 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2406 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002407 &insize))
2408 return NULL;
2409 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2410 outbuf, &temp))
2411 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002412 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2413 return PyUnicode_Decode(outbuf, strlen(outbuf),
2414 Py_FileSystemDefaultEncoding, NULL);
2415 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002416 return PyString_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002417} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002418#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002419
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002420PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002421"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002422Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002423
Barry Warsaw53699e91996-12-10 23:23:01 +00002424static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002425posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002426{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002427 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002428 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002429 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002430
2431#ifdef Py_WIN_WIDE_FILENAMES
2432 if (unicode_file_names()) {
2433 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002434 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002435 Py_BEGIN_ALLOW_THREADS
2436 /* PyUnicode_AS_UNICODE OK without thread lock as
2437 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002438 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002439 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002440 if (!res)
2441 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002442 Py_INCREF(Py_None);
2443 return Py_None;
2444 }
2445 /* Drop the argument parsing error as narrow strings
2446 are also valid. */
2447 PyErr_Clear();
2448 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002449 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2450 Py_FileSystemDefaultEncoding, &path, &mode))
2451 return NULL;
2452 Py_BEGIN_ALLOW_THREADS
2453 /* PyUnicode_AS_UNICODE OK without thread lock as
2454 it is a simple dereference. */
2455 res = CreateDirectoryA(path, NULL);
2456 Py_END_ALLOW_THREADS
2457 if (!res) {
2458 win32_error("mkdir", path);
2459 PyMem_Free(path);
2460 return NULL;
2461 }
2462 PyMem_Free(path);
2463 Py_INCREF(Py_None);
2464 return Py_None;
2465#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002466
Tim Peters5aa91602002-01-30 05:46:57 +00002467 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002468 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002469 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002470 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002471#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002472 res = mkdir(path);
2473#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002474 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002475#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002476 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002477 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002478 return posix_error_with_allocated_filename(path);
2479 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002480 Py_INCREF(Py_None);
2481 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002482#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002483}
2484
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002485
Neal Norwitz1818ed72006-03-26 00:29:48 +00002486/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2487#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002488#include <sys/resource.h>
2489#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002490
Neal Norwitz1818ed72006-03-26 00:29:48 +00002491
2492#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002493PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002494"nice(inc) -> new_priority\n\n\
2495Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002496
Barry Warsaw53699e91996-12-10 23:23:01 +00002497static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002498posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002499{
2500 int increment, value;
2501
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002502 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002503 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002504
2505 /* There are two flavours of 'nice': one that returns the new
2506 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002507 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2508 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002509
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002510 If we are of the nice family that returns the new priority, we
2511 need to clear errno before the call, and check if errno is filled
2512 before calling posix_error() on a returnvalue of -1, because the
2513 -1 may be the actual new priority! */
2514
2515 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002516 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002517#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002518 if (value == 0)
2519 value = getpriority(PRIO_PROCESS, 0);
2520#endif
2521 if (value == -1 && errno != 0)
2522 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002523 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002524 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002525}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002526#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002527
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002528PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002529"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002530Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002531
Barry Warsaw53699e91996-12-10 23:23:01 +00002532static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002533posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002534{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002535#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002536 PyObject *o1, *o2;
2537 char *p1, *p2;
2538 BOOL result;
2539 if (unicode_file_names()) {
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002540 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2541 goto error;
2542 if (!convert_to_unicode(&o1))
2543 goto error;
2544 if (!convert_to_unicode(&o2)) {
2545 Py_DECREF(o1);
2546 goto error;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002547 }
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002548 Py_BEGIN_ALLOW_THREADS
2549 result = MoveFileW(PyUnicode_AsUnicode(o1),
2550 PyUnicode_AsUnicode(o2));
2551 Py_END_ALLOW_THREADS
2552 Py_DECREF(o1);
2553 Py_DECREF(o2);
2554 if (!result)
2555 return win32_error("rename", NULL);
2556 Py_INCREF(Py_None);
2557 return Py_None;
2558error:
2559 PyErr_Clear();
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002560 }
2561 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2562 return NULL;
2563 Py_BEGIN_ALLOW_THREADS
2564 result = MoveFileA(p1, p2);
2565 Py_END_ALLOW_THREADS
2566 if (!result)
2567 return win32_error("rename", NULL);
2568 Py_INCREF(Py_None);
2569 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002570#else
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002571 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002572#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002573}
2574
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002575
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002576PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002577"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002578Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002579
Barry Warsaw53699e91996-12-10 23:23:01 +00002580static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002581posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002582{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002583#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002584 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002585#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002586 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002587#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002588}
2589
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002590
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002591PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002592"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002593Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002594
Barry Warsaw53699e91996-12-10 23:23:01 +00002595static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002596posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002597{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002598#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002599 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002600#else
2601 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2602#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002603}
2604
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002605
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002606#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002607PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002608"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002609Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002610
Barry Warsaw53699e91996-12-10 23:23:01 +00002611static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002612posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002613{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002614 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002615 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002616 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002617 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002618 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002619 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002620 Py_END_ALLOW_THREADS
2621 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002622}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002623#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002624
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002625
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002626PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002627"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002628Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002629
Barry Warsaw53699e91996-12-10 23:23:01 +00002630static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002631posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002632{
2633 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002634 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002635 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002636 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002637 if (i < 0)
2638 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002639 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002640}
2641
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002642
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002643PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002644"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002645Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002646
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002647PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002648"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002649Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002650
Barry Warsaw53699e91996-12-10 23:23:01 +00002651static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002652posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002653{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002654#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002655 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002656#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002657 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002658#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002659}
2660
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002661
Guido van Rossumb6775db1994-08-01 11:34:53 +00002662#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002663PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002664"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002665Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002666
Barry Warsaw53699e91996-12-10 23:23:01 +00002667static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002668posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002669{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002670 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002671 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002672
Barry Warsaw53699e91996-12-10 23:23:01 +00002673 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002674 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002675 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002676 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002677 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002678 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002679 u.sysname,
2680 u.nodename,
2681 u.release,
2682 u.version,
2683 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002684}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002685#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002686
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002687static int
2688extract_time(PyObject *t, long* sec, long* usec)
2689{
2690 long intval;
2691 if (PyFloat_Check(t)) {
2692 double tval = PyFloat_AsDouble(t);
Christian Heimese93237d2007-12-19 02:37:44 +00002693 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002694 if (!intobj)
2695 return -1;
2696 intval = PyInt_AsLong(intobj);
2697 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002698 if (intval == -1 && PyErr_Occurred())
2699 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002700 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002701 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002702 if (*usec < 0)
2703 /* If rounding gave us a negative number,
2704 truncate. */
2705 *usec = 0;
2706 return 0;
2707 }
2708 intval = PyInt_AsLong(t);
2709 if (intval == -1 && PyErr_Occurred())
2710 return -1;
2711 *sec = intval;
2712 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002713 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002714}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002715
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002716PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002717"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002718utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002719Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002720second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002721
Barry Warsaw53699e91996-12-10 23:23:01 +00002722static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002723posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002724{
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002725#ifdef Py_WIN_WIDE_FILENAMES
2726 PyObject *arg;
2727 PyUnicodeObject *obwpath;
2728 wchar_t *wpath = NULL;
2729 char *apath = NULL;
2730 HANDLE hFile;
2731 long atimesec, mtimesec, ausec, musec;
2732 FILETIME atime, mtime;
2733 PyObject *result = NULL;
2734
2735 if (unicode_file_names()) {
2736 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2737 wpath = PyUnicode_AS_UNICODE(obwpath);
2738 Py_BEGIN_ALLOW_THREADS
2739 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002740 NULL, OPEN_EXISTING,
2741 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002742 Py_END_ALLOW_THREADS
2743 if (hFile == INVALID_HANDLE_VALUE)
2744 return win32_error_unicode("utime", wpath);
2745 } else
2746 /* Drop the argument parsing error as narrow strings
2747 are also valid. */
2748 PyErr_Clear();
2749 }
2750 if (!wpath) {
2751 if (!PyArg_ParseTuple(args, "etO:utime",
2752 Py_FileSystemDefaultEncoding, &apath, &arg))
2753 return NULL;
2754 Py_BEGIN_ALLOW_THREADS
2755 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002756 NULL, OPEN_EXISTING,
2757 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002758 Py_END_ALLOW_THREADS
2759 if (hFile == INVALID_HANDLE_VALUE) {
2760 win32_error("utime", apath);
2761 PyMem_Free(apath);
2762 return NULL;
2763 }
2764 PyMem_Free(apath);
2765 }
2766
2767 if (arg == Py_None) {
2768 SYSTEMTIME now;
2769 GetSystemTime(&now);
2770 if (!SystemTimeToFileTime(&now, &mtime) ||
2771 !SystemTimeToFileTime(&now, &atime)) {
2772 win32_error("utime", NULL);
2773 goto done;
2774 }
2775 }
2776 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2777 PyErr_SetString(PyExc_TypeError,
2778 "utime() arg 2 must be a tuple (atime, mtime)");
2779 goto done;
2780 }
2781 else {
2782 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2783 &atimesec, &ausec) == -1)
2784 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002785 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002786 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2787 &mtimesec, &musec) == -1)
2788 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002789 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002790 }
2791 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2792 /* Avoid putting the file name into the error here,
2793 as that may confuse the user into believing that
2794 something is wrong with the file, when it also
2795 could be the time stamp that gives a problem. */
2796 win32_error("utime", NULL);
2797 }
2798 Py_INCREF(Py_None);
2799 result = Py_None;
2800done:
2801 CloseHandle(hFile);
2802 return result;
2803#else /* Py_WIN_WIDE_FILENAMES */
2804
Neal Norwitz2adf2102004-06-09 01:46:02 +00002805 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002806 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002807 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002808 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002809
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002810#if defined(HAVE_UTIMES)
2811 struct timeval buf[2];
2812#define ATIME buf[0].tv_sec
2813#define MTIME buf[1].tv_sec
2814#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002815/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002816 struct utimbuf buf;
2817#define ATIME buf.actime
2818#define MTIME buf.modtime
2819#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002820#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002821 time_t buf[2];
2822#define ATIME buf[0]
2823#define MTIME buf[1]
2824#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002825#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002826
Mark Hammond817c9292003-12-03 01:22:38 +00002827
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002828 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002829 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002830 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002831 if (arg == Py_None) {
2832 /* optional time values not given */
2833 Py_BEGIN_ALLOW_THREADS
2834 res = utime(path, NULL);
2835 Py_END_ALLOW_THREADS
2836 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002837 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002838 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002839 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002840 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002841 return NULL;
2842 }
2843 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002844 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002845 &atime, &ausec) == -1) {
2846 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002847 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002848 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002849 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002850 &mtime, &musec) == -1) {
2851 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002852 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002853 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002854 ATIME = atime;
2855 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002856#ifdef HAVE_UTIMES
2857 buf[0].tv_usec = ausec;
2858 buf[1].tv_usec = musec;
2859 Py_BEGIN_ALLOW_THREADS
2860 res = utimes(path, buf);
2861 Py_END_ALLOW_THREADS
2862#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002863 Py_BEGIN_ALLOW_THREADS
2864 res = utime(path, UTIME_ARG);
2865 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002866#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002867 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002868 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002869 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002870 }
Neal Norwitz96652712004-06-06 20:40:27 +00002871 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002872 Py_INCREF(Py_None);
2873 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002874#undef UTIME_ARG
2875#undef ATIME
2876#undef MTIME
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002877#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002878}
2879
Guido van Rossum85e3b011991-06-03 12:42:10 +00002880
Guido van Rossum3b066191991-06-04 19:40:25 +00002881/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002882
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002883PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002884"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002885Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002886
Barry Warsaw53699e91996-12-10 23:23:01 +00002887static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002888posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002889{
2890 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002891 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002892 return NULL;
2893 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002894 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002895}
2896
Martin v. Löwis114619e2002-10-07 06:44:21 +00002897#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2898static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002899free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002900{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002901 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002902 for (i = 0; i < count; i++)
2903 PyMem_Free(array[i]);
2904 PyMem_DEL(array);
2905}
2906#endif
2907
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002908
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002909#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002910PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002911"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002912Execute an executable path with arguments, replacing current process.\n\
2913\n\
2914 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002915 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002916
Barry Warsaw53699e91996-12-10 23:23:01 +00002917static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002918posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002919{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002920 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002921 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002922 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002923 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002924 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002925
Guido van Rossum89b33251993-10-22 14:26:06 +00002926 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002927 argv is a list or tuple of strings. */
2928
Martin v. Löwis114619e2002-10-07 06:44:21 +00002929 if (!PyArg_ParseTuple(args, "etO:execv",
2930 Py_FileSystemDefaultEncoding,
2931 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002932 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002933 if (PyList_Check(argv)) {
2934 argc = PyList_Size(argv);
2935 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002936 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002937 else if (PyTuple_Check(argv)) {
2938 argc = PyTuple_Size(argv);
2939 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002940 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002941 else {
Fred Drake661ea262000-10-24 19:57:45 +00002942 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002943 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002944 return NULL;
2945 }
2946
Barry Warsaw53699e91996-12-10 23:23:01 +00002947 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002948 if (argvlist == NULL) {
2949 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002950 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002951 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002952 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002953 if (!PyArg_Parse((*getitem)(argv, i), "et",
2954 Py_FileSystemDefaultEncoding,
2955 &argvlist[i])) {
2956 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002957 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002958 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002959 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002960 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002961
Guido van Rossum85e3b011991-06-03 12:42:10 +00002962 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002963 }
2964 argvlist[argc] = NULL;
2965
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002966 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002967
Guido van Rossum85e3b011991-06-03 12:42:10 +00002968 /* If we get here it's definitely an error */
2969
Martin v. Löwis114619e2002-10-07 06:44:21 +00002970 free_string_array(argvlist, argc);
2971 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002972 return posix_error();
2973}
2974
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002975
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002976PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002977"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002978Execute a path with arguments and environment, replacing current process.\n\
2979\n\
2980 path: path of executable file\n\
2981 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002982 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002983
Barry Warsaw53699e91996-12-10 23:23:01 +00002984static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002985posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002986{
2987 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002988 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002989 char **argvlist;
2990 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002991 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002992 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002993 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002994 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002995
2996 /* execve has three arguments: (path, argv, env), where
2997 argv is a list or tuple of strings and env is a dictionary
2998 like posix.environ. */
2999
Martin v. Löwis114619e2002-10-07 06:44:21 +00003000 if (!PyArg_ParseTuple(args, "etOO:execve",
3001 Py_FileSystemDefaultEncoding,
3002 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003003 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003004 if (PyList_Check(argv)) {
3005 argc = PyList_Size(argv);
3006 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003007 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003008 else if (PyTuple_Check(argv)) {
3009 argc = PyTuple_Size(argv);
3010 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003011 }
3012 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003013 PyErr_SetString(PyExc_TypeError,
3014 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003015 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003016 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003017 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003018 PyErr_SetString(PyExc_TypeError,
3019 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003020 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003021 }
3022
Barry Warsaw53699e91996-12-10 23:23:01 +00003023 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003024 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003025 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003026 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003027 }
3028 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003029 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00003030 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00003031 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00003032 &argvlist[i]))
3033 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003034 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003035 goto fail_1;
3036 }
3037 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003038 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003039 argvlist[argc] = NULL;
3040
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003041 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003042 if (i < 0)
3043 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00003044 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003045 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003046 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003047 goto fail_1;
3048 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003049 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003050 keys = PyMapping_Keys(env);
3051 vals = PyMapping_Values(env);
3052 if (!keys || !vals)
3053 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003054 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3055 PyErr_SetString(PyExc_TypeError,
3056 "execve(): env.keys() or env.values() is not a list");
3057 goto fail_2;
3058 }
Tim Peters5aa91602002-01-30 05:46:57 +00003059
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003060 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003061 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003062 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003063
3064 key = PyList_GetItem(keys, pos);
3065 val = PyList_GetItem(vals, pos);
3066 if (!key || !val)
3067 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003068
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003069 if (!PyArg_Parse(
3070 key,
3071 "s;execve() arg 3 contains a non-string key",
3072 &k) ||
3073 !PyArg_Parse(
3074 val,
3075 "s;execve() arg 3 contains a non-string value",
3076 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003077 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003078 goto fail_2;
3079 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003080
3081#if defined(PYOS_OS2)
3082 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3083 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3084#endif
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003085 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003086 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003087 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003088 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003089 goto fail_2;
3090 }
Tim Petersc8996f52001-12-03 20:41:00 +00003091 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003092 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003093#if defined(PYOS_OS2)
3094 }
3095#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003096 }
3097 envlist[envc] = 0;
3098
3099 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003100
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003101 /* If we get here it's definitely an error */
3102
3103 (void) posix_error();
3104
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003105 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003106 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003107 PyMem_DEL(envlist[envc]);
3108 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003109 fail_1:
3110 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003111 Py_XDECREF(vals);
3112 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003113 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003114 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003115 return NULL;
3116}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003117#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003118
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003119
Guido van Rossuma1065681999-01-25 23:20:23 +00003120#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003121PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003122"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003123Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003124\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003125 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003126 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003127 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003128
3129static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003130posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003131{
3132 char *path;
3133 PyObject *argv;
3134 char **argvlist;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003135 int mode, i;
3136 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003137 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003138 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003139
3140 /* spawnv has three arguments: (mode, path, argv), where
3141 argv is a list or tuple of strings. */
3142
Martin v. Löwis114619e2002-10-07 06:44:21 +00003143 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3144 Py_FileSystemDefaultEncoding,
3145 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003146 return NULL;
3147 if (PyList_Check(argv)) {
3148 argc = PyList_Size(argv);
3149 getitem = PyList_GetItem;
3150 }
3151 else if (PyTuple_Check(argv)) {
3152 argc = PyTuple_Size(argv);
3153 getitem = PyTuple_GetItem;
3154 }
3155 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003156 PyErr_SetString(PyExc_TypeError,
3157 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003158 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003159 return NULL;
3160 }
3161
3162 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003163 if (argvlist == NULL) {
3164 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003165 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003166 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003167 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003168 if (!PyArg_Parse((*getitem)(argv, i), "et",
3169 Py_FileSystemDefaultEncoding,
3170 &argvlist[i])) {
3171 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003172 PyErr_SetString(
3173 PyExc_TypeError,
3174 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003175 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00003176 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003177 }
3178 }
3179 argvlist[argc] = NULL;
3180
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003181#if defined(PYOS_OS2) && defined(PYCC_GCC)
3182 Py_BEGIN_ALLOW_THREADS
3183 spawnval = spawnv(mode, path, argvlist);
3184 Py_END_ALLOW_THREADS
3185#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003186 if (mode == _OLD_P_OVERLAY)
3187 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003188
Tim Peters25059d32001-12-07 20:35:43 +00003189 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003190 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003191 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003192#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003193
Martin v. Löwis114619e2002-10-07 06:44:21 +00003194 free_string_array(argvlist, argc);
3195 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003196
Fred Drake699f3522000-06-29 21:12:41 +00003197 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003198 return posix_error();
3199 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003200#if SIZEOF_LONG == SIZEOF_VOID_P
3201 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003202#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003203 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003204#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003205}
3206
3207
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003208PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003209"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003210Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003211\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003212 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003213 path: path of executable file\n\
3214 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003215 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003216
3217static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003218posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003219{
3220 char *path;
3221 PyObject *argv, *env;
3222 char **argvlist;
3223 char **envlist;
3224 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003225 int mode, pos, envc;
3226 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003227 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003228 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003229 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003230
3231 /* spawnve has four arguments: (mode, path, argv, env), where
3232 argv is a list or tuple of strings and env is a dictionary
3233 like posix.environ. */
3234
Martin v. Löwis114619e2002-10-07 06:44:21 +00003235 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3236 Py_FileSystemDefaultEncoding,
3237 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003238 return NULL;
3239 if (PyList_Check(argv)) {
3240 argc = PyList_Size(argv);
3241 getitem = PyList_GetItem;
3242 }
3243 else if (PyTuple_Check(argv)) {
3244 argc = PyTuple_Size(argv);
3245 getitem = PyTuple_GetItem;
3246 }
3247 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003248 PyErr_SetString(PyExc_TypeError,
3249 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003250 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003251 }
3252 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003253 PyErr_SetString(PyExc_TypeError,
3254 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003255 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003256 }
3257
3258 argvlist = PyMem_NEW(char *, argc+1);
3259 if (argvlist == NULL) {
3260 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003261 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003262 }
3263 for (i = 0; i < argc; i++) {
3264 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003265 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00003266 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00003267 &argvlist[i]))
3268 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003269 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003270 goto fail_1;
3271 }
3272 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003273 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003274 argvlist[argc] = NULL;
3275
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003276 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003277 if (i < 0)
3278 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003279 envlist = PyMem_NEW(char *, i + 1);
3280 if (envlist == NULL) {
3281 PyErr_NoMemory();
3282 goto fail_1;
3283 }
3284 envc = 0;
3285 keys = PyMapping_Keys(env);
3286 vals = PyMapping_Values(env);
3287 if (!keys || !vals)
3288 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003289 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3290 PyErr_SetString(PyExc_TypeError,
3291 "spawnve(): env.keys() or env.values() is not a list");
3292 goto fail_2;
3293 }
Tim Peters5aa91602002-01-30 05:46:57 +00003294
Guido van Rossuma1065681999-01-25 23:20:23 +00003295 for (pos = 0; pos < i; pos++) {
3296 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003297 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003298
3299 key = PyList_GetItem(keys, pos);
3300 val = PyList_GetItem(vals, pos);
3301 if (!key || !val)
3302 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003303
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003304 if (!PyArg_Parse(
3305 key,
3306 "s;spawnve() arg 3 contains a non-string key",
3307 &k) ||
3308 !PyArg_Parse(
3309 val,
3310 "s;spawnve() arg 3 contains a non-string value",
3311 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003312 {
3313 goto fail_2;
3314 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003315 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003316 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003317 if (p == NULL) {
3318 PyErr_NoMemory();
3319 goto fail_2;
3320 }
Tim Petersc8996f52001-12-03 20:41:00 +00003321 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003322 envlist[envc++] = p;
3323 }
3324 envlist[envc] = 0;
3325
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003326#if defined(PYOS_OS2) && defined(PYCC_GCC)
3327 Py_BEGIN_ALLOW_THREADS
3328 spawnval = spawnve(mode, path, argvlist, envlist);
3329 Py_END_ALLOW_THREADS
3330#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003331 if (mode == _OLD_P_OVERLAY)
3332 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003333
3334 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003335 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003336 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003337#endif
Tim Peters25059d32001-12-07 20:35:43 +00003338
Fred Drake699f3522000-06-29 21:12:41 +00003339 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003340 (void) posix_error();
3341 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003342#if SIZEOF_LONG == SIZEOF_VOID_P
3343 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003344#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003345 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003346#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003347
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003348 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003349 while (--envc >= 0)
3350 PyMem_DEL(envlist[envc]);
3351 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003352 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003353 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003354 Py_XDECREF(vals);
3355 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003356 fail_0:
3357 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003358 return res;
3359}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003360
3361/* OS/2 supports spawnvp & spawnvpe natively */
3362#if defined(PYOS_OS2)
3363PyDoc_STRVAR(posix_spawnvp__doc__,
3364"spawnvp(mode, file, args)\n\n\
3365Execute the program 'file' in a new process, using the environment\n\
3366search path to find the file.\n\
3367\n\
3368 mode: mode of process creation\n\
3369 file: executable file name\n\
3370 args: tuple or list of strings");
3371
3372static PyObject *
3373posix_spawnvp(PyObject *self, PyObject *args)
3374{
3375 char *path;
3376 PyObject *argv;
3377 char **argvlist;
3378 int mode, i, argc;
3379 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003380 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003381
3382 /* spawnvp has three arguments: (mode, path, argv), where
3383 argv is a list or tuple of strings. */
3384
3385 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3386 Py_FileSystemDefaultEncoding,
3387 &path, &argv))
3388 return NULL;
3389 if (PyList_Check(argv)) {
3390 argc = PyList_Size(argv);
3391 getitem = PyList_GetItem;
3392 }
3393 else if (PyTuple_Check(argv)) {
3394 argc = PyTuple_Size(argv);
3395 getitem = PyTuple_GetItem;
3396 }
3397 else {
3398 PyErr_SetString(PyExc_TypeError,
3399 "spawnvp() arg 2 must be a tuple or list");
3400 PyMem_Free(path);
3401 return NULL;
3402 }
3403
3404 argvlist = PyMem_NEW(char *, argc+1);
3405 if (argvlist == NULL) {
3406 PyMem_Free(path);
3407 return PyErr_NoMemory();
3408 }
3409 for (i = 0; i < argc; i++) {
3410 if (!PyArg_Parse((*getitem)(argv, i), "et",
3411 Py_FileSystemDefaultEncoding,
3412 &argvlist[i])) {
3413 free_string_array(argvlist, i);
3414 PyErr_SetString(
3415 PyExc_TypeError,
3416 "spawnvp() arg 2 must contain only strings");
3417 PyMem_Free(path);
3418 return NULL;
3419 }
3420 }
3421 argvlist[argc] = NULL;
3422
3423 Py_BEGIN_ALLOW_THREADS
3424#if defined(PYCC_GCC)
3425 spawnval = spawnvp(mode, path, argvlist);
3426#else
3427 spawnval = _spawnvp(mode, path, argvlist);
3428#endif
3429 Py_END_ALLOW_THREADS
3430
3431 free_string_array(argvlist, argc);
3432 PyMem_Free(path);
3433
3434 if (spawnval == -1)
3435 return posix_error();
3436 else
3437 return Py_BuildValue("l", (long) spawnval);
3438}
3439
3440
3441PyDoc_STRVAR(posix_spawnvpe__doc__,
3442"spawnvpe(mode, file, args, env)\n\n\
3443Execute the program 'file' in a new process, using the environment\n\
3444search path to find the file.\n\
3445\n\
3446 mode: mode of process creation\n\
3447 file: executable file name\n\
3448 args: tuple or list of arguments\n\
3449 env: dictionary of strings mapping to strings");
3450
3451static PyObject *
3452posix_spawnvpe(PyObject *self, PyObject *args)
3453{
3454 char *path;
3455 PyObject *argv, *env;
3456 char **argvlist;
3457 char **envlist;
3458 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3459 int mode, i, pos, argc, envc;
3460 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003461 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003462 int lastarg = 0;
3463
3464 /* spawnvpe has four arguments: (mode, path, argv, env), where
3465 argv is a list or tuple of strings and env is a dictionary
3466 like posix.environ. */
3467
3468 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3469 Py_FileSystemDefaultEncoding,
3470 &path, &argv, &env))
3471 return NULL;
3472 if (PyList_Check(argv)) {
3473 argc = PyList_Size(argv);
3474 getitem = PyList_GetItem;
3475 }
3476 else if (PyTuple_Check(argv)) {
3477 argc = PyTuple_Size(argv);
3478 getitem = PyTuple_GetItem;
3479 }
3480 else {
3481 PyErr_SetString(PyExc_TypeError,
3482 "spawnvpe() arg 2 must be a tuple or list");
3483 goto fail_0;
3484 }
3485 if (!PyMapping_Check(env)) {
3486 PyErr_SetString(PyExc_TypeError,
3487 "spawnvpe() arg 3 must be a mapping object");
3488 goto fail_0;
3489 }
3490
3491 argvlist = PyMem_NEW(char *, argc+1);
3492 if (argvlist == NULL) {
3493 PyErr_NoMemory();
3494 goto fail_0;
3495 }
3496 for (i = 0; i < argc; i++) {
3497 if (!PyArg_Parse((*getitem)(argv, i),
3498 "et;spawnvpe() arg 2 must contain only strings",
3499 Py_FileSystemDefaultEncoding,
3500 &argvlist[i]))
3501 {
3502 lastarg = i;
3503 goto fail_1;
3504 }
3505 }
3506 lastarg = argc;
3507 argvlist[argc] = NULL;
3508
3509 i = PyMapping_Size(env);
3510 if (i < 0)
3511 goto fail_1;
3512 envlist = PyMem_NEW(char *, i + 1);
3513 if (envlist == NULL) {
3514 PyErr_NoMemory();
3515 goto fail_1;
3516 }
3517 envc = 0;
3518 keys = PyMapping_Keys(env);
3519 vals = PyMapping_Values(env);
3520 if (!keys || !vals)
3521 goto fail_2;
3522 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3523 PyErr_SetString(PyExc_TypeError,
3524 "spawnvpe(): env.keys() or env.values() is not a list");
3525 goto fail_2;
3526 }
3527
3528 for (pos = 0; pos < i; pos++) {
3529 char *p, *k, *v;
3530 size_t len;
3531
3532 key = PyList_GetItem(keys, pos);
3533 val = PyList_GetItem(vals, pos);
3534 if (!key || !val)
3535 goto fail_2;
3536
3537 if (!PyArg_Parse(
3538 key,
3539 "s;spawnvpe() arg 3 contains a non-string key",
3540 &k) ||
3541 !PyArg_Parse(
3542 val,
3543 "s;spawnvpe() arg 3 contains a non-string value",
3544 &v))
3545 {
3546 goto fail_2;
3547 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003548 len = PyString_Size(key) + PyString_Size(val) + 2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003549 p = PyMem_NEW(char, len);
3550 if (p == NULL) {
3551 PyErr_NoMemory();
3552 goto fail_2;
3553 }
3554 PyOS_snprintf(p, len, "%s=%s", k, v);
3555 envlist[envc++] = p;
3556 }
3557 envlist[envc] = 0;
3558
3559 Py_BEGIN_ALLOW_THREADS
3560#if defined(PYCC_GCC)
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003561 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003562#else
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003563 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003564#endif
3565 Py_END_ALLOW_THREADS
3566
3567 if (spawnval == -1)
3568 (void) posix_error();
3569 else
3570 res = Py_BuildValue("l", (long) spawnval);
3571
3572 fail_2:
3573 while (--envc >= 0)
3574 PyMem_DEL(envlist[envc]);
3575 PyMem_DEL(envlist);
3576 fail_1:
3577 free_string_array(argvlist, lastarg);
3578 Py_XDECREF(vals);
3579 Py_XDECREF(keys);
3580 fail_0:
3581 PyMem_Free(path);
3582 return res;
3583}
3584#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003585#endif /* HAVE_SPAWNV */
3586
3587
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003588#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003589PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003590"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003591Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3592\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003593Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003594
3595static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003596posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003597{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003598 pid_t pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003599 if (pid == -1)
3600 return posix_error();
Gregory P. Smithfb7a50f2008-07-14 06:06:48 +00003601 if (pid == 0)
3602 PyOS_AfterFork();
Christian Heimes951cc0f2008-01-31 23:08:23 +00003603 return PyInt_FromLong(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003604}
3605#endif
3606
3607
Guido van Rossumad0ee831995-03-01 10:34:45 +00003608#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003609PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003610"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003611Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003612Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003613
Barry Warsaw53699e91996-12-10 23:23:01 +00003614static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003615posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003616{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003617 pid_t pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003618 if (pid == -1)
3619 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003620 if (pid == 0)
3621 PyOS_AfterFork();
Christian Heimes951cc0f2008-01-31 23:08:23 +00003622 return PyInt_FromLong(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003623}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003624#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003625
Neal Norwitzb59798b2003-03-21 01:43:31 +00003626/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003627/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3628#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003629#define DEV_PTY_FILE "/dev/ptc"
3630#define HAVE_DEV_PTMX
3631#else
3632#define DEV_PTY_FILE "/dev/ptmx"
3633#endif
3634
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003635#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003636#ifdef HAVE_PTY_H
3637#include <pty.h>
3638#else
3639#ifdef HAVE_LIBUTIL_H
3640#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003641#endif /* HAVE_LIBUTIL_H */
3642#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003643#ifdef HAVE_STROPTS_H
3644#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003645#endif
3646#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003647
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003648#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003649PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003650"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003651Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003652
3653static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003654posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003655{
3656 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003657#ifndef HAVE_OPENPTY
3658 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003659#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003660#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003661 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003662#ifdef sun
Neal Norwitz84a98e02006-04-10 07:44:23 +00003663 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003664#endif
3665#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003666
Thomas Wouters70c21a12000-07-14 14:28:33 +00003667#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003668 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3669 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003670#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003671 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3672 if (slave_name == NULL)
3673 return posix_error();
3674
3675 slave_fd = open(slave_name, O_RDWR);
3676 if (slave_fd < 0)
3677 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003678#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003679 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003680 if (master_fd < 0)
3681 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003682 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003683 /* change permission of slave */
3684 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003685 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003686 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003687 }
3688 /* unlock slave */
3689 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003690 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003691 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003692 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003693 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003694 slave_name = ptsname(master_fd); /* get name of slave */
3695 if (slave_name == NULL)
3696 return posix_error();
3697 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3698 if (slave_fd < 0)
3699 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003700#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003701 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3702 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003703#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003704 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003705#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003706#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003707#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003708
Fred Drake8cef4cf2000-06-28 16:40:38 +00003709 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003710
Fred Drake8cef4cf2000-06-28 16:40:38 +00003711}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003712#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003713
3714#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003715PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003716"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003717Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3718Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003719To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003720
3721static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003722posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003723{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003724 int master_fd = -1;
3725 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003726
Fred Drake8cef4cf2000-06-28 16:40:38 +00003727 pid = forkpty(&master_fd, NULL, NULL, NULL);
3728 if (pid == -1)
3729 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003730 if (pid == 0)
3731 PyOS_AfterFork();
Christian Heimes951cc0f2008-01-31 23:08:23 +00003732 return Py_BuildValue("(li)", pid, master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003733}
3734#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003735
Guido van Rossumad0ee831995-03-01 10:34:45 +00003736#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003737PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003738"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003739Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003740
Barry Warsaw53699e91996-12-10 23:23:01 +00003741static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003742posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003743{
Barry Warsaw53699e91996-12-10 23:23:01 +00003744 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003745}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003746#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003747
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003748
Guido van Rossumad0ee831995-03-01 10:34:45 +00003749#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003750PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003751"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003752Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003753
Barry Warsaw53699e91996-12-10 23:23:01 +00003754static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003755posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003756{
Barry Warsaw53699e91996-12-10 23:23:01 +00003757 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003758}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003759#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003760
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003761
Guido van Rossumad0ee831995-03-01 10:34:45 +00003762#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003763PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003764"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003765Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003766
Barry Warsaw53699e91996-12-10 23:23:01 +00003767static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003768posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003769{
Barry Warsaw53699e91996-12-10 23:23:01 +00003770 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003771}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003772#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003773
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003774
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003775PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003776"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003777Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003778
Barry Warsaw53699e91996-12-10 23:23:01 +00003779static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003780posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003781{
Barry Warsaw53699e91996-12-10 23:23:01 +00003782 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003783}
3784
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003785
Fred Drakec9680921999-12-13 16:37:25 +00003786#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003787PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003788"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003789Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003790
3791static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003792posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003793{
3794 PyObject *result = NULL;
3795
Fred Drakec9680921999-12-13 16:37:25 +00003796#ifdef NGROUPS_MAX
3797#define MAX_GROUPS NGROUPS_MAX
3798#else
3799 /* defined to be 16 on Solaris7, so this should be a small number */
3800#define MAX_GROUPS 64
3801#endif
3802 gid_t grouplist[MAX_GROUPS];
3803 int n;
3804
3805 n = getgroups(MAX_GROUPS, grouplist);
3806 if (n < 0)
3807 posix_error();
3808 else {
3809 result = PyList_New(n);
3810 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003811 int i;
3812 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003813 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003814 if (o == NULL) {
3815 Py_DECREF(result);
3816 result = NULL;
3817 break;
3818 }
3819 PyList_SET_ITEM(result, i, o);
3820 }
3821 }
3822 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003823
Fred Drakec9680921999-12-13 16:37:25 +00003824 return result;
3825}
3826#endif
3827
Martin v. Löwis606edc12002-06-13 21:09:11 +00003828#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003829PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003830"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003831Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003832
3833static PyObject *
3834posix_getpgid(PyObject *self, PyObject *args)
3835{
3836 int pid, pgid;
3837 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3838 return NULL;
3839 pgid = getpgid(pid);
3840 if (pgid < 0)
3841 return posix_error();
3842 return PyInt_FromLong((long)pgid);
3843}
3844#endif /* HAVE_GETPGID */
3845
3846
Guido van Rossumb6775db1994-08-01 11:34:53 +00003847#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003848PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003849"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003850Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003851
Barry Warsaw53699e91996-12-10 23:23:01 +00003852static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003853posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003854{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003855#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003856 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003857#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003858 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003859#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003860}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003861#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003862
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003863
Guido van Rossumb6775db1994-08-01 11:34:53 +00003864#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003865PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003866"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003867Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003868
Barry Warsaw53699e91996-12-10 23:23:01 +00003869static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003870posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003871{
Guido van Rossum64933891994-10-20 21:56:42 +00003872#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003873 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003874#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003875 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003876#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003877 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003878 Py_INCREF(Py_None);
3879 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003880}
3881
Guido van Rossumb6775db1994-08-01 11:34:53 +00003882#endif /* HAVE_SETPGRP */
3883
Guido van Rossumad0ee831995-03-01 10:34:45 +00003884#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003885PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003886"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003887Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003888
Barry Warsaw53699e91996-12-10 23:23:01 +00003889static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003890posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003891{
Christian Heimesd491d712008-02-01 18:49:26 +00003892 return PyInt_FromLong(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003893}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003894#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003895
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003896
Fred Drake12c6e2d1999-12-14 21:25:03 +00003897#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003898PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003899"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003900Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003901
3902static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003903posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003904{
Neal Norwitze241ce82003-02-17 18:17:05 +00003905 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003906 char *name;
3907 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003908
Fred Drakea30680b2000-12-06 21:24:28 +00003909 errno = 0;
3910 name = getlogin();
3911 if (name == NULL) {
3912 if (errno)
3913 posix_error();
3914 else
3915 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003916 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003917 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003918 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003919 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003920 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003921
Fred Drake12c6e2d1999-12-14 21:25:03 +00003922 return result;
3923}
3924#endif
3925
Guido van Rossumad0ee831995-03-01 10:34:45 +00003926#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003927PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003928"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003929Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003930
Barry Warsaw53699e91996-12-10 23:23:01 +00003931static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003932posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003933{
Barry Warsaw53699e91996-12-10 23:23:01 +00003934 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003935}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003936#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003937
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003938
Guido van Rossumad0ee831995-03-01 10:34:45 +00003939#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003940PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003941"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003942Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003943
Barry Warsaw53699e91996-12-10 23:23:01 +00003944static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003945posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003946{
Christian Heimesd491d712008-02-01 18:49:26 +00003947 pid_t pid;
3948 int sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003949 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003950 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003951#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003952 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3953 APIRET rc;
3954 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003955 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003956
3957 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3958 APIRET rc;
3959 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003960 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003961
3962 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003963 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003964#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003965 if (kill(pid, sig) == -1)
3966 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003967#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003968 Py_INCREF(Py_None);
3969 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003970}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003971#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003972
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003973#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003974PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003975"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003976Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003977
3978static PyObject *
3979posix_killpg(PyObject *self, PyObject *args)
3980{
3981 int pgid, sig;
3982 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3983 return NULL;
3984 if (killpg(pgid, sig) == -1)
3985 return posix_error();
3986 Py_INCREF(Py_None);
3987 return Py_None;
3988}
3989#endif
3990
Guido van Rossumc0125471996-06-28 18:55:32 +00003991#ifdef HAVE_PLOCK
3992
3993#ifdef HAVE_SYS_LOCK_H
3994#include <sys/lock.h>
3995#endif
3996
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003997PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003998"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003999Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004000
Barry Warsaw53699e91996-12-10 23:23:01 +00004001static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004002posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004003{
4004 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004005 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00004006 return NULL;
4007 if (plock(op) == -1)
4008 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004009 Py_INCREF(Py_None);
4010 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004011}
4012#endif
4013
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004014
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004015#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004016PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004017"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004018Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004019
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004020#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004021#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004022static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004023async_system(const char *command)
4024{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004025 char errormsg[256], args[1024];
4026 RESULTCODES rcodes;
4027 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004028
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004029 char *shell = getenv("COMSPEC");
4030 if (!shell)
4031 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004032
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004033 /* avoid overflowing the argument buffer */
4034 if (strlen(shell) + 3 + strlen(command) >= 1024)
4035 return ERROR_NOT_ENOUGH_MEMORY
4036
4037 args[0] = '\0';
4038 strcat(args, shell);
4039 strcat(args, "/c ");
4040 strcat(args, command);
4041
4042 /* execute asynchronously, inheriting the environment */
4043 rc = DosExecPgm(errormsg,
4044 sizeof(errormsg),
4045 EXEC_ASYNC,
4046 args,
4047 NULL,
4048 &rcodes,
4049 shell);
4050 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004051}
4052
Guido van Rossumd48f2521997-12-05 22:19:34 +00004053static FILE *
4054popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004055{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004056 int oldfd, tgtfd;
4057 HFILE pipeh[2];
4058 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004059
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004060 /* mode determines which of stdin or stdout is reconnected to
4061 * the pipe to the child
4062 */
4063 if (strchr(mode, 'r') != NULL) {
4064 tgt_fd = 1; /* stdout */
4065 } else if (strchr(mode, 'w')) {
4066 tgt_fd = 0; /* stdin */
4067 } else {
4068 *err = ERROR_INVALID_ACCESS;
4069 return NULL;
4070 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004071
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00004072 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004073 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4074 *err = rc;
4075 return NULL;
4076 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004077
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004078 /* prevent other threads accessing stdio */
4079 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004080
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004081 /* reconnect stdio and execute child */
4082 oldfd = dup(tgtfd);
4083 close(tgtfd);
4084 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4085 DosClose(pipeh[tgtfd]);
4086 rc = async_system(command);
4087 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004088
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004089 /* restore stdio */
4090 dup2(oldfd, tgtfd);
4091 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004092
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004093 /* allow other threads access to stdio */
4094 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004095
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004096 /* if execution of child was successful return file stream */
4097 if (rc == NO_ERROR)
4098 return fdopen(pipeh[1 - tgtfd], mode);
4099 else {
4100 DosClose(pipeh[1 - tgtfd]);
4101 *err = rc;
4102 return NULL;
4103 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004104}
4105
4106static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004107posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004108{
4109 char *name;
4110 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00004111 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004112 FILE *fp;
4113 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004114 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004115 return NULL;
4116 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00004117 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004118 Py_END_ALLOW_THREADS
4119 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004120 return os2_error(err);
4121
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004122 f = PyFile_FromFile(fp, name, mode, fclose);
4123 if (f != NULL)
4124 PyFile_SetBufSize(f, bufsize);
4125 return f;
4126}
4127
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004128#elif defined(PYCC_GCC)
4129
4130/* standard posix version of popen() support */
4131static PyObject *
4132posix_popen(PyObject *self, PyObject *args)
4133{
4134 char *name;
4135 char *mode = "r";
4136 int bufsize = -1;
4137 FILE *fp;
4138 PyObject *f;
4139 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4140 return NULL;
4141 Py_BEGIN_ALLOW_THREADS
4142 fp = popen(name, mode);
4143 Py_END_ALLOW_THREADS
4144 if (fp == NULL)
4145 return posix_error();
4146 f = PyFile_FromFile(fp, name, mode, pclose);
4147 if (f != NULL)
4148 PyFile_SetBufSize(f, bufsize);
4149 return f;
4150}
4151
4152/* fork() under OS/2 has lots'o'warts
4153 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4154 * most of this code is a ripoff of the win32 code, but using the
4155 * capabilities of EMX's C library routines
4156 */
4157
4158/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4159#define POPEN_1 1
4160#define POPEN_2 2
4161#define POPEN_3 3
4162#define POPEN_4 4
4163
4164static PyObject *_PyPopen(char *, int, int, int);
4165static int _PyPclose(FILE *file);
4166
4167/*
4168 * Internal dictionary mapping popen* file pointers to process handles,
4169 * for use when retrieving the process exit code. See _PyPclose() below
4170 * for more information on this dictionary's use.
4171 */
4172static PyObject *_PyPopenProcs = NULL;
4173
4174/* os2emx version of popen2()
4175 *
4176 * The result of this function is a pipe (file) connected to the
4177 * process's stdin, and a pipe connected to the process's stdout.
4178 */
4179
4180static PyObject *
4181os2emx_popen2(PyObject *self, PyObject *args)
4182{
4183 PyObject *f;
4184 int tm=0;
4185
4186 char *cmdstring;
4187 char *mode = "t";
4188 int bufsize = -1;
4189 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4190 return NULL;
4191
4192 if (*mode == 't')
4193 tm = O_TEXT;
4194 else if (*mode != 'b') {
4195 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4196 return NULL;
4197 } else
4198 tm = O_BINARY;
4199
4200 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
4201
4202 return f;
4203}
4204
4205/*
4206 * Variation on os2emx.popen2
4207 *
4208 * The result of this function is 3 pipes - the process's stdin,
4209 * stdout and stderr
4210 */
4211
4212static PyObject *
4213os2emx_popen3(PyObject *self, PyObject *args)
4214{
4215 PyObject *f;
4216 int tm = 0;
4217
4218 char *cmdstring;
4219 char *mode = "t";
4220 int bufsize = -1;
4221 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4222 return NULL;
4223
4224 if (*mode == 't')
4225 tm = O_TEXT;
4226 else if (*mode != 'b') {
4227 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4228 return NULL;
4229 } else
4230 tm = O_BINARY;
4231
4232 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
4233
4234 return f;
4235}
4236
4237/*
4238 * Variation on os2emx.popen2
4239 *
Tim Peters11b23062003-04-23 02:39:17 +00004240 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004241 * and stdout+stderr combined as a single pipe.
4242 */
4243
4244static PyObject *
4245os2emx_popen4(PyObject *self, PyObject *args)
4246{
4247 PyObject *f;
4248 int tm = 0;
4249
4250 char *cmdstring;
4251 char *mode = "t";
4252 int bufsize = -1;
4253 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4254 return NULL;
4255
4256 if (*mode == 't')
4257 tm = O_TEXT;
4258 else if (*mode != 'b') {
4259 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4260 return NULL;
4261 } else
4262 tm = O_BINARY;
4263
4264 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
4265
4266 return f;
4267}
4268
4269/* a couple of structures for convenient handling of multiple
4270 * file handles and pipes
4271 */
4272struct file_ref
4273{
4274 int handle;
4275 int flags;
4276};
4277
4278struct pipe_ref
4279{
4280 int rd;
4281 int wr;
4282};
4283
4284/* The following code is derived from the win32 code */
4285
4286static PyObject *
4287_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4288{
4289 struct file_ref stdio[3];
4290 struct pipe_ref p_fd[3];
4291 FILE *p_s[3];
Christian Heimesd491d712008-02-01 18:49:26 +00004292 int file_count, i, pipe_err;
4293 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004294 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4295 PyObject *f, *p_f[3];
4296
4297 /* file modes for subsequent fdopen's on pipe handles */
4298 if (mode == O_TEXT)
4299 {
4300 rd_mode = "rt";
4301 wr_mode = "wt";
4302 }
4303 else
4304 {
4305 rd_mode = "rb";
4306 wr_mode = "wb";
4307 }
4308
4309 /* prepare shell references */
4310 if ((shell = getenv("EMXSHELL")) == NULL)
4311 if ((shell = getenv("COMSPEC")) == NULL)
4312 {
4313 errno = ENOENT;
4314 return posix_error();
4315 }
4316
4317 sh_name = _getname(shell);
4318 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4319 opt = "/c";
4320 else
4321 opt = "-c";
4322
4323 /* save current stdio fds + their flags, and set not inheritable */
4324 i = pipe_err = 0;
4325 while (pipe_err >= 0 && i < 3)
4326 {
4327 pipe_err = stdio[i].handle = dup(i);
4328 stdio[i].flags = fcntl(i, F_GETFD, 0);
4329 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4330 i++;
4331 }
4332 if (pipe_err < 0)
4333 {
4334 /* didn't get them all saved - clean up and bail out */
4335 int saved_err = errno;
4336 while (i-- > 0)
4337 {
4338 close(stdio[i].handle);
4339 }
4340 errno = saved_err;
4341 return posix_error();
4342 }
4343
4344 /* create pipe ends */
4345 file_count = 2;
4346 if (n == POPEN_3)
4347 file_count = 3;
4348 i = pipe_err = 0;
4349 while ((pipe_err == 0) && (i < file_count))
4350 pipe_err = pipe((int *)&p_fd[i++]);
4351 if (pipe_err < 0)
4352 {
4353 /* didn't get them all made - clean up and bail out */
4354 while (i-- > 0)
4355 {
4356 close(p_fd[i].wr);
4357 close(p_fd[i].rd);
4358 }
4359 errno = EPIPE;
4360 return posix_error();
4361 }
4362
4363 /* change the actual standard IO streams over temporarily,
4364 * making the retained pipe ends non-inheritable
4365 */
4366 pipe_err = 0;
4367
4368 /* - stdin */
4369 if (dup2(p_fd[0].rd, 0) == 0)
4370 {
4371 close(p_fd[0].rd);
4372 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4373 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4374 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4375 {
4376 close(p_fd[0].wr);
4377 pipe_err = -1;
4378 }
4379 }
4380 else
4381 {
4382 pipe_err = -1;
4383 }
4384
4385 /* - stdout */
4386 if (pipe_err == 0)
4387 {
4388 if (dup2(p_fd[1].wr, 1) == 1)
4389 {
4390 close(p_fd[1].wr);
4391 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4392 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4393 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4394 {
4395 close(p_fd[1].rd);
4396 pipe_err = -1;
4397 }
4398 }
4399 else
4400 {
4401 pipe_err = -1;
4402 }
4403 }
4404
4405 /* - stderr, as required */
4406 if (pipe_err == 0)
4407 switch (n)
4408 {
4409 case POPEN_3:
4410 {
4411 if (dup2(p_fd[2].wr, 2) == 2)
4412 {
4413 close(p_fd[2].wr);
4414 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4415 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4416 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4417 {
4418 close(p_fd[2].rd);
4419 pipe_err = -1;
4420 }
4421 }
4422 else
4423 {
4424 pipe_err = -1;
4425 }
4426 break;
4427 }
4428
4429 case POPEN_4:
4430 {
4431 if (dup2(1, 2) != 2)
4432 {
4433 pipe_err = -1;
4434 }
4435 break;
4436 }
4437 }
4438
4439 /* spawn the child process */
4440 if (pipe_err == 0)
4441 {
4442 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4443 if (pipe_pid == -1)
4444 {
4445 pipe_err = -1;
4446 }
4447 else
4448 {
4449 /* save the PID into the FILE structure
4450 * NOTE: this implementation doesn't actually
4451 * take advantage of this, but do it for
4452 * completeness - AIM Apr01
4453 */
4454 for (i = 0; i < file_count; i++)
4455 p_s[i]->_pid = pipe_pid;
4456 }
4457 }
4458
4459 /* reset standard IO to normal */
4460 for (i = 0; i < 3; i++)
4461 {
4462 dup2(stdio[i].handle, i);
4463 fcntl(i, F_SETFD, stdio[i].flags);
4464 close(stdio[i].handle);
4465 }
4466
4467 /* if any remnant problems, clean up and bail out */
4468 if (pipe_err < 0)
4469 {
4470 for (i = 0; i < 3; i++)
4471 {
4472 close(p_fd[i].rd);
4473 close(p_fd[i].wr);
4474 }
4475 errno = EPIPE;
4476 return posix_error_with_filename(cmdstring);
4477 }
4478
4479 /* build tuple of file objects to return */
4480 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4481 PyFile_SetBufSize(p_f[0], bufsize);
4482 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4483 PyFile_SetBufSize(p_f[1], bufsize);
4484 if (n == POPEN_3)
4485 {
4486 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4487 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004488 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004489 }
4490 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004491 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004492
4493 /*
4494 * Insert the files we've created into the process dictionary
4495 * all referencing the list with the process handle and the
4496 * initial number of files (see description below in _PyPclose).
4497 * Since if _PyPclose later tried to wait on a process when all
4498 * handles weren't closed, it could create a deadlock with the
4499 * child, we spend some energy here to try to ensure that we
4500 * either insert all file handles into the dictionary or none
4501 * at all. It's a little clumsy with the various popen modes
4502 * and variable number of files involved.
4503 */
4504 if (!_PyPopenProcs)
4505 {
4506 _PyPopenProcs = PyDict_New();
4507 }
4508
4509 if (_PyPopenProcs)
4510 {
4511 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4512 int ins_rc[3];
4513
4514 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4515 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4516
4517 procObj = PyList_New(2);
4518 pidObj = PyInt_FromLong((long) pipe_pid);
4519 intObj = PyInt_FromLong((long) file_count);
4520
4521 if (procObj && pidObj && intObj)
4522 {
4523 PyList_SetItem(procObj, 0, pidObj);
4524 PyList_SetItem(procObj, 1, intObj);
4525
4526 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4527 if (fileObj[0])
4528 {
4529 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4530 fileObj[0],
4531 procObj);
4532 }
4533 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4534 if (fileObj[1])
4535 {
4536 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4537 fileObj[1],
4538 procObj);
4539 }
4540 if (file_count >= 3)
4541 {
4542 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4543 if (fileObj[2])
4544 {
4545 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4546 fileObj[2],
4547 procObj);
4548 }
4549 }
4550
4551 if (ins_rc[0] < 0 || !fileObj[0] ||
4552 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4553 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4554 {
4555 /* Something failed - remove any dictionary
4556 * entries that did make it.
4557 */
4558 if (!ins_rc[0] && fileObj[0])
4559 {
4560 PyDict_DelItem(_PyPopenProcs,
4561 fileObj[0]);
4562 }
4563 if (!ins_rc[1] && fileObj[1])
4564 {
4565 PyDict_DelItem(_PyPopenProcs,
4566 fileObj[1]);
4567 }
4568 if (!ins_rc[2] && fileObj[2])
4569 {
4570 PyDict_DelItem(_PyPopenProcs,
4571 fileObj[2]);
4572 }
4573 }
4574 }
Tim Peters11b23062003-04-23 02:39:17 +00004575
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004576 /*
4577 * Clean up our localized references for the dictionary keys
4578 * and value since PyDict_SetItem will Py_INCREF any copies
4579 * that got placed in the dictionary.
4580 */
4581 Py_XDECREF(procObj);
4582 Py_XDECREF(fileObj[0]);
4583 Py_XDECREF(fileObj[1]);
4584 Py_XDECREF(fileObj[2]);
4585 }
4586
4587 /* Child is launched. */
4588 return f;
4589}
4590
4591/*
4592 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4593 * exit code for the child process and return as a result of the close.
4594 *
4595 * This function uses the _PyPopenProcs dictionary in order to map the
4596 * input file pointer to information about the process that was
4597 * originally created by the popen* call that created the file pointer.
4598 * The dictionary uses the file pointer as a key (with one entry
4599 * inserted for each file returned by the original popen* call) and a
4600 * single list object as the value for all files from a single call.
4601 * The list object contains the Win32 process handle at [0], and a file
4602 * count at [1], which is initialized to the total number of file
4603 * handles using that list.
4604 *
4605 * This function closes whichever handle it is passed, and decrements
4606 * the file count in the dictionary for the process handle pointed to
4607 * by this file. On the last close (when the file count reaches zero),
4608 * this function will wait for the child process and then return its
4609 * exit code as the result of the close() operation. This permits the
4610 * files to be closed in any order - it is always the close() of the
4611 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004612 *
4613 * NOTE: This function is currently called with the GIL released.
4614 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004615 */
4616
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004617static int _PyPclose(FILE *file)
4618{
4619 int result;
4620 int exit_code;
Christian Heimesd491d712008-02-01 18:49:26 +00004621 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004622 PyObject *procObj, *pidObj, *intObj, *fileObj;
4623 int file_count;
4624#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004625 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004626#endif
4627
4628 /* Close the file handle first, to ensure it can't block the
4629 * child from exiting if it's the last handle.
4630 */
4631 result = fclose(file);
4632
4633#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004634 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004635#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004636 if (_PyPopenProcs)
4637 {
4638 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4639 (procObj = PyDict_GetItem(_PyPopenProcs,
4640 fileObj)) != NULL &&
4641 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4642 (intObj = PyList_GetItem(procObj,1)) != NULL)
4643 {
4644 pipe_pid = (int) PyInt_AsLong(pidObj);
4645 file_count = (int) PyInt_AsLong(intObj);
4646
4647 if (file_count > 1)
4648 {
4649 /* Still other files referencing process */
4650 file_count--;
4651 PyList_SetItem(procObj,1,
4652 PyInt_FromLong((long) file_count));
4653 }
4654 else
4655 {
4656 /* Last file for this process */
4657 if (result != EOF &&
4658 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4659 {
4660 /* extract exit status */
4661 if (WIFEXITED(exit_code))
4662 {
4663 result = WEXITSTATUS(exit_code);
4664 }
4665 else
4666 {
4667 errno = EPIPE;
4668 result = -1;
4669 }
4670 }
4671 else
4672 {
4673 /* Indicate failure - this will cause the file object
4674 * to raise an I/O error and translate the last
4675 * error code from errno. We do have a problem with
4676 * last errors that overlap the normal errno table,
4677 * but that's a consistent problem with the file object.
4678 */
4679 result = -1;
4680 }
4681 }
4682
4683 /* Remove this file pointer from dictionary */
4684 PyDict_DelItem(_PyPopenProcs, fileObj);
4685
4686 if (PyDict_Size(_PyPopenProcs) == 0)
4687 {
4688 Py_DECREF(_PyPopenProcs);
4689 _PyPopenProcs = NULL;
4690 }
4691
4692 } /* if object retrieval ok */
4693
4694 Py_XDECREF(fileObj);
4695 } /* if _PyPopenProcs */
4696
4697#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004698 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004699#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004700 return result;
4701}
4702
4703#endif /* PYCC_??? */
4704
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004705#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004706
4707/*
4708 * Portable 'popen' replacement for Win32.
4709 *
4710 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4711 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004712 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004713 */
4714
4715#include <malloc.h>
4716#include <io.h>
4717#include <fcntl.h>
4718
4719/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4720#define POPEN_1 1
4721#define POPEN_2 2
4722#define POPEN_3 3
4723#define POPEN_4 4
4724
4725static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004726static int _PyPclose(FILE *file);
4727
4728/*
4729 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004730 * for use when retrieving the process exit code. See _PyPclose() below
4731 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004732 */
4733static PyObject *_PyPopenProcs = NULL;
4734
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004735
4736/* popen that works from a GUI.
4737 *
4738 * The result of this function is a pipe (file) connected to the
4739 * processes stdin or stdout, depending on the requested mode.
4740 */
4741
4742static PyObject *
4743posix_popen(PyObject *self, PyObject *args)
4744{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004745 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004746 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004747
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004748 char *cmdstring;
4749 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004750 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004751 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004752 return NULL;
4753
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004754 if (*mode == 'r')
4755 tm = _O_RDONLY;
4756 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004757 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004758 return NULL;
4759 } else
4760 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004761
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004762 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004763 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004764 return NULL;
4765 }
4766
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004767 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004768 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004769 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004770 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004771 else
4772 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4773
4774 return f;
4775}
4776
4777/* Variation on win32pipe.popen
4778 *
4779 * The result of this function is a pipe (file) connected to the
4780 * process's stdin, and a pipe connected to the process's stdout.
4781 */
4782
4783static PyObject *
4784win32_popen2(PyObject *self, PyObject *args)
4785{
4786 PyObject *f;
4787 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004788
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004789 char *cmdstring;
4790 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004791 int bufsize = -1;
4792 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004793 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004794
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004795 if (*mode == 't')
4796 tm = _O_TEXT;
4797 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004798 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004799 return NULL;
4800 } else
4801 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004802
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004803 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004804 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004805 return NULL;
4806 }
4807
4808 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004809
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004810 return f;
4811}
4812
4813/*
4814 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004815 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004816 * The result of this function is 3 pipes - the process's stdin,
4817 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004818 */
4819
4820static PyObject *
4821win32_popen3(PyObject *self, PyObject *args)
4822{
4823 PyObject *f;
4824 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004825
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004826 char *cmdstring;
4827 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004828 int bufsize = -1;
4829 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004830 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004831
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004832 if (*mode == 't')
4833 tm = _O_TEXT;
4834 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004835 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004836 return NULL;
4837 } else
4838 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004839
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004840 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004841 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004842 return NULL;
4843 }
4844
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004845 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004846
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004847 return f;
4848}
4849
4850/*
4851 * Variation on win32pipe.popen
4852 *
Tim Peters5aa91602002-01-30 05:46:57 +00004853 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004854 * and stdout+stderr combined as a single pipe.
4855 */
4856
4857static PyObject *
4858win32_popen4(PyObject *self, PyObject *args)
4859{
4860 PyObject *f;
4861 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004862
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004863 char *cmdstring;
4864 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004865 int bufsize = -1;
4866 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004867 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004868
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004869 if (*mode == 't')
4870 tm = _O_TEXT;
4871 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004872 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004873 return NULL;
4874 } else
4875 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004876
4877 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004878 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004879 return NULL;
4880 }
4881
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004882 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004883
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004884 return f;
4885}
4886
Mark Hammond08501372001-01-31 07:30:29 +00004887static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004888_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004889 HANDLE hStdin,
4890 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004891 HANDLE hStderr,
4892 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004893{
4894 PROCESS_INFORMATION piProcInfo;
4895 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004896 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004897 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004898 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004899 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004900 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004901
4902 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004903 char *comshell;
4904
Tim Peters92e4dd82002-10-05 01:47:34 +00004905 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004906 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004907 /* x < i, so x fits into an integer */
4908 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004909
4910 /* Explicitly check if we are using COMMAND.COM. If we are
4911 * then use the w9xpopen hack.
4912 */
4913 comshell = s1 + x;
4914 while (comshell >= s1 && *comshell != '\\')
4915 --comshell;
4916 ++comshell;
4917
4918 if (GetVersion() < 0x80000000 &&
4919 _stricmp(comshell, "command.com") != 0) {
4920 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004921 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004922 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004923 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004924 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004925 }
4926 else {
4927 /*
Tim Peters402d5982001-08-27 06:37:48 +00004928 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4929 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004930 */
Mark Hammond08501372001-01-31 07:30:29 +00004931 char modulepath[_MAX_PATH];
4932 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004933 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Martin v. Löwis26fd9602006-04-22 11:15:41 +00004934 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004935 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004936 x = i+1;
4937 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004938 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004939 strncat(modulepath,
4940 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004941 (sizeof(modulepath)/sizeof(modulepath[0]))
4942 -strlen(modulepath));
4943 if (stat(modulepath, &statinfo) != 0) {
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00004944 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
Tim Peters5aa91602002-01-30 05:46:57 +00004945 /* Eeek - file-not-found - possibly an embedding
4946 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004947 */
Tim Peters5aa91602002-01-30 05:46:57 +00004948 strncpy(modulepath,
4949 Py_GetExecPrefix(),
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00004950 mplen);
4951 modulepath[mplen-1] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004952 if (modulepath[strlen(modulepath)-1] != '\\')
4953 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004954 strncat(modulepath,
4955 szConsoleSpawn,
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00004956 mplen-strlen(modulepath));
Mark Hammond08501372001-01-31 07:30:29 +00004957 /* No where else to look - raise an easily identifiable
4958 error, rather than leaving Windows to report
4959 "file not found" - as the user is probably blissfully
4960 unaware this shim EXE is used, and it will confuse them.
4961 (well, it confused me for a while ;-)
4962 */
4963 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004964 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004965 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004966 "for popen to work with your shell "
4967 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004968 szConsoleSpawn);
4969 return FALSE;
4970 }
4971 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004972 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004973 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004974 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004975
Tim Peters92e4dd82002-10-05 01:47:34 +00004976 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004977 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004978 /* To maintain correct argument passing semantics,
4979 we pass the command-line as it stands, and allow
4980 quoting to be applied. w9xpopen.exe will then
4981 use its argv vector, and re-quote the necessary
4982 args for the ultimate child process.
4983 */
Tim Peters75cdad52001-11-28 22:07:30 +00004984 PyOS_snprintf(
4985 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004986 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004987 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004988 s1,
4989 s3,
4990 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004991 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004992 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004993 dialog:
4994 "Your program accessed mem currently in use at xxx"
4995 and a hopeful warning about the stability of your
4996 system.
4997 Cost is Ctrl+C wont kill children, but anyone
4998 who cares can have a go!
4999 */
5000 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005001 }
5002 }
5003
5004 /* Could be an else here to try cmd.exe / command.com in the path
5005 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00005006 else {
Tim Peters402d5982001-08-27 06:37:48 +00005007 PyErr_SetString(PyExc_RuntimeError,
5008 "Cannot locate a COMSPEC environment variable to "
5009 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00005010 return FALSE;
5011 }
Tim Peters5aa91602002-01-30 05:46:57 +00005012
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005013 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5014 siStartInfo.cb = sizeof(STARTUPINFO);
5015 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5016 siStartInfo.hStdInput = hStdin;
5017 siStartInfo.hStdOutput = hStdout;
5018 siStartInfo.hStdError = hStderr;
5019 siStartInfo.wShowWindow = SW_HIDE;
5020
5021 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005022 s2,
5023 NULL,
5024 NULL,
5025 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005026 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005027 NULL,
5028 NULL,
5029 &siStartInfo,
5030 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005031 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005032 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005033
Mark Hammondb37a3732000-08-14 04:47:33 +00005034 /* Return process handle */
5035 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005036 return TRUE;
5037 }
Tim Peters402d5982001-08-27 06:37:48 +00005038 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005039 return FALSE;
5040}
5041
5042/* The following code is based off of KB: Q190351 */
5043
5044static PyObject *
5045_PyPopen(char *cmdstring, int mode, int n)
5046{
5047 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5048 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00005049 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005050
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005051 SECURITY_ATTRIBUTES saAttr;
5052 BOOL fSuccess;
5053 int fd1, fd2, fd3;
5054 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00005055 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005056 PyObject *f;
5057
5058 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5059 saAttr.bInheritHandle = TRUE;
5060 saAttr.lpSecurityDescriptor = NULL;
5061
5062 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5063 return win32_error("CreatePipe", NULL);
5064
5065 /* Create new output read handle and the input write handle. Set
5066 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005067 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005068 * being created. */
5069 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005070 GetCurrentProcess(), &hChildStdinWrDup, 0,
5071 FALSE,
5072 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005073 if (!fSuccess)
5074 return win32_error("DuplicateHandle", NULL);
5075
5076 /* Close the inheritable version of ChildStdin
5077 that we're using. */
5078 CloseHandle(hChildStdinWr);
5079
5080 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5081 return win32_error("CreatePipe", NULL);
5082
5083 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005084 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5085 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005086 if (!fSuccess)
5087 return win32_error("DuplicateHandle", NULL);
5088
5089 /* Close the inheritable version of ChildStdout
5090 that we're using. */
5091 CloseHandle(hChildStdoutRd);
5092
5093 if (n != POPEN_4) {
5094 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5095 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005096 fSuccess = DuplicateHandle(GetCurrentProcess(),
5097 hChildStderrRd,
5098 GetCurrentProcess(),
5099 &hChildStderrRdDup, 0,
5100 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005101 if (!fSuccess)
5102 return win32_error("DuplicateHandle", NULL);
5103 /* Close the inheritable version of ChildStdErr that we're using. */
5104 CloseHandle(hChildStderrRd);
5105 }
Tim Peters5aa91602002-01-30 05:46:57 +00005106
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005107 switch (n) {
5108 case POPEN_1:
5109 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5110 case _O_WRONLY | _O_TEXT:
5111 /* Case for writing to child Stdin in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005112 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005113 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005114 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005115 PyFile_SetBufSize(f, 0);
5116 /* We don't care about these pipes anymore, so close them. */
5117 CloseHandle(hChildStdoutRdDup);
5118 CloseHandle(hChildStderrRdDup);
5119 break;
5120
5121 case _O_RDONLY | _O_TEXT:
5122 /* Case for reading from child Stdout in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005123 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005124 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005125 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005126 PyFile_SetBufSize(f, 0);
5127 /* We don't care about these pipes anymore, so close them. */
5128 CloseHandle(hChildStdinWrDup);
5129 CloseHandle(hChildStderrRdDup);
5130 break;
5131
5132 case _O_RDONLY | _O_BINARY:
5133 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005134 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005135 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005136 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005137 PyFile_SetBufSize(f, 0);
5138 /* We don't care about these pipes anymore, so close them. */
5139 CloseHandle(hChildStdinWrDup);
5140 CloseHandle(hChildStderrRdDup);
5141 break;
5142
5143 case _O_WRONLY | _O_BINARY:
5144 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005145 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005146 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005147 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005148 PyFile_SetBufSize(f, 0);
5149 /* We don't care about these pipes anymore, so close them. */
5150 CloseHandle(hChildStdoutRdDup);
5151 CloseHandle(hChildStderrRdDup);
5152 break;
5153 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005154 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005155 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005156
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005157 case POPEN_2:
5158 case POPEN_4:
5159 {
5160 char *m1, *m2;
5161 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005162
Tim Peters7dca21e2002-08-19 00:42:29 +00005163 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005164 m1 = "r";
5165 m2 = "w";
5166 } else {
5167 m1 = "rb";
5168 m2 = "wb";
5169 }
5170
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005171 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005172 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005173 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005174 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005175 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005176 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00005177 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005178 PyFile_SetBufSize(p2, 0);
5179
5180 if (n != 4)
5181 CloseHandle(hChildStderrRdDup);
5182
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005183 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00005184 Py_XDECREF(p1);
5185 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00005186 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005187 break;
5188 }
Tim Peters5aa91602002-01-30 05:46:57 +00005189
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005190 case POPEN_3:
5191 {
5192 char *m1, *m2;
5193 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005194
Tim Peters7dca21e2002-08-19 00:42:29 +00005195 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005196 m1 = "r";
5197 m2 = "w";
5198 } else {
5199 m1 = "rb";
5200 m2 = "wb";
5201 }
5202
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005203 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005204 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005205 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005206 f2 = _fdopen(fd2, m1);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005207 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005208 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005209 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00005210 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5211 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005212 PyFile_SetBufSize(p1, 0);
5213 PyFile_SetBufSize(p2, 0);
5214 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005215 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00005216 Py_XDECREF(p1);
5217 Py_XDECREF(p2);
5218 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00005219 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005220 break;
5221 }
5222 }
5223
5224 if (n == POPEN_4) {
5225 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005226 hChildStdinRd,
5227 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005228 hChildStdoutWr,
5229 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005230 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005231 }
5232 else {
5233 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005234 hChildStdinRd,
5235 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005236 hChildStderrWr,
5237 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005238 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005239 }
5240
Mark Hammondb37a3732000-08-14 04:47:33 +00005241 /*
5242 * Insert the files we've created into the process dictionary
5243 * all referencing the list with the process handle and the
5244 * initial number of files (see description below in _PyPclose).
5245 * Since if _PyPclose later tried to wait on a process when all
5246 * handles weren't closed, it could create a deadlock with the
5247 * child, we spend some energy here to try to ensure that we
5248 * either insert all file handles into the dictionary or none
5249 * at all. It's a little clumsy with the various popen modes
5250 * and variable number of files involved.
5251 */
5252 if (!_PyPopenProcs) {
5253 _PyPopenProcs = PyDict_New();
5254 }
5255
5256 if (_PyPopenProcs) {
5257 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5258 int ins_rc[3];
5259
5260 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5261 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
5262
5263 procObj = PyList_New(2);
5264 hProcessObj = PyLong_FromVoidPtr(hProcess);
5265 intObj = PyInt_FromLong(file_count);
5266
5267 if (procObj && hProcessObj && intObj) {
5268 PyList_SetItem(procObj,0,hProcessObj);
5269 PyList_SetItem(procObj,1,intObj);
5270
5271 fileObj[0] = PyLong_FromVoidPtr(f1);
5272 if (fileObj[0]) {
5273 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5274 fileObj[0],
5275 procObj);
5276 }
5277 if (file_count >= 2) {
5278 fileObj[1] = PyLong_FromVoidPtr(f2);
5279 if (fileObj[1]) {
5280 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5281 fileObj[1],
5282 procObj);
5283 }
5284 }
5285 if (file_count >= 3) {
5286 fileObj[2] = PyLong_FromVoidPtr(f3);
5287 if (fileObj[2]) {
5288 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5289 fileObj[2],
5290 procObj);
5291 }
5292 }
5293
5294 if (ins_rc[0] < 0 || !fileObj[0] ||
5295 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5296 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5297 /* Something failed - remove any dictionary
5298 * entries that did make it.
5299 */
5300 if (!ins_rc[0] && fileObj[0]) {
5301 PyDict_DelItem(_PyPopenProcs,
5302 fileObj[0]);
5303 }
5304 if (!ins_rc[1] && fileObj[1]) {
5305 PyDict_DelItem(_PyPopenProcs,
5306 fileObj[1]);
5307 }
5308 if (!ins_rc[2] && fileObj[2]) {
5309 PyDict_DelItem(_PyPopenProcs,
5310 fileObj[2]);
5311 }
5312 }
5313 }
Tim Peters5aa91602002-01-30 05:46:57 +00005314
Mark Hammondb37a3732000-08-14 04:47:33 +00005315 /*
5316 * Clean up our localized references for the dictionary keys
5317 * and value since PyDict_SetItem will Py_INCREF any copies
5318 * that got placed in the dictionary.
5319 */
5320 Py_XDECREF(procObj);
5321 Py_XDECREF(fileObj[0]);
5322 Py_XDECREF(fileObj[1]);
5323 Py_XDECREF(fileObj[2]);
5324 }
5325
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005326 /* Child is launched. Close the parents copy of those pipe
5327 * handles that only the child should have open. You need to
5328 * make sure that no handles to the write end of the output pipe
5329 * are maintained in this process or else the pipe will not close
5330 * when the child process exits and the ReadFile will hang. */
5331
5332 if (!CloseHandle(hChildStdinRd))
5333 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005334
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005335 if (!CloseHandle(hChildStdoutWr))
5336 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005337
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005338 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5339 return win32_error("CloseHandle", NULL);
5340
5341 return f;
5342}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005343
5344/*
5345 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5346 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005347 *
5348 * This function uses the _PyPopenProcs dictionary in order to map the
5349 * input file pointer to information about the process that was
5350 * originally created by the popen* call that created the file pointer.
5351 * The dictionary uses the file pointer as a key (with one entry
5352 * inserted for each file returned by the original popen* call) and a
5353 * single list object as the value for all files from a single call.
5354 * The list object contains the Win32 process handle at [0], and a file
5355 * count at [1], which is initialized to the total number of file
5356 * handles using that list.
5357 *
5358 * This function closes whichever handle it is passed, and decrements
5359 * the file count in the dictionary for the process handle pointed to
5360 * by this file. On the last close (when the file count reaches zero),
5361 * this function will wait for the child process and then return its
5362 * exit code as the result of the close() operation. This permits the
5363 * files to be closed in any order - it is always the close() of the
5364 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005365 *
5366 * NOTE: This function is currently called with the GIL released.
5367 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005368 */
Tim Peters736aa322000-09-01 06:51:24 +00005369
Fredrik Lundh56055a42000-07-23 19:47:12 +00005370static int _PyPclose(FILE *file)
5371{
Fredrik Lundh20318932000-07-26 17:29:12 +00005372 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005373 DWORD exit_code;
5374 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00005375 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5376 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005377#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005378 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005379#endif
5380
Fredrik Lundh20318932000-07-26 17:29:12 +00005381 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00005382 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00005383 */
5384 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005385#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005386 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005387#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005388 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005389 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5390 (procObj = PyDict_GetItem(_PyPopenProcs,
5391 fileObj)) != NULL &&
5392 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5393 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5394
5395 hProcess = PyLong_AsVoidPtr(hProcessObj);
5396 file_count = PyInt_AsLong(intObj);
5397
5398 if (file_count > 1) {
5399 /* Still other files referencing process */
5400 file_count--;
5401 PyList_SetItem(procObj,1,
5402 PyInt_FromLong(file_count));
5403 } else {
5404 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00005405 if (result != EOF &&
5406 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5407 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00005408 /* Possible truncation here in 16-bit environments, but
5409 * real exit codes are just the lower byte in any event.
5410 */
5411 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005412 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00005413 /* Indicate failure - this will cause the file object
5414 * to raise an I/O error and translate the last Win32
5415 * error code from errno. We do have a problem with
5416 * last errors that overlap the normal errno table,
5417 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005418 */
Fredrik Lundh20318932000-07-26 17:29:12 +00005419 if (result != EOF) {
5420 /* If the error wasn't from the fclose(), then
5421 * set errno for the file object error handling.
5422 */
5423 errno = GetLastError();
5424 }
5425 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005426 }
5427
5428 /* Free up the native handle at this point */
5429 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00005430 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005431
Mark Hammondb37a3732000-08-14 04:47:33 +00005432 /* Remove this file pointer from dictionary */
5433 PyDict_DelItem(_PyPopenProcs, fileObj);
5434
5435 if (PyDict_Size(_PyPopenProcs) == 0) {
5436 Py_DECREF(_PyPopenProcs);
5437 _PyPopenProcs = NULL;
5438 }
5439
5440 } /* if object retrieval ok */
5441
5442 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005443 } /* if _PyPopenProcs */
5444
Tim Peters736aa322000-09-01 06:51:24 +00005445#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005446 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005447#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005448 return result;
5449}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005450
5451#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005452static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005453posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005454{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005455 char *name;
5456 char *mode = "r";
5457 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00005458 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005459 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005460 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00005461 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00005462 /* Strip mode of binary or text modifiers */
5463 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5464 mode = "r";
5465 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5466 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00005467 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005468 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005469 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00005470 if (fp == NULL)
5471 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005472 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005473 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005474 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005475 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005476}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005477
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005478#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005479#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005480
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005481
Guido van Rossumb6775db1994-08-01 11:34:53 +00005482#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005483PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005484"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005485Set the current process's user id.");
5486
Barry Warsaw53699e91996-12-10 23:23:01 +00005487static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005488posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005489{
5490 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005491 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005492 return NULL;
5493 if (setuid(uid) < 0)
5494 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005495 Py_INCREF(Py_None);
5496 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005497}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005498#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005499
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005500
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005501#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005502PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005503"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005504Set the current process's effective user id.");
5505
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005506static PyObject *
5507posix_seteuid (PyObject *self, PyObject *args)
5508{
5509 int euid;
5510 if (!PyArg_ParseTuple(args, "i", &euid)) {
5511 return NULL;
5512 } else if (seteuid(euid) < 0) {
5513 return posix_error();
5514 } else {
5515 Py_INCREF(Py_None);
5516 return Py_None;
5517 }
5518}
5519#endif /* HAVE_SETEUID */
5520
5521#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005522PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005523"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005524Set the current process's effective group id.");
5525
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005526static PyObject *
5527posix_setegid (PyObject *self, PyObject *args)
5528{
5529 int egid;
5530 if (!PyArg_ParseTuple(args, "i", &egid)) {
5531 return NULL;
5532 } else if (setegid(egid) < 0) {
5533 return posix_error();
5534 } else {
5535 Py_INCREF(Py_None);
5536 return Py_None;
5537 }
5538}
5539#endif /* HAVE_SETEGID */
5540
5541#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005542PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005543"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005544Set the current process's real and effective user ids.");
5545
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005546static PyObject *
5547posix_setreuid (PyObject *self, PyObject *args)
5548{
5549 int ruid, euid;
5550 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
5551 return NULL;
5552 } else if (setreuid(ruid, euid) < 0) {
5553 return posix_error();
5554 } else {
5555 Py_INCREF(Py_None);
5556 return Py_None;
5557 }
5558}
5559#endif /* HAVE_SETREUID */
5560
5561#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005562PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005563"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005564Set the current process's real and effective group ids.");
5565
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005566static PyObject *
5567posix_setregid (PyObject *self, PyObject *args)
5568{
5569 int rgid, egid;
5570 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
5571 return NULL;
5572 } else if (setregid(rgid, egid) < 0) {
5573 return posix_error();
5574 } else {
5575 Py_INCREF(Py_None);
5576 return Py_None;
5577 }
5578}
5579#endif /* HAVE_SETREGID */
5580
Guido van Rossumb6775db1994-08-01 11:34:53 +00005581#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005582PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005583"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005584Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005585
Barry Warsaw53699e91996-12-10 23:23:01 +00005586static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005587posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005588{
5589 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005590 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005591 return NULL;
5592 if (setgid(gid) < 0)
5593 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005594 Py_INCREF(Py_None);
5595 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005596}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005597#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005598
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005599#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005600PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005601"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005602Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005603
5604static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005605posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005606{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005607 int i, len;
5608 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005609
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005610 if (!PySequence_Check(groups)) {
5611 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5612 return NULL;
5613 }
5614 len = PySequence_Size(groups);
5615 if (len > MAX_GROUPS) {
5616 PyErr_SetString(PyExc_ValueError, "too many groups");
5617 return NULL;
5618 }
5619 for(i = 0; i < len; i++) {
5620 PyObject *elem;
5621 elem = PySequence_GetItem(groups, i);
5622 if (!elem)
5623 return NULL;
5624 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005625 if (!PyLong_Check(elem)) {
5626 PyErr_SetString(PyExc_TypeError,
5627 "groups must be integers");
5628 Py_DECREF(elem);
5629 return NULL;
5630 } else {
5631 unsigned long x = PyLong_AsUnsignedLong(elem);
5632 if (PyErr_Occurred()) {
5633 PyErr_SetString(PyExc_TypeError,
5634 "group id too big");
5635 Py_DECREF(elem);
5636 return NULL;
5637 }
5638 grouplist[i] = x;
5639 /* read back the value to see if it fitted in gid_t */
5640 if (grouplist[i] != x) {
5641 PyErr_SetString(PyExc_TypeError,
5642 "group id too big");
5643 Py_DECREF(elem);
5644 return NULL;
5645 }
5646 }
5647 } else {
5648 long x = PyInt_AsLong(elem);
5649 grouplist[i] = x;
5650 if (grouplist[i] != x) {
5651 PyErr_SetString(PyExc_TypeError,
5652 "group id too big");
5653 Py_DECREF(elem);
5654 return NULL;
5655 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005656 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005657 Py_DECREF(elem);
5658 }
5659
5660 if (setgroups(len, grouplist) < 0)
5661 return posix_error();
5662 Py_INCREF(Py_None);
5663 return Py_None;
5664}
5665#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005666
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005667#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005668static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00005669wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00005670{
5671 PyObject *result;
5672 static PyObject *struct_rusage;
5673
5674 if (pid == -1)
5675 return posix_error();
5676
5677 if (struct_rusage == NULL) {
Christian Heimes000a0742008-01-03 22:16:32 +00005678 PyObject *m = PyImport_ImportModuleNoBlock("resource");
Neal Norwitz05a45592006-03-20 06:30:08 +00005679 if (m == NULL)
5680 return NULL;
5681 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5682 Py_DECREF(m);
5683 if (struct_rusage == NULL)
5684 return NULL;
5685 }
5686
5687 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5688 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5689 if (!result)
5690 return NULL;
5691
5692#ifndef doubletime
5693#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5694#endif
5695
5696 PyStructSequence_SET_ITEM(result, 0,
5697 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5698 PyStructSequence_SET_ITEM(result, 1,
5699 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5700#define SET_INT(result, index, value)\
5701 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5702 SET_INT(result, 2, ru->ru_maxrss);
5703 SET_INT(result, 3, ru->ru_ixrss);
5704 SET_INT(result, 4, ru->ru_idrss);
5705 SET_INT(result, 5, ru->ru_isrss);
5706 SET_INT(result, 6, ru->ru_minflt);
5707 SET_INT(result, 7, ru->ru_majflt);
5708 SET_INT(result, 8, ru->ru_nswap);
5709 SET_INT(result, 9, ru->ru_inblock);
5710 SET_INT(result, 10, ru->ru_oublock);
5711 SET_INT(result, 11, ru->ru_msgsnd);
5712 SET_INT(result, 12, ru->ru_msgrcv);
5713 SET_INT(result, 13, ru->ru_nsignals);
5714 SET_INT(result, 14, ru->ru_nvcsw);
5715 SET_INT(result, 15, ru->ru_nivcsw);
5716#undef SET_INT
5717
5718 if (PyErr_Occurred()) {
5719 Py_DECREF(result);
5720 return NULL;
5721 }
5722
Neal Norwitz9b00a562006-03-20 08:47:12 +00005723 return Py_BuildValue("iiN", pid, status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005724}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005725#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005726
5727#ifdef HAVE_WAIT3
5728PyDoc_STRVAR(posix_wait3__doc__,
5729"wait3(options) -> (pid, status, rusage)\n\n\
5730Wait for completion of a child process.");
5731
5732static PyObject *
5733posix_wait3(PyObject *self, PyObject *args)
5734{
Christian Heimesd491d712008-02-01 18:49:26 +00005735 pid_t pid;
5736 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005737 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005738 WAIT_TYPE status;
5739 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005740
5741 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5742 return NULL;
5743
5744 Py_BEGIN_ALLOW_THREADS
5745 pid = wait3(&status, options, &ru);
5746 Py_END_ALLOW_THREADS
5747
Neal Norwitzd5a37542006-03-20 06:48:34 +00005748 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005749}
5750#endif /* HAVE_WAIT3 */
5751
5752#ifdef HAVE_WAIT4
5753PyDoc_STRVAR(posix_wait4__doc__,
5754"wait4(pid, options) -> (pid, status, rusage)\n\n\
5755Wait for completion of a given child process.");
5756
5757static PyObject *
5758posix_wait4(PyObject *self, PyObject *args)
5759{
Christian Heimesd491d712008-02-01 18:49:26 +00005760 pid_t pid;
5761 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005762 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005763 WAIT_TYPE status;
5764 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005765
5766 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5767 return NULL;
5768
5769 Py_BEGIN_ALLOW_THREADS
5770 pid = wait4(pid, &status, options, &ru);
5771 Py_END_ALLOW_THREADS
5772
Neal Norwitzd5a37542006-03-20 06:48:34 +00005773 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005774}
5775#endif /* HAVE_WAIT4 */
5776
Guido van Rossumb6775db1994-08-01 11:34:53 +00005777#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005778PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005779"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005780Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005781
Barry Warsaw53699e91996-12-10 23:23:01 +00005782static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005783posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005784{
Christian Heimesd491d712008-02-01 18:49:26 +00005785 pid_t pid;
5786 int options;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005787 WAIT_TYPE status;
5788 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005789
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005790 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005791 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005792 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005793 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005794 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005795 if (pid == -1)
5796 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005797
5798 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005799}
5800
Tim Petersab034fa2002-02-01 11:27:43 +00005801#elif defined(HAVE_CWAIT)
5802
5803/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005804PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005805"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005806"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005807
5808static PyObject *
5809posix_waitpid(PyObject *self, PyObject *args)
5810{
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005811 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005812 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005813
5814 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5815 return NULL;
5816 Py_BEGIN_ALLOW_THREADS
5817 pid = _cwait(&status, pid, options);
5818 Py_END_ALLOW_THREADS
5819 if (pid == -1)
5820 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005821
5822 /* shift the status left a byte so this is more like the POSIX waitpid */
5823 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005824}
5825#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005826
Guido van Rossumad0ee831995-03-01 10:34:45 +00005827#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005828PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005829"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005830Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005831
Barry Warsaw53699e91996-12-10 23:23:01 +00005832static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005833posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005834{
Christian Heimesd491d712008-02-01 18:49:26 +00005835 pid_t pid;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005836 WAIT_TYPE status;
5837 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005838
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005839 Py_BEGIN_ALLOW_THREADS
5840 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005841 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005842 if (pid == -1)
5843 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005844
5845 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005846}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005847#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005848
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005849
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005850PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005851"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005852Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005853
Barry Warsaw53699e91996-12-10 23:23:01 +00005854static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005855posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005856{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005857#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005858 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005859#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005860#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005861 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005862#else
5863 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5864#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005865#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005866}
5867
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005868
Guido van Rossumb6775db1994-08-01 11:34:53 +00005869#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005870PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005871"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005872Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005873
Barry Warsaw53699e91996-12-10 23:23:01 +00005874static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005875posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005876{
Ronald Oussoren10168f22006-10-22 10:45:18 +00005877 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005878 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005879 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005880 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00005881#ifdef Py_USING_UNICODE
5882 int arg_is_unicode = 0;
5883#endif
5884
5885 if (!PyArg_ParseTuple(args, "et:readlink",
5886 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005887 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00005888#ifdef Py_USING_UNICODE
5889 v = PySequence_GetItem(args, 0);
Neal Norwitz91a57212007-08-12 17:11:13 +00005890 if (v == NULL) {
5891 PyMem_Free(path);
5892 return NULL;
5893 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00005894
5895 if (PyUnicode_Check(v)) {
5896 arg_is_unicode = 1;
5897 }
5898 Py_DECREF(v);
5899#endif
5900
Barry Warsaw53699e91996-12-10 23:23:01 +00005901 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005902 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005903 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005904 if (n < 0)
Neal Norwitz91a57212007-08-12 17:11:13 +00005905 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00005906
Neal Norwitz91a57212007-08-12 17:11:13 +00005907 PyMem_Free(path);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00005908 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00005909#ifdef Py_USING_UNICODE
5910 if (arg_is_unicode) {
5911 PyObject *w;
5912
5913 w = PyUnicode_FromEncodedObject(v,
5914 Py_FileSystemDefaultEncoding,
5915 "strict");
5916 if (w != NULL) {
5917 Py_DECREF(v);
5918 v = w;
5919 }
5920 else {
5921 /* fall back to the original byte string, as
5922 discussed in patch #683592 */
5923 PyErr_Clear();
5924 }
5925 }
5926#endif
5927 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005928}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005929#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005930
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005931
Guido van Rossumb6775db1994-08-01 11:34:53 +00005932#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005933PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005934"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005935Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005936
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005937static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005938posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005939{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00005940 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005941}
5942#endif /* HAVE_SYMLINK */
5943
5944
5945#ifdef HAVE_TIMES
5946#ifndef HZ
5947#define HZ 60 /* Universal constant :-) */
5948#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005949
Guido van Rossumd48f2521997-12-05 22:19:34 +00005950#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5951static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005952system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005953{
5954 ULONG value = 0;
5955
5956 Py_BEGIN_ALLOW_THREADS
5957 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5958 Py_END_ALLOW_THREADS
5959
5960 return value;
5961}
5962
5963static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005964posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005965{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005966 /* Currently Only Uptime is Provided -- Others Later */
5967 return Py_BuildValue("ddddd",
5968 (double)0 /* t.tms_utime / HZ */,
5969 (double)0 /* t.tms_stime / HZ */,
5970 (double)0 /* t.tms_cutime / HZ */,
5971 (double)0 /* t.tms_cstime / HZ */,
5972 (double)system_uptime() / 1000);
5973}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005974#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005975static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005976posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005977{
5978 struct tms t;
5979 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005980 errno = 0;
5981 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005982 if (c == (clock_t) -1)
5983 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005984 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005985 (double)t.tms_utime / HZ,
5986 (double)t.tms_stime / HZ,
5987 (double)t.tms_cutime / HZ,
5988 (double)t.tms_cstime / HZ,
5989 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005990}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005991#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005992#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005993
5994
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005995#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005996#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005997static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005998posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005999{
6000 FILETIME create, exit, kernel, user;
6001 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006002 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006003 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6004 /* The fields of a FILETIME structure are the hi and lo part
6005 of a 64-bit value expressed in 100 nanosecond units.
6006 1e7 is one second in such units; 1e-7 the inverse.
6007 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6008 */
Barry Warsaw53699e91996-12-10 23:23:01 +00006009 return Py_BuildValue(
6010 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006011 (double)(user.dwHighDateTime*429.4967296 +
6012 user.dwLowDateTime*1e-7),
Georg Brandl0a40ffb2008-02-13 07:20:22 +00006013 (double)(kernel.dwHighDateTime*429.4967296 +
6014 kernel.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00006015 (double)0,
6016 (double)0,
6017 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006018}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006019#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006020
6021#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006022PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006023"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006024Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006025#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006026
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006027
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006028#ifdef HAVE_GETSID
6029PyDoc_STRVAR(posix_getsid__doc__,
6030"getsid(pid) -> sid\n\n\
6031Call the system call getsid().");
6032
6033static PyObject *
6034posix_getsid(PyObject *self, PyObject *args)
6035{
Christian Heimesd491d712008-02-01 18:49:26 +00006036 pid_t pid;
6037 int sid;
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006038 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
6039 return NULL;
6040 sid = getsid(pid);
6041 if (sid < 0)
6042 return posix_error();
6043 return PyInt_FromLong((long)sid);
6044}
6045#endif /* HAVE_GETSID */
6046
6047
Guido van Rossumb6775db1994-08-01 11:34:53 +00006048#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006049PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006050"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006051Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006052
Barry Warsaw53699e91996-12-10 23:23:01 +00006053static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006054posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006055{
Guido van Rossum687dd131993-05-17 08:34:16 +00006056 if (setsid() < 0)
6057 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006058 Py_INCREF(Py_None);
6059 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006060}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006061#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006062
Guido van Rossumb6775db1994-08-01 11:34:53 +00006063#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006064PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006065"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006066Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006067
Barry Warsaw53699e91996-12-10 23:23:01 +00006068static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006069posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006070{
Christian Heimesd491d712008-02-01 18:49:26 +00006071 pid_t pid;
6072 int pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006073 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00006074 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006075 if (setpgid(pid, pgrp) < 0)
6076 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006077 Py_INCREF(Py_None);
6078 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006079}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006080#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006081
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006082
Guido van Rossumb6775db1994-08-01 11:34:53 +00006083#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006084PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006085"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006086Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006087
Barry Warsaw53699e91996-12-10 23:23:01 +00006088static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006089posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006090{
Christian Heimese6a80742008-02-03 19:51:13 +00006091 int fd;
6092 pid_t pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006093 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006094 return NULL;
6095 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006096 if (pgid < 0)
6097 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006098 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006099}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006100#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006101
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006102
Guido van Rossumb6775db1994-08-01 11:34:53 +00006103#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006104PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006105"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006106Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006107
Barry Warsaw53699e91996-12-10 23:23:01 +00006108static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006109posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006110{
6111 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006112 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006113 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006114 if (tcsetpgrp(fd, pgid) < 0)
6115 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00006116 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00006117 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006118}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006119#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006120
Guido van Rossum687dd131993-05-17 08:34:16 +00006121/* Functions acting on file descriptors */
6122
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006123PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006124"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006125Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006126
Barry Warsaw53699e91996-12-10 23:23:01 +00006127static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006128posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006129{
Mark Hammondef8b6542001-05-13 08:04:26 +00006130 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006131 int flag;
6132 int mode = 0777;
6133 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006134
6135#ifdef MS_WINDOWS
6136 if (unicode_file_names()) {
6137 PyUnicodeObject *po;
6138 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6139 Py_BEGIN_ALLOW_THREADS
6140 /* PyUnicode_AS_UNICODE OK without thread
6141 lock as it is a simple dereference. */
6142 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6143 Py_END_ALLOW_THREADS
6144 if (fd < 0)
6145 return posix_error();
6146 return PyInt_FromLong((long)fd);
6147 }
6148 /* Drop the argument parsing error as narrow strings
6149 are also valid. */
6150 PyErr_Clear();
6151 }
6152#endif
6153
Tim Peters5aa91602002-01-30 05:46:57 +00006154 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00006155 Py_FileSystemDefaultEncoding, &file,
6156 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00006157 return NULL;
6158
Barry Warsaw53699e91996-12-10 23:23:01 +00006159 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006160 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00006161 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006162 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00006163 return posix_error_with_allocated_filename(file);
6164 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00006165 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006166}
6167
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006168
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006169PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006170"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006171Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006172
Barry Warsaw53699e91996-12-10 23:23:01 +00006173static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006174posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006175{
6176 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006177 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006178 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006179 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006180 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006181 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006182 if (res < 0)
6183 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006184 Py_INCREF(Py_None);
6185 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006186}
6187
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006188
Georg Brandl309501a2008-01-19 20:22:13 +00006189PyDoc_STRVAR(posix_closerange__doc__,
6190"closerange(fd_low, fd_high)\n\n\
6191Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6192
6193static PyObject *
6194posix_closerange(PyObject *self, PyObject *args)
6195{
6196 int fd_from, fd_to, i;
6197 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6198 return NULL;
6199 Py_BEGIN_ALLOW_THREADS
6200 for (i = fd_from; i < fd_to; i++)
6201 close(i);
6202 Py_END_ALLOW_THREADS
6203 Py_RETURN_NONE;
6204}
6205
6206
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006207PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006208"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006209Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006210
Barry Warsaw53699e91996-12-10 23:23:01 +00006211static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006212posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006213{
6214 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006215 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006216 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006217 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006218 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006219 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006220 if (fd < 0)
6221 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006222 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006223}
6224
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006225
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006226PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006227"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006228Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006229
Barry Warsaw53699e91996-12-10 23:23:01 +00006230static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006231posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006232{
6233 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006234 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00006235 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006236 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006237 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00006238 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006239 if (res < 0)
6240 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006241 Py_INCREF(Py_None);
6242 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006243}
6244
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006245
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006246PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006247"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006248Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006249
Barry Warsaw53699e91996-12-10 23:23:01 +00006250static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006251posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006252{
6253 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006254#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006255 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006256#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00006257 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006258#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006259 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006260 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00006261 return NULL;
6262#ifdef SEEK_SET
6263 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6264 switch (how) {
6265 case 0: how = SEEK_SET; break;
6266 case 1: how = SEEK_CUR; break;
6267 case 2: how = SEEK_END; break;
6268 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006269#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006270
6271#if !defined(HAVE_LARGEFILE_SUPPORT)
6272 pos = PyInt_AsLong(posobj);
6273#else
6274 pos = PyLong_Check(posobj) ?
6275 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
6276#endif
6277 if (PyErr_Occurred())
6278 return NULL;
6279
Barry Warsaw53699e91996-12-10 23:23:01 +00006280 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006281#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00006282 res = _lseeki64(fd, pos, how);
6283#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006284 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006285#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006286 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006287 if (res < 0)
6288 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006289
6290#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00006291 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006292#else
6293 return PyLong_FromLongLong(res);
6294#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006295}
6296
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006297
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006298PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006299"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006300Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006301
Barry Warsaw53699e91996-12-10 23:23:01 +00006302static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006303posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006304{
Guido van Rossum8bac5461996-06-11 18:38:48 +00006305 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00006306 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006307 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00006308 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00006309 if (size < 0) {
6310 errno = EINVAL;
6311 return posix_error();
6312 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006313 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006314 if (buffer == NULL)
6315 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006316 Py_BEGIN_ALLOW_THREADS
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006317 n = read(fd, PyString_AsString(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00006318 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00006319 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006320 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00006321 return posix_error();
6322 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00006323 if (n != size)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006324 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00006325 return buffer;
6326}
6327
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006328
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006329PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006330"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006331Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006332
Barry Warsaw53699e91996-12-10 23:23:01 +00006333static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006334posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006335{
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006336 Py_buffer pbuf;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006337 int fd;
6338 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006339
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006340 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
Guido van Rossum687dd131993-05-17 08:34:16 +00006341 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006342 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006343 size = write(fd, pbuf.buf, (size_t)pbuf.len);
Barry Warsaw53699e91996-12-10 23:23:01 +00006344 Py_END_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006345 PyBuffer_Release(&pbuf);
Guido van Rossum687dd131993-05-17 08:34:16 +00006346 if (size < 0)
6347 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006348 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006349}
6350
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006351
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006352PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006353"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006354Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006355
Barry Warsaw53699e91996-12-10 23:23:01 +00006356static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006357posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006358{
6359 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00006360 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00006361 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006362 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006363 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006364#ifdef __VMS
6365 /* on OpenVMS we must ensure that all bytes are written to the file */
6366 fsync(fd);
6367#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006368 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00006369 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00006370 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00006371 if (res != 0) {
6372#ifdef MS_WINDOWS
6373 return win32_error("fstat", NULL);
6374#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006375 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006376#endif
6377 }
Tim Peters5aa91602002-01-30 05:46:57 +00006378
Martin v. Löwis14694662006-02-03 12:54:16 +00006379 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006380}
6381
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006382
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006383PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006384"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006385Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006386
Barry Warsaw53699e91996-12-10 23:23:01 +00006387static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006388posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006389{
Guido van Rossum687dd131993-05-17 08:34:16 +00006390 int fd;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006391 char *orgmode = "r";
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006392 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00006393 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00006394 PyObject *f;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006395 char *mode;
6396 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00006397 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006398
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006399 /* Sanitize mode. See fileobject.c */
6400 mode = PyMem_MALLOC(strlen(orgmode)+3);
6401 if (!mode) {
6402 PyErr_NoMemory();
6403 return NULL;
6404 }
6405 strcpy(mode, orgmode);
6406 if (_PyFile_SanitizeMode(mode)) {
6407 PyMem_FREE(mode);
Thomas Heller1f043e22002-11-07 16:00:59 +00006408 return NULL;
6409 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006410 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006411#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Georg Brandl54a188a2006-03-31 20:00:11 +00006412 if (mode[0] == 'a') {
6413 /* try to make sure the O_APPEND flag is set */
6414 int flags;
6415 flags = fcntl(fd, F_GETFL);
6416 if (flags != -1)
6417 fcntl(fd, F_SETFL, flags | O_APPEND);
6418 fp = fdopen(fd, mode);
Thomas Wouters2a9a6b02006-03-31 22:38:19 +00006419 if (fp == NULL && flags != -1)
Georg Brandl54a188a2006-03-31 20:00:11 +00006420 /* restore old mode if fdopen failed */
6421 fcntl(fd, F_SETFL, flags);
6422 } else {
6423 fp = fdopen(fd, mode);
6424 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006425#else
6426 fp = fdopen(fd, mode);
6427#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006428 Py_END_ALLOW_THREADS
Neal Norwitzd83eb312007-05-02 04:47:55 +00006429 PyMem_FREE(mode);
Guido van Rossum687dd131993-05-17 08:34:16 +00006430 if (fp == NULL)
6431 return posix_error();
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006432 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006433 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00006434 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006435 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006436}
6437
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006438PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006439"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006440Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006441connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006442
6443static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006444posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006445{
6446 int fd;
6447 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6448 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006449 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006450}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006451
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006452#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006453PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006454"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006455Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006456
Barry Warsaw53699e91996-12-10 23:23:01 +00006457static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006458posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006459{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006460#if defined(PYOS_OS2)
6461 HFILE read, write;
6462 APIRET rc;
6463
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006464 Py_BEGIN_ALLOW_THREADS
6465 rc = DosCreatePipe( &read, &write, 4096);
6466 Py_END_ALLOW_THREADS
6467 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006468 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006469
6470 return Py_BuildValue("(ii)", read, write);
6471#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006472#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00006473 int fds[2];
6474 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00006475 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006476 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00006477 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006478 if (res != 0)
6479 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006480 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006481#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00006482 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006483 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00006484 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00006485 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006486 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00006487 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00006488 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006489 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00006490 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6491 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006492 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006493#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006494#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006495}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006496#endif /* HAVE_PIPE */
6497
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006498
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006499#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006500PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006501"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006502Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006503
Barry Warsaw53699e91996-12-10 23:23:01 +00006504static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006505posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006506{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006507 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006508 int mode = 0666;
6509 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006510 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006511 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006512 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006513 res = mkfifo(filename, mode);
6514 Py_END_ALLOW_THREADS
6515 if (res < 0)
6516 return posix_error();
6517 Py_INCREF(Py_None);
6518 return Py_None;
6519}
6520#endif
6521
6522
Neal Norwitz11690112002-07-30 01:08:28 +00006523#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006524PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006525"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006526Create a filesystem node (file, device special file or named pipe)\n\
6527named filename. mode specifies both the permissions to use and the\n\
6528type of node to be created, being combined (bitwise OR) with one of\n\
6529S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006530device defines the newly created device special file (probably using\n\
6531os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006532
6533
6534static PyObject *
6535posix_mknod(PyObject *self, PyObject *args)
6536{
6537 char *filename;
6538 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006539 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006540 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00006541 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006542 return NULL;
6543 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006544 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00006545 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006546 if (res < 0)
6547 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006548 Py_INCREF(Py_None);
6549 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006550}
6551#endif
6552
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006553#ifdef HAVE_DEVICE_MACROS
6554PyDoc_STRVAR(posix_major__doc__,
6555"major(device) -> major number\n\
6556Extracts a device major number from a raw device number.");
6557
6558static PyObject *
6559posix_major(PyObject *self, PyObject *args)
6560{
6561 int device;
6562 if (!PyArg_ParseTuple(args, "i:major", &device))
6563 return NULL;
6564 return PyInt_FromLong((long)major(device));
6565}
6566
6567PyDoc_STRVAR(posix_minor__doc__,
6568"minor(device) -> minor number\n\
6569Extracts a device minor number from a raw device number.");
6570
6571static PyObject *
6572posix_minor(PyObject *self, PyObject *args)
6573{
6574 int device;
6575 if (!PyArg_ParseTuple(args, "i:minor", &device))
6576 return NULL;
6577 return PyInt_FromLong((long)minor(device));
6578}
6579
6580PyDoc_STRVAR(posix_makedev__doc__,
6581"makedev(major, minor) -> device number\n\
6582Composes a raw device number from the major and minor device numbers.");
6583
6584static PyObject *
6585posix_makedev(PyObject *self, PyObject *args)
6586{
6587 int major, minor;
6588 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6589 return NULL;
6590 return PyInt_FromLong((long)makedev(major, minor));
6591}
6592#endif /* device macros */
6593
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006594
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006595#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006596PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006597"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006598Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006599
Barry Warsaw53699e91996-12-10 23:23:01 +00006600static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006601posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006602{
6603 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006604 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006605 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006606 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006607
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006608 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006609 return NULL;
6610
6611#if !defined(HAVE_LARGEFILE_SUPPORT)
6612 length = PyInt_AsLong(lenobj);
6613#else
6614 length = PyLong_Check(lenobj) ?
6615 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6616#endif
6617 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006618 return NULL;
6619
Barry Warsaw53699e91996-12-10 23:23:01 +00006620 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006621 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006622 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006623 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006624 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006625 return NULL;
6626 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006627 Py_INCREF(Py_None);
6628 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006629}
6630#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006631
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006632#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006633PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006634"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006635Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006636
Fred Drake762e2061999-08-26 17:23:54 +00006637/* Save putenv() parameters as values here, so we can collect them when they
6638 * get re-set with another call for the same key. */
6639static PyObject *posix_putenv_garbage;
6640
Tim Peters5aa91602002-01-30 05:46:57 +00006641static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006642posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006643{
6644 char *s1, *s2;
Anthony Baxter64182fe2006-04-11 12:14:09 +00006645 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006646 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006647 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006648
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006649 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006650 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006651
6652#if defined(PYOS_OS2)
6653 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6654 APIRET rc;
6655
Guido van Rossumd48f2521997-12-05 22:19:34 +00006656 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6657 if (rc != NO_ERROR)
6658 return os2_error(rc);
6659
6660 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6661 APIRET rc;
6662
Guido van Rossumd48f2521997-12-05 22:19:34 +00006663 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6664 if (rc != NO_ERROR)
6665 return os2_error(rc);
6666 } else {
6667#endif
6668
Fred Drake762e2061999-08-26 17:23:54 +00006669 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006670 len = strlen(s1) + strlen(s2) + 2;
6671 /* len includes space for a trailing \0; the size arg to
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006672 PyString_FromStringAndSize does not count that */
6673 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006674 if (newstr == NULL)
6675 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006676 newenv = PyString_AS_STRING(newstr);
Anthony Baxter64182fe2006-04-11 12:14:09 +00006677 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6678 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006679 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006680 posix_error();
6681 return NULL;
6682 }
Fred Drake762e2061999-08-26 17:23:54 +00006683 /* Install the first arg and newstr in posix_putenv_garbage;
6684 * this will cause previous value to be collected. This has to
6685 * happen after the real putenv() call because the old value
6686 * was still accessible until then. */
6687 if (PyDict_SetItem(posix_putenv_garbage,
6688 PyTuple_GET_ITEM(args, 0), newstr)) {
6689 /* really not much we can do; just leak */
6690 PyErr_Clear();
6691 }
6692 else {
6693 Py_DECREF(newstr);
6694 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006695
6696#if defined(PYOS_OS2)
6697 }
6698#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006699 Py_INCREF(Py_None);
6700 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006701}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006702#endif /* putenv */
6703
Guido van Rossumc524d952001-10-19 01:31:59 +00006704#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006705PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006706"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006707Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006708
6709static PyObject *
6710posix_unsetenv(PyObject *self, PyObject *args)
6711{
6712 char *s1;
6713
6714 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6715 return NULL;
6716
6717 unsetenv(s1);
6718
6719 /* Remove the key from posix_putenv_garbage;
6720 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006721 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006722 * old value was still accessible until then.
6723 */
6724 if (PyDict_DelItem(posix_putenv_garbage,
6725 PyTuple_GET_ITEM(args, 0))) {
6726 /* really not much we can do; just leak */
6727 PyErr_Clear();
6728 }
6729
6730 Py_INCREF(Py_None);
6731 return Py_None;
6732}
6733#endif /* unsetenv */
6734
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006735PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006736"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006737Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006738
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006739static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006740posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006741{
6742 int code;
6743 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006744 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006745 return NULL;
6746 message = strerror(code);
6747 if (message == NULL) {
6748 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006749 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006750 return NULL;
6751 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006752 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006753}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006754
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006755
Guido van Rossumc9641791998-08-04 15:26:23 +00006756#ifdef HAVE_SYS_WAIT_H
6757
Fred Drake106c1a02002-04-23 15:58:02 +00006758#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006759PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006760"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006761Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006762
6763static PyObject *
6764posix_WCOREDUMP(PyObject *self, PyObject *args)
6765{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006766 WAIT_TYPE status;
6767 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006768
Neal Norwitzd5a37542006-03-20 06:48:34 +00006769 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006770 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006771
6772 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006773}
6774#endif /* WCOREDUMP */
6775
6776#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006777PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006778"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006779Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006780job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006781
6782static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006783posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006784{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006785 WAIT_TYPE status;
6786 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006787
Neal Norwitzd5a37542006-03-20 06:48:34 +00006788 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006789 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006790
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006791 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006792}
6793#endif /* WIFCONTINUED */
6794
Guido van Rossumc9641791998-08-04 15:26:23 +00006795#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006796PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006797"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006798Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006799
6800static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006801posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006802{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006803 WAIT_TYPE status;
6804 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006805
Neal Norwitzd5a37542006-03-20 06:48:34 +00006806 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006807 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006808
Fred Drake106c1a02002-04-23 15:58:02 +00006809 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006810}
6811#endif /* WIFSTOPPED */
6812
6813#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006814PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006815"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006816Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006817
6818static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006819posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006820{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006821 WAIT_TYPE status;
6822 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006823
Neal Norwitzd5a37542006-03-20 06:48:34 +00006824 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006825 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006826
Fred Drake106c1a02002-04-23 15:58:02 +00006827 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006828}
6829#endif /* WIFSIGNALED */
6830
6831#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006832PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006833"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006834Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006835system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006836
6837static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006838posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006839{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006840 WAIT_TYPE status;
6841 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006842
Neal Norwitzd5a37542006-03-20 06:48:34 +00006843 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006844 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006845
Fred Drake106c1a02002-04-23 15:58:02 +00006846 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006847}
6848#endif /* WIFEXITED */
6849
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006850#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006851PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006852"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006853Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006854
6855static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006856posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006857{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006858 WAIT_TYPE status;
6859 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006860
Neal Norwitzd5a37542006-03-20 06:48:34 +00006861 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006862 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006863
Guido van Rossumc9641791998-08-04 15:26:23 +00006864 return Py_BuildValue("i", WEXITSTATUS(status));
6865}
6866#endif /* WEXITSTATUS */
6867
6868#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006869PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006870"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006871Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006872value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006873
6874static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006875posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006876{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006877 WAIT_TYPE status;
6878 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006879
Neal Norwitzd5a37542006-03-20 06:48:34 +00006880 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006881 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006882
Guido van Rossumc9641791998-08-04 15:26:23 +00006883 return Py_BuildValue("i", WTERMSIG(status));
6884}
6885#endif /* WTERMSIG */
6886
6887#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006888PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006889"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006890Return the signal that stopped the process that provided\n\
6891the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006892
6893static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006894posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006895{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006896 WAIT_TYPE status;
6897 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006898
Neal Norwitzd5a37542006-03-20 06:48:34 +00006899 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006900 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006901
Guido van Rossumc9641791998-08-04 15:26:23 +00006902 return Py_BuildValue("i", WSTOPSIG(status));
6903}
6904#endif /* WSTOPSIG */
6905
6906#endif /* HAVE_SYS_WAIT_H */
6907
6908
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006909#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006910#ifdef _SCO_DS
6911/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6912 needed definitions in sys/statvfs.h */
6913#define _SVID3
6914#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006915#include <sys/statvfs.h>
6916
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006917static PyObject*
6918_pystatvfs_fromstructstatvfs(struct statvfs st) {
6919 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6920 if (v == NULL)
6921 return NULL;
6922
6923#if !defined(HAVE_LARGEFILE_SUPPORT)
6924 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6925 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6926 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6927 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6928 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6929 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6930 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6931 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6932 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6933 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6934#else
6935 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6936 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006937 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006938 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006939 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006940 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006941 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006942 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006943 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006944 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006945 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006946 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006947 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006948 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006949 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6950 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6951#endif
6952
6953 return v;
6954}
6955
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006956PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006957"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006958Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006959
6960static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006961posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006962{
6963 int fd, res;
6964 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006965
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006966 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006967 return NULL;
6968 Py_BEGIN_ALLOW_THREADS
6969 res = fstatvfs(fd, &st);
6970 Py_END_ALLOW_THREADS
6971 if (res != 0)
6972 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006973
6974 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006975}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006976#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006977
6978
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006979#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006980#include <sys/statvfs.h>
6981
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006982PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006983"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006984Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006985
6986static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006987posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006988{
6989 char *path;
6990 int res;
6991 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006992 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006993 return NULL;
6994 Py_BEGIN_ALLOW_THREADS
6995 res = statvfs(path, &st);
6996 Py_END_ALLOW_THREADS
6997 if (res != 0)
6998 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006999
7000 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007001}
7002#endif /* HAVE_STATVFS */
7003
7004
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007005#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007006PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007007"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007008Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007009The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007010or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007011
7012static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007013posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007014{
7015 PyObject *result = NULL;
7016 char *dir = NULL;
7017 char *pfx = NULL;
7018 char *name;
7019
7020 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
7021 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007022
7023 if (PyErr_Warn(PyExc_RuntimeWarning,
7024 "tempnam is a potential security risk to your program") < 0)
7025 return NULL;
7026
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007027#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007028 name = _tempnam(dir, pfx);
7029#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007030 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007031#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007032 if (name == NULL)
7033 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007034 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007035 free(name);
7036 return result;
7037}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007038#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007039
7040
7041#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007042PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007043"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007044Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007045
7046static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007047posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007048{
7049 FILE *fp;
7050
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007051 fp = tmpfile();
7052 if (fp == NULL)
7053 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007054 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007055}
7056#endif
7057
7058
7059#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007060PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007061"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007062Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007063
7064static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007065posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007066{
7067 char buffer[L_tmpnam];
7068 char *name;
7069
Skip Montanaro95618b52001-08-18 18:52:10 +00007070 if (PyErr_Warn(PyExc_RuntimeWarning,
7071 "tmpnam is a potential security risk to your program") < 0)
7072 return NULL;
7073
Greg Wardb48bc172000-03-01 21:51:56 +00007074#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007075 name = tmpnam_r(buffer);
7076#else
7077 name = tmpnam(buffer);
7078#endif
7079 if (name == NULL) {
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007080 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007081#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007082 "unexpected NULL from tmpnam_r"
7083#else
7084 "unexpected NULL from tmpnam"
7085#endif
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007086 );
7087 PyErr_SetObject(PyExc_OSError, err);
7088 Py_XDECREF(err);
7089 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007090 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007091 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007092}
7093#endif
7094
7095
Fred Drakec9680921999-12-13 16:37:25 +00007096/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7097 * It maps strings representing configuration variable names to
7098 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007099 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007100 * rarely-used constants. There are three separate tables that use
7101 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007102 *
7103 * This code is always included, even if none of the interfaces that
7104 * need it are included. The #if hackery needed to avoid it would be
7105 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007106 */
7107struct constdef {
7108 char *name;
7109 long value;
7110};
7111
Fred Drake12c6e2d1999-12-14 21:25:03 +00007112static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007113conv_confname(PyObject *arg, int *valuep, struct constdef *table,
7114 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007115{
7116 if (PyInt_Check(arg)) {
7117 *valuep = PyInt_AS_LONG(arg);
7118 return 1;
7119 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007120 if (PyString_Check(arg)) {
Fred Drake12c6e2d1999-12-14 21:25:03 +00007121 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00007122 size_t lo = 0;
7123 size_t mid;
7124 size_t hi = tablesize;
7125 int cmp;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007126 char *confname = PyString_AS_STRING(arg);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007127 while (lo < hi) {
7128 mid = (lo + hi) / 2;
7129 cmp = strcmp(confname, table[mid].name);
7130 if (cmp < 0)
7131 hi = mid;
7132 else if (cmp > 0)
7133 lo = mid + 1;
7134 else {
7135 *valuep = table[mid].value;
7136 return 1;
7137 }
7138 }
7139 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
7140 }
7141 else
7142 PyErr_SetString(PyExc_TypeError,
7143 "configuration names must be strings or integers");
7144 return 0;
7145}
7146
7147
7148#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7149static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007150#ifdef _PC_ABI_AIO_XFER_MAX
7151 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
7152#endif
7153#ifdef _PC_ABI_ASYNC_IO
7154 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
7155#endif
Fred Drakec9680921999-12-13 16:37:25 +00007156#ifdef _PC_ASYNC_IO
7157 {"PC_ASYNC_IO", _PC_ASYNC_IO},
7158#endif
7159#ifdef _PC_CHOWN_RESTRICTED
7160 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
7161#endif
7162#ifdef _PC_FILESIZEBITS
7163 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
7164#endif
7165#ifdef _PC_LAST
7166 {"PC_LAST", _PC_LAST},
7167#endif
7168#ifdef _PC_LINK_MAX
7169 {"PC_LINK_MAX", _PC_LINK_MAX},
7170#endif
7171#ifdef _PC_MAX_CANON
7172 {"PC_MAX_CANON", _PC_MAX_CANON},
7173#endif
7174#ifdef _PC_MAX_INPUT
7175 {"PC_MAX_INPUT", _PC_MAX_INPUT},
7176#endif
7177#ifdef _PC_NAME_MAX
7178 {"PC_NAME_MAX", _PC_NAME_MAX},
7179#endif
7180#ifdef _PC_NO_TRUNC
7181 {"PC_NO_TRUNC", _PC_NO_TRUNC},
7182#endif
7183#ifdef _PC_PATH_MAX
7184 {"PC_PATH_MAX", _PC_PATH_MAX},
7185#endif
7186#ifdef _PC_PIPE_BUF
7187 {"PC_PIPE_BUF", _PC_PIPE_BUF},
7188#endif
7189#ifdef _PC_PRIO_IO
7190 {"PC_PRIO_IO", _PC_PRIO_IO},
7191#endif
7192#ifdef _PC_SOCK_MAXBUF
7193 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
7194#endif
7195#ifdef _PC_SYNC_IO
7196 {"PC_SYNC_IO", _PC_SYNC_IO},
7197#endif
7198#ifdef _PC_VDISABLE
7199 {"PC_VDISABLE", _PC_VDISABLE},
7200#endif
7201};
7202
Fred Drakec9680921999-12-13 16:37:25 +00007203static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007204conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007205{
7206 return conv_confname(arg, valuep, posix_constants_pathconf,
7207 sizeof(posix_constants_pathconf)
7208 / sizeof(struct constdef));
7209}
7210#endif
7211
7212#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007213PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007214"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007215Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007216If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007217
7218static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007219posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007220{
7221 PyObject *result = NULL;
7222 int name, fd;
7223
Fred Drake12c6e2d1999-12-14 21:25:03 +00007224 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7225 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00007226 long limit;
7227
7228 errno = 0;
7229 limit = fpathconf(fd, name);
7230 if (limit == -1 && errno != 0)
7231 posix_error();
7232 else
7233 result = PyInt_FromLong(limit);
7234 }
7235 return result;
7236}
7237#endif
7238
7239
7240#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007241PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007242"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007243Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007244If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007245
7246static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007247posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007248{
7249 PyObject *result = NULL;
7250 int name;
7251 char *path;
7252
7253 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7254 conv_path_confname, &name)) {
7255 long limit;
7256
7257 errno = 0;
7258 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007259 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00007260 if (errno == EINVAL)
7261 /* could be a path or name problem */
7262 posix_error();
7263 else
7264 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007265 }
Fred Drakec9680921999-12-13 16:37:25 +00007266 else
7267 result = PyInt_FromLong(limit);
7268 }
7269 return result;
7270}
7271#endif
7272
7273#ifdef HAVE_CONFSTR
7274static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007275#ifdef _CS_ARCHITECTURE
7276 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
7277#endif
7278#ifdef _CS_HOSTNAME
7279 {"CS_HOSTNAME", _CS_HOSTNAME},
7280#endif
7281#ifdef _CS_HW_PROVIDER
7282 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
7283#endif
7284#ifdef _CS_HW_SERIAL
7285 {"CS_HW_SERIAL", _CS_HW_SERIAL},
7286#endif
7287#ifdef _CS_INITTAB_NAME
7288 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
7289#endif
Fred Drakec9680921999-12-13 16:37:25 +00007290#ifdef _CS_LFS64_CFLAGS
7291 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
7292#endif
7293#ifdef _CS_LFS64_LDFLAGS
7294 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
7295#endif
7296#ifdef _CS_LFS64_LIBS
7297 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
7298#endif
7299#ifdef _CS_LFS64_LINTFLAGS
7300 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
7301#endif
7302#ifdef _CS_LFS_CFLAGS
7303 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
7304#endif
7305#ifdef _CS_LFS_LDFLAGS
7306 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
7307#endif
7308#ifdef _CS_LFS_LIBS
7309 {"CS_LFS_LIBS", _CS_LFS_LIBS},
7310#endif
7311#ifdef _CS_LFS_LINTFLAGS
7312 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
7313#endif
Fred Draked86ed291999-12-15 15:34:33 +00007314#ifdef _CS_MACHINE
7315 {"CS_MACHINE", _CS_MACHINE},
7316#endif
Fred Drakec9680921999-12-13 16:37:25 +00007317#ifdef _CS_PATH
7318 {"CS_PATH", _CS_PATH},
7319#endif
Fred Draked86ed291999-12-15 15:34:33 +00007320#ifdef _CS_RELEASE
7321 {"CS_RELEASE", _CS_RELEASE},
7322#endif
7323#ifdef _CS_SRPC_DOMAIN
7324 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
7325#endif
7326#ifdef _CS_SYSNAME
7327 {"CS_SYSNAME", _CS_SYSNAME},
7328#endif
7329#ifdef _CS_VERSION
7330 {"CS_VERSION", _CS_VERSION},
7331#endif
Fred Drakec9680921999-12-13 16:37:25 +00007332#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
7333 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
7334#endif
7335#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
7336 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
7337#endif
7338#ifdef _CS_XBS5_ILP32_OFF32_LIBS
7339 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
7340#endif
7341#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
7342 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
7343#endif
7344#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
7345 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
7346#endif
7347#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
7348 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
7349#endif
7350#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
7351 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
7352#endif
7353#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
7354 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
7355#endif
7356#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7357 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
7358#endif
7359#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7360 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7361#endif
7362#ifdef _CS_XBS5_LP64_OFF64_LIBS
7363 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7364#endif
7365#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7366 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7367#endif
7368#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7369 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7370#endif
7371#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7372 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7373#endif
7374#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7375 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7376#endif
7377#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7378 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7379#endif
Fred Draked86ed291999-12-15 15:34:33 +00007380#ifdef _MIPS_CS_AVAIL_PROCESSORS
7381 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7382#endif
7383#ifdef _MIPS_CS_BASE
7384 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7385#endif
7386#ifdef _MIPS_CS_HOSTID
7387 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7388#endif
7389#ifdef _MIPS_CS_HW_NAME
7390 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7391#endif
7392#ifdef _MIPS_CS_NUM_PROCESSORS
7393 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7394#endif
7395#ifdef _MIPS_CS_OSREL_MAJ
7396 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7397#endif
7398#ifdef _MIPS_CS_OSREL_MIN
7399 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7400#endif
7401#ifdef _MIPS_CS_OSREL_PATCH
7402 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7403#endif
7404#ifdef _MIPS_CS_OS_NAME
7405 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7406#endif
7407#ifdef _MIPS_CS_OS_PROVIDER
7408 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7409#endif
7410#ifdef _MIPS_CS_PROCESSORS
7411 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7412#endif
7413#ifdef _MIPS_CS_SERIAL
7414 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7415#endif
7416#ifdef _MIPS_CS_VENDOR
7417 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7418#endif
Fred Drakec9680921999-12-13 16:37:25 +00007419};
7420
7421static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007422conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007423{
7424 return conv_confname(arg, valuep, posix_constants_confstr,
7425 sizeof(posix_constants_confstr)
7426 / sizeof(struct constdef));
7427}
7428
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007429PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007430"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007431Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007432
7433static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007434posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007435{
7436 PyObject *result = NULL;
7437 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007438 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007439
7440 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Skip Montanarodd527fc2006-04-18 00:49:49 +00007441 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007442
Fred Drakec9680921999-12-13 16:37:25 +00007443 errno = 0;
Skip Montanarodd527fc2006-04-18 00:49:49 +00007444 len = confstr(name, buffer, sizeof(buffer));
Skip Montanaro94785ef2006-04-20 01:29:48 +00007445 if (len == 0) {
7446 if (errno) {
7447 posix_error();
7448 }
7449 else {
7450 result = Py_None;
7451 Py_INCREF(Py_None);
7452 }
Fred Drakec9680921999-12-13 16:37:25 +00007453 }
7454 else {
Neal Norwitz0d21b1e2006-04-20 06:44:42 +00007455 if ((unsigned int)len >= sizeof(buffer)) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007456 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007457 if (result != NULL)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007458 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00007459 }
7460 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007461 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007462 }
7463 }
7464 return result;
7465}
7466#endif
7467
7468
7469#ifdef HAVE_SYSCONF
7470static struct constdef posix_constants_sysconf[] = {
7471#ifdef _SC_2_CHAR_TERM
7472 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7473#endif
7474#ifdef _SC_2_C_BIND
7475 {"SC_2_C_BIND", _SC_2_C_BIND},
7476#endif
7477#ifdef _SC_2_C_DEV
7478 {"SC_2_C_DEV", _SC_2_C_DEV},
7479#endif
7480#ifdef _SC_2_C_VERSION
7481 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7482#endif
7483#ifdef _SC_2_FORT_DEV
7484 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7485#endif
7486#ifdef _SC_2_FORT_RUN
7487 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7488#endif
7489#ifdef _SC_2_LOCALEDEF
7490 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7491#endif
7492#ifdef _SC_2_SW_DEV
7493 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7494#endif
7495#ifdef _SC_2_UPE
7496 {"SC_2_UPE", _SC_2_UPE},
7497#endif
7498#ifdef _SC_2_VERSION
7499 {"SC_2_VERSION", _SC_2_VERSION},
7500#endif
Fred Draked86ed291999-12-15 15:34:33 +00007501#ifdef _SC_ABI_ASYNCHRONOUS_IO
7502 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7503#endif
7504#ifdef _SC_ACL
7505 {"SC_ACL", _SC_ACL},
7506#endif
Fred Drakec9680921999-12-13 16:37:25 +00007507#ifdef _SC_AIO_LISTIO_MAX
7508 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7509#endif
Fred Drakec9680921999-12-13 16:37:25 +00007510#ifdef _SC_AIO_MAX
7511 {"SC_AIO_MAX", _SC_AIO_MAX},
7512#endif
7513#ifdef _SC_AIO_PRIO_DELTA_MAX
7514 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7515#endif
7516#ifdef _SC_ARG_MAX
7517 {"SC_ARG_MAX", _SC_ARG_MAX},
7518#endif
7519#ifdef _SC_ASYNCHRONOUS_IO
7520 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7521#endif
7522#ifdef _SC_ATEXIT_MAX
7523 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7524#endif
Fred Draked86ed291999-12-15 15:34:33 +00007525#ifdef _SC_AUDIT
7526 {"SC_AUDIT", _SC_AUDIT},
7527#endif
Fred Drakec9680921999-12-13 16:37:25 +00007528#ifdef _SC_AVPHYS_PAGES
7529 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7530#endif
7531#ifdef _SC_BC_BASE_MAX
7532 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7533#endif
7534#ifdef _SC_BC_DIM_MAX
7535 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7536#endif
7537#ifdef _SC_BC_SCALE_MAX
7538 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7539#endif
7540#ifdef _SC_BC_STRING_MAX
7541 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7542#endif
Fred Draked86ed291999-12-15 15:34:33 +00007543#ifdef _SC_CAP
7544 {"SC_CAP", _SC_CAP},
7545#endif
Fred Drakec9680921999-12-13 16:37:25 +00007546#ifdef _SC_CHARCLASS_NAME_MAX
7547 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7548#endif
7549#ifdef _SC_CHAR_BIT
7550 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7551#endif
7552#ifdef _SC_CHAR_MAX
7553 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7554#endif
7555#ifdef _SC_CHAR_MIN
7556 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7557#endif
7558#ifdef _SC_CHILD_MAX
7559 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7560#endif
7561#ifdef _SC_CLK_TCK
7562 {"SC_CLK_TCK", _SC_CLK_TCK},
7563#endif
7564#ifdef _SC_COHER_BLKSZ
7565 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7566#endif
7567#ifdef _SC_COLL_WEIGHTS_MAX
7568 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7569#endif
7570#ifdef _SC_DCACHE_ASSOC
7571 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7572#endif
7573#ifdef _SC_DCACHE_BLKSZ
7574 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7575#endif
7576#ifdef _SC_DCACHE_LINESZ
7577 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7578#endif
7579#ifdef _SC_DCACHE_SZ
7580 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7581#endif
7582#ifdef _SC_DCACHE_TBLKSZ
7583 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7584#endif
7585#ifdef _SC_DELAYTIMER_MAX
7586 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7587#endif
7588#ifdef _SC_EQUIV_CLASS_MAX
7589 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7590#endif
7591#ifdef _SC_EXPR_NEST_MAX
7592 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7593#endif
7594#ifdef _SC_FSYNC
7595 {"SC_FSYNC", _SC_FSYNC},
7596#endif
7597#ifdef _SC_GETGR_R_SIZE_MAX
7598 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7599#endif
7600#ifdef _SC_GETPW_R_SIZE_MAX
7601 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7602#endif
7603#ifdef _SC_ICACHE_ASSOC
7604 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7605#endif
7606#ifdef _SC_ICACHE_BLKSZ
7607 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7608#endif
7609#ifdef _SC_ICACHE_LINESZ
7610 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7611#endif
7612#ifdef _SC_ICACHE_SZ
7613 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7614#endif
Fred Draked86ed291999-12-15 15:34:33 +00007615#ifdef _SC_INF
7616 {"SC_INF", _SC_INF},
7617#endif
Fred Drakec9680921999-12-13 16:37:25 +00007618#ifdef _SC_INT_MAX
7619 {"SC_INT_MAX", _SC_INT_MAX},
7620#endif
7621#ifdef _SC_INT_MIN
7622 {"SC_INT_MIN", _SC_INT_MIN},
7623#endif
7624#ifdef _SC_IOV_MAX
7625 {"SC_IOV_MAX", _SC_IOV_MAX},
7626#endif
Fred Draked86ed291999-12-15 15:34:33 +00007627#ifdef _SC_IP_SECOPTS
7628 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7629#endif
Fred Drakec9680921999-12-13 16:37:25 +00007630#ifdef _SC_JOB_CONTROL
7631 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7632#endif
Fred Draked86ed291999-12-15 15:34:33 +00007633#ifdef _SC_KERN_POINTERS
7634 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7635#endif
7636#ifdef _SC_KERN_SIM
7637 {"SC_KERN_SIM", _SC_KERN_SIM},
7638#endif
Fred Drakec9680921999-12-13 16:37:25 +00007639#ifdef _SC_LINE_MAX
7640 {"SC_LINE_MAX", _SC_LINE_MAX},
7641#endif
7642#ifdef _SC_LOGIN_NAME_MAX
7643 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7644#endif
7645#ifdef _SC_LOGNAME_MAX
7646 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7647#endif
7648#ifdef _SC_LONG_BIT
7649 {"SC_LONG_BIT", _SC_LONG_BIT},
7650#endif
Fred Draked86ed291999-12-15 15:34:33 +00007651#ifdef _SC_MAC
7652 {"SC_MAC", _SC_MAC},
7653#endif
Fred Drakec9680921999-12-13 16:37:25 +00007654#ifdef _SC_MAPPED_FILES
7655 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7656#endif
7657#ifdef _SC_MAXPID
7658 {"SC_MAXPID", _SC_MAXPID},
7659#endif
7660#ifdef _SC_MB_LEN_MAX
7661 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7662#endif
7663#ifdef _SC_MEMLOCK
7664 {"SC_MEMLOCK", _SC_MEMLOCK},
7665#endif
7666#ifdef _SC_MEMLOCK_RANGE
7667 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7668#endif
7669#ifdef _SC_MEMORY_PROTECTION
7670 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7671#endif
7672#ifdef _SC_MESSAGE_PASSING
7673 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7674#endif
Fred Draked86ed291999-12-15 15:34:33 +00007675#ifdef _SC_MMAP_FIXED_ALIGNMENT
7676 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7677#endif
Fred Drakec9680921999-12-13 16:37:25 +00007678#ifdef _SC_MQ_OPEN_MAX
7679 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7680#endif
7681#ifdef _SC_MQ_PRIO_MAX
7682 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7683#endif
Fred Draked86ed291999-12-15 15:34:33 +00007684#ifdef _SC_NACLS_MAX
7685 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7686#endif
Fred Drakec9680921999-12-13 16:37:25 +00007687#ifdef _SC_NGROUPS_MAX
7688 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7689#endif
7690#ifdef _SC_NL_ARGMAX
7691 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7692#endif
7693#ifdef _SC_NL_LANGMAX
7694 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7695#endif
7696#ifdef _SC_NL_MSGMAX
7697 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7698#endif
7699#ifdef _SC_NL_NMAX
7700 {"SC_NL_NMAX", _SC_NL_NMAX},
7701#endif
7702#ifdef _SC_NL_SETMAX
7703 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7704#endif
7705#ifdef _SC_NL_TEXTMAX
7706 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7707#endif
7708#ifdef _SC_NPROCESSORS_CONF
7709 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7710#endif
7711#ifdef _SC_NPROCESSORS_ONLN
7712 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7713#endif
Fred Draked86ed291999-12-15 15:34:33 +00007714#ifdef _SC_NPROC_CONF
7715 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7716#endif
7717#ifdef _SC_NPROC_ONLN
7718 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7719#endif
Fred Drakec9680921999-12-13 16:37:25 +00007720#ifdef _SC_NZERO
7721 {"SC_NZERO", _SC_NZERO},
7722#endif
7723#ifdef _SC_OPEN_MAX
7724 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7725#endif
7726#ifdef _SC_PAGESIZE
7727 {"SC_PAGESIZE", _SC_PAGESIZE},
7728#endif
7729#ifdef _SC_PAGE_SIZE
7730 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7731#endif
7732#ifdef _SC_PASS_MAX
7733 {"SC_PASS_MAX", _SC_PASS_MAX},
7734#endif
7735#ifdef _SC_PHYS_PAGES
7736 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7737#endif
7738#ifdef _SC_PII
7739 {"SC_PII", _SC_PII},
7740#endif
7741#ifdef _SC_PII_INTERNET
7742 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7743#endif
7744#ifdef _SC_PII_INTERNET_DGRAM
7745 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7746#endif
7747#ifdef _SC_PII_INTERNET_STREAM
7748 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7749#endif
7750#ifdef _SC_PII_OSI
7751 {"SC_PII_OSI", _SC_PII_OSI},
7752#endif
7753#ifdef _SC_PII_OSI_CLTS
7754 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7755#endif
7756#ifdef _SC_PII_OSI_COTS
7757 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7758#endif
7759#ifdef _SC_PII_OSI_M
7760 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7761#endif
7762#ifdef _SC_PII_SOCKET
7763 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7764#endif
7765#ifdef _SC_PII_XTI
7766 {"SC_PII_XTI", _SC_PII_XTI},
7767#endif
7768#ifdef _SC_POLL
7769 {"SC_POLL", _SC_POLL},
7770#endif
7771#ifdef _SC_PRIORITIZED_IO
7772 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7773#endif
7774#ifdef _SC_PRIORITY_SCHEDULING
7775 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7776#endif
7777#ifdef _SC_REALTIME_SIGNALS
7778 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7779#endif
7780#ifdef _SC_RE_DUP_MAX
7781 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7782#endif
7783#ifdef _SC_RTSIG_MAX
7784 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7785#endif
7786#ifdef _SC_SAVED_IDS
7787 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7788#endif
7789#ifdef _SC_SCHAR_MAX
7790 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7791#endif
7792#ifdef _SC_SCHAR_MIN
7793 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7794#endif
7795#ifdef _SC_SELECT
7796 {"SC_SELECT", _SC_SELECT},
7797#endif
7798#ifdef _SC_SEMAPHORES
7799 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7800#endif
7801#ifdef _SC_SEM_NSEMS_MAX
7802 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7803#endif
7804#ifdef _SC_SEM_VALUE_MAX
7805 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7806#endif
7807#ifdef _SC_SHARED_MEMORY_OBJECTS
7808 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7809#endif
7810#ifdef _SC_SHRT_MAX
7811 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7812#endif
7813#ifdef _SC_SHRT_MIN
7814 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7815#endif
7816#ifdef _SC_SIGQUEUE_MAX
7817 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7818#endif
7819#ifdef _SC_SIGRT_MAX
7820 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7821#endif
7822#ifdef _SC_SIGRT_MIN
7823 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7824#endif
Fred Draked86ed291999-12-15 15:34:33 +00007825#ifdef _SC_SOFTPOWER
7826 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7827#endif
Fred Drakec9680921999-12-13 16:37:25 +00007828#ifdef _SC_SPLIT_CACHE
7829 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7830#endif
7831#ifdef _SC_SSIZE_MAX
7832 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7833#endif
7834#ifdef _SC_STACK_PROT
7835 {"SC_STACK_PROT", _SC_STACK_PROT},
7836#endif
7837#ifdef _SC_STREAM_MAX
7838 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7839#endif
7840#ifdef _SC_SYNCHRONIZED_IO
7841 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7842#endif
7843#ifdef _SC_THREADS
7844 {"SC_THREADS", _SC_THREADS},
7845#endif
7846#ifdef _SC_THREAD_ATTR_STACKADDR
7847 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7848#endif
7849#ifdef _SC_THREAD_ATTR_STACKSIZE
7850 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7851#endif
7852#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7853 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7854#endif
7855#ifdef _SC_THREAD_KEYS_MAX
7856 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7857#endif
7858#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7859 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7860#endif
7861#ifdef _SC_THREAD_PRIO_INHERIT
7862 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7863#endif
7864#ifdef _SC_THREAD_PRIO_PROTECT
7865 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7866#endif
7867#ifdef _SC_THREAD_PROCESS_SHARED
7868 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7869#endif
7870#ifdef _SC_THREAD_SAFE_FUNCTIONS
7871 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7872#endif
7873#ifdef _SC_THREAD_STACK_MIN
7874 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7875#endif
7876#ifdef _SC_THREAD_THREADS_MAX
7877 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7878#endif
7879#ifdef _SC_TIMERS
7880 {"SC_TIMERS", _SC_TIMERS},
7881#endif
7882#ifdef _SC_TIMER_MAX
7883 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7884#endif
7885#ifdef _SC_TTY_NAME_MAX
7886 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7887#endif
7888#ifdef _SC_TZNAME_MAX
7889 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7890#endif
7891#ifdef _SC_T_IOV_MAX
7892 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7893#endif
7894#ifdef _SC_UCHAR_MAX
7895 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7896#endif
7897#ifdef _SC_UINT_MAX
7898 {"SC_UINT_MAX", _SC_UINT_MAX},
7899#endif
7900#ifdef _SC_UIO_MAXIOV
7901 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7902#endif
7903#ifdef _SC_ULONG_MAX
7904 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7905#endif
7906#ifdef _SC_USHRT_MAX
7907 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7908#endif
7909#ifdef _SC_VERSION
7910 {"SC_VERSION", _SC_VERSION},
7911#endif
7912#ifdef _SC_WORD_BIT
7913 {"SC_WORD_BIT", _SC_WORD_BIT},
7914#endif
7915#ifdef _SC_XBS5_ILP32_OFF32
7916 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7917#endif
7918#ifdef _SC_XBS5_ILP32_OFFBIG
7919 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7920#endif
7921#ifdef _SC_XBS5_LP64_OFF64
7922 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7923#endif
7924#ifdef _SC_XBS5_LPBIG_OFFBIG
7925 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7926#endif
7927#ifdef _SC_XOPEN_CRYPT
7928 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7929#endif
7930#ifdef _SC_XOPEN_ENH_I18N
7931 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7932#endif
7933#ifdef _SC_XOPEN_LEGACY
7934 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7935#endif
7936#ifdef _SC_XOPEN_REALTIME
7937 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7938#endif
7939#ifdef _SC_XOPEN_REALTIME_THREADS
7940 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7941#endif
7942#ifdef _SC_XOPEN_SHM
7943 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7944#endif
7945#ifdef _SC_XOPEN_UNIX
7946 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7947#endif
7948#ifdef _SC_XOPEN_VERSION
7949 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7950#endif
7951#ifdef _SC_XOPEN_XCU_VERSION
7952 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7953#endif
7954#ifdef _SC_XOPEN_XPG2
7955 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7956#endif
7957#ifdef _SC_XOPEN_XPG3
7958 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7959#endif
7960#ifdef _SC_XOPEN_XPG4
7961 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7962#endif
7963};
7964
7965static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007966conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007967{
7968 return conv_confname(arg, valuep, posix_constants_sysconf,
7969 sizeof(posix_constants_sysconf)
7970 / sizeof(struct constdef));
7971}
7972
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007973PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007974"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007975Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007976
7977static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007978posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007979{
7980 PyObject *result = NULL;
7981 int name;
7982
7983 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7984 int value;
7985
7986 errno = 0;
7987 value = sysconf(name);
7988 if (value == -1 && errno != 0)
7989 posix_error();
7990 else
7991 result = PyInt_FromLong(value);
7992 }
7993 return result;
7994}
7995#endif
7996
7997
Fred Drakebec628d1999-12-15 18:31:10 +00007998/* This code is used to ensure that the tables of configuration value names
7999 * are in sorted order as required by conv_confname(), and also to build the
8000 * the exported dictionaries that are used to publish information about the
8001 * names available on the host platform.
8002 *
8003 * Sorting the table at runtime ensures that the table is properly ordered
8004 * when used, even for platforms we're not able to test on. It also makes
8005 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008006 */
Fred Drakebec628d1999-12-15 18:31:10 +00008007
8008static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008009cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008010{
8011 const struct constdef *c1 =
8012 (const struct constdef *) v1;
8013 const struct constdef *c2 =
8014 (const struct constdef *) v2;
8015
8016 return strcmp(c1->name, c2->name);
8017}
8018
8019static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008020setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008021 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008022{
Fred Drakebec628d1999-12-15 18:31:10 +00008023 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008024 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008025
8026 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8027 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008028 if (d == NULL)
8029 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008030
Barry Warsaw3155db32000-04-13 15:20:40 +00008031 for (i=0; i < tablesize; ++i) {
8032 PyObject *o = PyInt_FromLong(table[i].value);
8033 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8034 Py_XDECREF(o);
8035 Py_DECREF(d);
8036 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008037 }
Barry Warsaw3155db32000-04-13 15:20:40 +00008038 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008039 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008040 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008041}
8042
Fred Drakebec628d1999-12-15 18:31:10 +00008043/* Return -1 on failure, 0 on success. */
8044static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008045setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008046{
8047#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008048 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008049 sizeof(posix_constants_pathconf)
8050 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008051 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008052 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008053#endif
8054#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008055 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008056 sizeof(posix_constants_confstr)
8057 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008058 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008059 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008060#endif
8061#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008062 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008063 sizeof(posix_constants_sysconf)
8064 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008065 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008066 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008067#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008068 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008069}
Fred Draked86ed291999-12-15 15:34:33 +00008070
8071
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008072PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008073"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008074Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008075in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008076
8077static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008078posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008079{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008080 abort();
8081 /*NOTREACHED*/
8082 Py_FatalError("abort() called from Python code didn't abort!");
8083 return NULL;
8084}
Fred Drakebec628d1999-12-15 18:31:10 +00008085
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008086#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008087PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008088"startfile(filepath [, operation]) - Start a file with its associated\n\
8089application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008090\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008091When \"operation\" is not specified or \"open\", this acts like\n\
8092double-clicking the file in Explorer, or giving the file name as an\n\
8093argument to the DOS \"start\" command: the file is opened with whatever\n\
8094application (if any) its extension is associated.\n\
8095When another \"operation\" is given, it specifies what should be done with\n\
8096the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008097\n\
8098startfile returns as soon as the associated application is launched.\n\
8099There is no option to wait for the application to close, and no way\n\
8100to retrieve the application's exit status.\n\
8101\n\
8102The filepath is relative to the current directory. If you want to use\n\
8103an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008104the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008105
8106static PyObject *
8107win32_startfile(PyObject *self, PyObject *args)
8108{
8109 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00008110 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008111 HINSTANCE rc;
Georg Brandlad89dc82006-04-03 12:26:26 +00008112#ifdef Py_WIN_WIDE_FILENAMES
8113 if (unicode_file_names()) {
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008114 PyObject *unipath, *woperation = NULL;
Georg Brandlad89dc82006-04-03 12:26:26 +00008115 if (!PyArg_ParseTuple(args, "U|s:startfile",
8116 &unipath, &operation)) {
8117 PyErr_Clear();
8118 goto normal;
8119 }
8120
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008121
8122 if (operation) {
8123 woperation = PyUnicode_DecodeASCII(operation,
8124 strlen(operation), NULL);
8125 if (!woperation) {
8126 PyErr_Clear();
8127 operation = NULL;
8128 goto normal;
8129 }
Georg Brandlad89dc82006-04-03 12:26:26 +00008130 }
8131
8132 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008133 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Georg Brandlad89dc82006-04-03 12:26:26 +00008134 PyUnicode_AS_UNICODE(unipath),
Georg Brandlad89dc82006-04-03 12:26:26 +00008135 NULL, NULL, SW_SHOWNORMAL);
8136 Py_END_ALLOW_THREADS
8137
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008138 Py_XDECREF(woperation);
Georg Brandlad89dc82006-04-03 12:26:26 +00008139 if (rc <= (HINSTANCE)32) {
8140 PyObject *errval = win32_error_unicode("startfile",
8141 PyUnicode_AS_UNICODE(unipath));
8142 return errval;
8143 }
8144 Py_INCREF(Py_None);
8145 return Py_None;
8146 }
8147#endif
8148
8149normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00008150 if (!PyArg_ParseTuple(args, "et|s:startfile",
8151 Py_FileSystemDefaultEncoding, &filepath,
8152 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00008153 return NULL;
8154 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00008155 rc = ShellExecute((HWND)0, operation, filepath,
8156 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008157 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00008158 if (rc <= (HINSTANCE)32) {
8159 PyObject *errval = win32_error("startfile", filepath);
8160 PyMem_Free(filepath);
8161 return errval;
8162 }
8163 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008164 Py_INCREF(Py_None);
8165 return Py_None;
8166}
8167#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008168
Martin v. Löwis438b5342002-12-27 10:16:42 +00008169#ifdef HAVE_GETLOADAVG
8170PyDoc_STRVAR(posix_getloadavg__doc__,
8171"getloadavg() -> (float, float, float)\n\n\
8172Return the number of processes in the system run queue averaged over\n\
8173the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8174was unobtainable");
8175
8176static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008177posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008178{
8179 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008180 if (getloadavg(loadavg, 3)!=3) {
8181 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8182 return NULL;
8183 } else
8184 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
8185}
8186#endif
8187
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008188#ifdef MS_WINDOWS
8189
8190PyDoc_STRVAR(win32_urandom__doc__,
8191"urandom(n) -> str\n\n\
8192Return a string of n random bytes suitable for cryptographic use.");
8193
8194typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8195 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8196 DWORD dwFlags );
8197typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8198 BYTE *pbBuffer );
8199
8200static CRYPTGENRANDOM pCryptGenRandom = NULL;
Martin v. Löwisaf699dd2007-09-04 09:51:57 +00008201/* This handle is never explicitly released. Instead, the operating
8202 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008203static HCRYPTPROV hCryptProv = 0;
8204
Tim Peters4ad82172004-08-30 17:02:04 +00008205static PyObject*
8206win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008207{
Tim Petersd3115382004-08-30 17:36:46 +00008208 int howMany;
8209 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008210
Tim Peters4ad82172004-08-30 17:02:04 +00008211 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00008212 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00008213 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00008214 if (howMany < 0)
8215 return PyErr_Format(PyExc_ValueError,
8216 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008217
Tim Peters4ad82172004-08-30 17:02:04 +00008218 if (hCryptProv == 0) {
8219 HINSTANCE hAdvAPI32 = NULL;
8220 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008221
Tim Peters4ad82172004-08-30 17:02:04 +00008222 /* Obtain handle to the DLL containing CryptoAPI
8223 This should not fail */
8224 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8225 if(hAdvAPI32 == NULL)
8226 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008227
Tim Peters4ad82172004-08-30 17:02:04 +00008228 /* Obtain pointers to the CryptoAPI functions
8229 This will fail on some early versions of Win95 */
8230 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8231 hAdvAPI32,
8232 "CryptAcquireContextA");
8233 if (pCryptAcquireContext == NULL)
8234 return PyErr_Format(PyExc_NotImplementedError,
8235 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008236
Tim Peters4ad82172004-08-30 17:02:04 +00008237 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8238 hAdvAPI32, "CryptGenRandom");
Georg Brandl74bb7832006-09-06 06:03:59 +00008239 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00008240 return PyErr_Format(PyExc_NotImplementedError,
8241 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008242
Tim Peters4ad82172004-08-30 17:02:04 +00008243 /* Acquire context */
8244 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8245 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8246 return win32_error("CryptAcquireContext", NULL);
8247 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008248
Tim Peters4ad82172004-08-30 17:02:04 +00008249 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008250 result = PyString_FromStringAndSize(NULL, howMany);
Tim Petersd3115382004-08-30 17:36:46 +00008251 if (result != NULL) {
8252 /* Get random data */
Amaury Forgeot d'Arc74bd40d2008-07-21 21:06:46 +00008253 memset(PyString_AS_STRING(result), 0, howMany); /* zero seed */
Tim Petersd3115382004-08-30 17:36:46 +00008254 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008255 PyString_AS_STRING(result))) {
Tim Petersd3115382004-08-30 17:36:46 +00008256 Py_DECREF(result);
8257 return win32_error("CryptGenRandom", NULL);
8258 }
Tim Peters4ad82172004-08-30 17:02:04 +00008259 }
Tim Petersd3115382004-08-30 17:36:46 +00008260 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008261}
8262#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008263
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008264#ifdef __VMS
8265/* Use openssl random routine */
8266#include <openssl/rand.h>
8267PyDoc_STRVAR(vms_urandom__doc__,
8268"urandom(n) -> str\n\n\
8269Return a string of n random bytes suitable for cryptographic use.");
8270
8271static PyObject*
8272vms_urandom(PyObject *self, PyObject *args)
8273{
8274 int howMany;
8275 PyObject* result;
8276
8277 /* Read arguments */
8278 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8279 return NULL;
8280 if (howMany < 0)
8281 return PyErr_Format(PyExc_ValueError,
8282 "negative argument not allowed");
8283
8284 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008285 result = PyString_FromStringAndSize(NULL, howMany);
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008286 if (result != NULL) {
8287 /* Get random data */
8288 if (RAND_pseudo_bytes((unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008289 PyString_AS_STRING(result),
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008290 howMany) < 0) {
8291 Py_DECREF(result);
8292 return PyErr_Format(PyExc_ValueError,
8293 "RAND_pseudo_bytes");
8294 }
8295 }
8296 return result;
8297}
8298#endif
8299
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008300static PyMethodDef posix_methods[] = {
8301 {"access", posix_access, METH_VARARGS, posix_access__doc__},
8302#ifdef HAVE_TTYNAME
8303 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
8304#endif
8305 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008306#ifdef HAVE_CHFLAGS
8307 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
8308#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008309 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008310#ifdef HAVE_FCHMOD
8311 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
8312#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008313#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008314 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008315#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008316#ifdef HAVE_LCHMOD
8317 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
8318#endif /* HAVE_LCHMOD */
8319#ifdef HAVE_FCHOWN
8320 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
8321#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008322#ifdef HAVE_LCHFLAGS
8323 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
8324#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008325#ifdef HAVE_LCHOWN
8326 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
8327#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008328#ifdef HAVE_CHROOT
8329 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
8330#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008331#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00008332 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008333#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008334#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00008335 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008336#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00008337 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008338#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008339#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008340#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008341 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008342#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008343 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8344 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8345 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008346#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008347 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008348#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008349#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008350 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008351#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008352 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8353 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8354 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008355 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008356#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008357 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008358#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008359#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008360 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008361#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008362 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008363#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00008364 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008365#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008366 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8367 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8368 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008369#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00008370 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008371#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008372 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008373#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008374 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8375 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008376#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008377#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008378 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8379 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008380#if defined(PYOS_OS2)
8381 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8382 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8383#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008384#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008385#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00008386 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008387#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008388#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00008389 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008390#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008391#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00008392 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008393#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008394#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00008395 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008396#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008397#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008398 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008399#endif /* HAVE_GETEGID */
8400#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008401 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008402#endif /* HAVE_GETEUID */
8403#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008404 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008405#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008406#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00008407 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008408#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008409 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008410#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008411 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008412#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008413#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00008414 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008415#endif /* HAVE_GETPPID */
8416#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008417 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008418#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008419#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00008420 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008421#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008422#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008423 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008424#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008425#ifdef HAVE_KILLPG
8426 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8427#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008428#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008429 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008430#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008431#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008432 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008433#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008434 {"popen2", win32_popen2, METH_VARARGS},
8435 {"popen3", win32_popen3, METH_VARARGS},
8436 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00008437 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008438#else
8439#if defined(PYOS_OS2) && defined(PYCC_GCC)
8440 {"popen2", os2emx_popen2, METH_VARARGS},
8441 {"popen3", os2emx_popen3, METH_VARARGS},
8442 {"popen4", os2emx_popen4, METH_VARARGS},
8443#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008444#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008445#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008446#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008447 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008448#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008449#ifdef HAVE_SETEUID
8450 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8451#endif /* HAVE_SETEUID */
8452#ifdef HAVE_SETEGID
8453 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8454#endif /* HAVE_SETEGID */
8455#ifdef HAVE_SETREUID
8456 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8457#endif /* HAVE_SETREUID */
8458#ifdef HAVE_SETREGID
8459 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8460#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008461#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008462 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008463#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008464#ifdef HAVE_SETGROUPS
Georg Brandl96a8c392006-05-29 21:04:52 +00008465 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008466#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008467#ifdef HAVE_GETPGID
8468 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8469#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008470#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008471 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008472#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008473#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00008474 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008475#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008476#ifdef HAVE_WAIT3
8477 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8478#endif /* HAVE_WAIT3 */
8479#ifdef HAVE_WAIT4
8480 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8481#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008482#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008483 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008484#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008485#ifdef HAVE_GETSID
8486 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8487#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008488#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00008489 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008490#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008491#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008492 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008493#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008494#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008495 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008496#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008497#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008498 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008499#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008500 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8501 {"close", posix_close, METH_VARARGS, posix_close__doc__},
Georg Brandl309501a2008-01-19 20:22:13 +00008502 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008503 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8504 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8505 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8506 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8507 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8508 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8509 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00008510 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008511#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00008512 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008513#endif
8514#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008515 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008516#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008517#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008518 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8519#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008520#ifdef HAVE_DEVICE_MACROS
8521 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8522 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8523 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8524#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008525#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008526 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008527#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008528#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008529 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008530#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008531#ifdef HAVE_UNSETENV
8532 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8533#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008534 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008535#ifdef HAVE_FCHDIR
8536 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8537#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008538#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008539 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008540#endif
8541#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008542 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008543#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008544#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008545#ifdef WCOREDUMP
8546 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8547#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008548#ifdef WIFCONTINUED
8549 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8550#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008551#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008552 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008553#endif /* WIFSTOPPED */
8554#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008555 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008556#endif /* WIFSIGNALED */
8557#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008558 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008559#endif /* WIFEXITED */
8560#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008561 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008562#endif /* WEXITSTATUS */
8563#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008564 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008565#endif /* WTERMSIG */
8566#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008567 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008568#endif /* WSTOPSIG */
8569#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008570#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008571 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008572#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008573#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008574 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008575#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008576#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00008577 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008578#endif
8579#ifdef HAVE_TEMPNAM
8580 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8581#endif
8582#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00008583 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008584#endif
Fred Drakec9680921999-12-13 16:37:25 +00008585#ifdef HAVE_CONFSTR
8586 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8587#endif
8588#ifdef HAVE_SYSCONF
8589 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8590#endif
8591#ifdef HAVE_FPATHCONF
8592 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8593#endif
8594#ifdef HAVE_PATHCONF
8595 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8596#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008597 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008598#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00008599 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8600#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008601#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00008602 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008603#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008604 #ifdef MS_WINDOWS
8605 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8606 #endif
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008607 #ifdef __VMS
8608 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8609 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008610 {NULL, NULL} /* Sentinel */
8611};
8612
8613
Barry Warsaw4a342091996-12-19 23:50:02 +00008614static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008615ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008616{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008617 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008618}
8619
Guido van Rossumd48f2521997-12-05 22:19:34 +00008620#if defined(PYOS_OS2)
8621/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008622static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008623{
8624 APIRET rc;
8625 ULONG values[QSV_MAX+1];
8626 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008627 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008628
8629 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008630 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008631 Py_END_ALLOW_THREADS
8632
8633 if (rc != NO_ERROR) {
8634 os2_error(rc);
8635 return -1;
8636 }
8637
Fred Drake4d1e64b2002-04-15 19:40:07 +00008638 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8639 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8640 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8641 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8642 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8643 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8644 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008645
8646 switch (values[QSV_VERSION_MINOR]) {
8647 case 0: ver = "2.00"; break;
8648 case 10: ver = "2.10"; break;
8649 case 11: ver = "2.11"; break;
8650 case 30: ver = "3.00"; break;
8651 case 40: ver = "4.00"; break;
8652 case 50: ver = "5.00"; break;
8653 default:
Tim Peters885d4572001-11-28 20:27:42 +00008654 PyOS_snprintf(tmp, sizeof(tmp),
8655 "%d-%d", values[QSV_VERSION_MAJOR],
8656 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008657 ver = &tmp[0];
8658 }
8659
8660 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008661 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008662 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008663
8664 /* Add Indicator of Which Drive was Used to Boot the System */
8665 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8666 tmp[1] = ':';
8667 tmp[2] = '\0';
8668
Fred Drake4d1e64b2002-04-15 19:40:07 +00008669 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008670}
8671#endif
8672
Barry Warsaw4a342091996-12-19 23:50:02 +00008673static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008674all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008675{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008676#ifdef F_OK
8677 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008678#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008679#ifdef R_OK
8680 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008681#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008682#ifdef W_OK
8683 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008684#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008685#ifdef X_OK
8686 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008687#endif
Fred Drakec9680921999-12-13 16:37:25 +00008688#ifdef NGROUPS_MAX
8689 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8690#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008691#ifdef TMP_MAX
8692 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8693#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008694#ifdef WCONTINUED
8695 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8696#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008697#ifdef WNOHANG
8698 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008699#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008700#ifdef WUNTRACED
8701 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8702#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008703#ifdef O_RDONLY
8704 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8705#endif
8706#ifdef O_WRONLY
8707 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8708#endif
8709#ifdef O_RDWR
8710 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8711#endif
8712#ifdef O_NDELAY
8713 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8714#endif
8715#ifdef O_NONBLOCK
8716 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8717#endif
8718#ifdef O_APPEND
8719 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8720#endif
8721#ifdef O_DSYNC
8722 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8723#endif
8724#ifdef O_RSYNC
8725 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8726#endif
8727#ifdef O_SYNC
8728 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8729#endif
8730#ifdef O_NOCTTY
8731 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8732#endif
8733#ifdef O_CREAT
8734 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8735#endif
8736#ifdef O_EXCL
8737 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8738#endif
8739#ifdef O_TRUNC
8740 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8741#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008742#ifdef O_BINARY
8743 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8744#endif
8745#ifdef O_TEXT
8746 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8747#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008748#ifdef O_LARGEFILE
8749 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8750#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008751#ifdef O_SHLOCK
8752 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8753#endif
8754#ifdef O_EXLOCK
8755 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8756#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008757
Tim Peters5aa91602002-01-30 05:46:57 +00008758/* MS Windows */
8759#ifdef O_NOINHERIT
8760 /* Don't inherit in child processes. */
8761 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8762#endif
8763#ifdef _O_SHORT_LIVED
8764 /* Optimize for short life (keep in memory). */
8765 /* MS forgot to define this one with a non-underscore form too. */
8766 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8767#endif
8768#ifdef O_TEMPORARY
8769 /* Automatically delete when last handle is closed. */
8770 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8771#endif
8772#ifdef O_RANDOM
8773 /* Optimize for random access. */
8774 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8775#endif
8776#ifdef O_SEQUENTIAL
8777 /* Optimize for sequential access. */
8778 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8779#endif
8780
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008781/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00008782#ifdef O_ASYNC
8783 /* Send a SIGIO signal whenever input or output
8784 becomes available on file descriptor */
8785 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
8786#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008787#ifdef O_DIRECT
8788 /* Direct disk access. */
8789 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8790#endif
8791#ifdef O_DIRECTORY
8792 /* Must be a directory. */
8793 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8794#endif
8795#ifdef O_NOFOLLOW
8796 /* Do not follow links. */
8797 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8798#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00008799#ifdef O_NOATIME
8800 /* Do not update the access time. */
8801 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
8802#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008803
Barry Warsaw5676bd12003-01-07 20:57:09 +00008804 /* These come from sysexits.h */
8805#ifdef EX_OK
8806 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008807#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008808#ifdef EX_USAGE
8809 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008810#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008811#ifdef EX_DATAERR
8812 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008813#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008814#ifdef EX_NOINPUT
8815 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008816#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008817#ifdef EX_NOUSER
8818 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008819#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008820#ifdef EX_NOHOST
8821 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008822#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008823#ifdef EX_UNAVAILABLE
8824 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008825#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008826#ifdef EX_SOFTWARE
8827 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008828#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008829#ifdef EX_OSERR
8830 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008831#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008832#ifdef EX_OSFILE
8833 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008834#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008835#ifdef EX_CANTCREAT
8836 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008837#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008838#ifdef EX_IOERR
8839 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008840#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008841#ifdef EX_TEMPFAIL
8842 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008843#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008844#ifdef EX_PROTOCOL
8845 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008846#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008847#ifdef EX_NOPERM
8848 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008849#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008850#ifdef EX_CONFIG
8851 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008852#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008853#ifdef EX_NOTFOUND
8854 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008855#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008856
Guido van Rossum246bc171999-02-01 23:54:31 +00008857#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008858#if defined(PYOS_OS2) && defined(PYCC_GCC)
8859 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8860 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8861 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8862 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8863 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8864 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8865 if (ins(d, "P_PM", (long)P_PM)) return -1;
8866 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8867 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8868 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8869 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8870 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8871 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8872 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8873 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8874 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8875 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8876 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8877 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8878 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8879#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008880 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8881 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8882 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8883 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8884 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008885#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008886#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008887
Guido van Rossumd48f2521997-12-05 22:19:34 +00008888#if defined(PYOS_OS2)
8889 if (insertvalues(d)) return -1;
8890#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008891 return 0;
8892}
8893
8894
Tim Peters5aa91602002-01-30 05:46:57 +00008895#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008896#define INITFUNC initnt
8897#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008898
8899#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008900#define INITFUNC initos2
8901#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008902
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008903#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008904#define INITFUNC initposix
8905#define MODNAME "posix"
8906#endif
8907
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008908PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008909INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008910{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008911 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008912
Fred Drake4d1e64b2002-04-15 19:40:07 +00008913 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008914 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008915 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008916 if (m == NULL)
8917 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008918
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008919 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008920 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008921 Py_XINCREF(v);
8922 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008923 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008924 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008925
Fred Drake4d1e64b2002-04-15 19:40:07 +00008926 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008927 return;
8928
Fred Drake4d1e64b2002-04-15 19:40:07 +00008929 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008930 return;
8931
Fred Drake4d1e64b2002-04-15 19:40:07 +00008932 Py_INCREF(PyExc_OSError);
8933 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008934
Guido van Rossumb3d39562000-01-31 18:41:26 +00008935#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008936 if (posix_putenv_garbage == NULL)
8937 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008938#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008939
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00008940 if (!initialized) {
8941 stat_result_desc.name = MODNAME ".stat_result";
8942 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8943 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8944 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8945 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8946 structseq_new = StatResultType.tp_new;
8947 StatResultType.tp_new = statresult_new;
8948
8949 statvfs_result_desc.name = MODNAME ".statvfs_result";
8950 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
8951 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008952 Py_INCREF((PyObject*) &StatResultType);
8953 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008954 Py_INCREF((PyObject*) &StatVFSResultType);
8955 PyModule_AddObject(m, "statvfs_result",
8956 (PyObject*) &StatVFSResultType);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00008957 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00008958
8959#ifdef __APPLE__
8960 /*
8961 * Step 2 of weak-linking support on Mac OS X.
8962 *
8963 * The code below removes functions that are not available on the
8964 * currently active platform.
8965 *
8966 * This block allow one to use a python binary that was build on
8967 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8968 * OSX 10.4.
8969 */
8970#ifdef HAVE_FSTATVFS
8971 if (fstatvfs == NULL) {
8972 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8973 return;
8974 }
8975 }
8976#endif /* HAVE_FSTATVFS */
8977
8978#ifdef HAVE_STATVFS
8979 if (statvfs == NULL) {
8980 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8981 return;
8982 }
8983 }
8984#endif /* HAVE_STATVFS */
8985
8986# ifdef HAVE_LCHOWN
8987 if (lchown == NULL) {
8988 if (PyObject_DelAttrString(m, "lchown") == -1) {
8989 return;
8990 }
8991 }
8992#endif /* HAVE_LCHOWN */
8993
8994
8995#endif /* __APPLE__ */
8996
Guido van Rossumb6775db1994-08-01 11:34:53 +00008997}
Anthony Baxterac6bd462006-04-13 02:06:09 +00008998
8999#ifdef __cplusplus
9000}
9001#endif
9002
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009003