blob: f18e1546eb0b3ae14720e5e5aaeb70dfed619be7 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Ronald Oussorend06b6f22006-04-23 11:59:25 +000016#ifdef __APPLE__
17 /*
18 * Step 1 of support for weak-linking a number of symbols existing on
19 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
20 * at the end of this file for more information.
21 */
22# pragma weak lchown
23# pragma weak statvfs
24# pragma weak fstatvfs
25
26#endif /* __APPLE__ */
27
Thomas Wouters68bc4f92006-03-01 01:05:10 +000028#define PY_SSIZE_T_CLEAN
29
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000030#include "Python.h"
31#include "structseq.h"
32
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000034# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000035#endif /* defined(__VMS) */
36
Anthony Baxterac6bd462006-04-13 02:06:09 +000037#ifdef __cplusplus
38extern "C" {
39#endif
40
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000041PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000042"This module provides access to operating system functionality that is\n\
43standardized by the C Standard and the POSIX standard (a thinly\n\
44disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000045corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000047#ifndef Py_USING_UNICODE
48/* This is used in signatures of functions. */
49#define Py_UNICODE void
50#endif
51
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000052#if defined(PYOS_OS2)
53#define INCL_DOS
54#define INCL_DOSERRORS
55#define INCL_DOSPROCESS
56#define INCL_NOPMAPI
57#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000058#if defined(PYCC_GCC)
59#include <ctype.h>
60#include <io.h>
61#include <stdio.h>
62#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000063#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000064#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000065#endif
66
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000067#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000068#include <sys/types.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000069#endif /* HAVE_SYS_TYPES_H */
70
71#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000072#include <sys/stat.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000073#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000074
Guido van Rossum36bc6801995-06-14 22:54:23 +000075#ifdef HAVE_SYS_WAIT_H
76#include <sys/wait.h> /* For WNOHANG */
77#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000078
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000079#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000080#include <signal.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000081#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000082
Guido van Rossumb6775db1994-08-01 11:34:53 +000083#ifdef HAVE_FCNTL_H
84#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000085#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000086
Guido van Rossuma6535fd2001-10-18 19:44:10 +000087#ifdef HAVE_GRP_H
88#include <grp.h>
89#endif
90
Barry Warsaw5676bd12003-01-07 20:57:09 +000091#ifdef HAVE_SYSEXITS_H
92#include <sysexits.h>
93#endif /* HAVE_SYSEXITS_H */
94
Anthony Baxter8a560de2004-10-13 15:30:56 +000095#ifdef HAVE_SYS_LOADAVG_H
96#include <sys/loadavg.h>
97#endif
98
Guido van Rossuma4916fa1996-05-23 22:58:55 +000099/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000100/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000101#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000102#include <process.h>
103#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000104#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000105#define HAVE_GETCWD 1
106#define HAVE_OPENDIR 1
107#define HAVE_SYSTEM 1
108#if defined(__OS2__)
109#define HAVE_EXECV 1
110#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000111#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000112#include <process.h>
113#else
114#ifdef __BORLANDC__ /* Borland compiler */
115#define HAVE_EXECV 1
116#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000117#define HAVE_OPENDIR 1
118#define HAVE_PIPE 1
119#define HAVE_POPEN 1
120#define HAVE_SYSTEM 1
121#define HAVE_WAIT 1
122#else
123#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000124#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000125#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000126#define HAVE_EXECV 1
127#define HAVE_PIPE 1
128#define HAVE_POPEN 1
129#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000130#define HAVE_CWAIT 1
Tim Peters11b23062003-04-23 02:39:17 +0000131#define HAVE_FSYNC 1
132#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000133#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000134#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
135/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000136#else /* all other compilers */
137/* Unix functions that the configure script doesn't check for */
138#define HAVE_EXECV 1
139#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000140#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
141#define HAVE_FORK1 1
142#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000143#define HAVE_GETCWD 1
144#define HAVE_GETEGID 1
145#define HAVE_GETEUID 1
146#define HAVE_GETGID 1
147#define HAVE_GETPPID 1
148#define HAVE_GETUID 1
149#define HAVE_KILL 1
150#define HAVE_OPENDIR 1
151#define HAVE_PIPE 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000152#ifndef __rtems__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#define HAVE_POPEN 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000154#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#define HAVE_SYSTEM 1
156#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000157#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000158#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000159#endif /* _MSC_VER */
160#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000161#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000162#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000163
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000164#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000165
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000166#if defined(__sgi)&&_COMPILER_VERSION>=700
167/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
168 (default) */
169extern char *ctermid_r(char *);
170#endif
171
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000172#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000173#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000174extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000175#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000176#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000177extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000178#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000179extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000180#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000181#endif
182#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000183extern int chdir(char *);
184extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000185#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000186extern int chdir(const char *);
187extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000188#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000189#ifdef __BORLANDC__
190extern int chmod(const char *, int);
191#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000192extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000193#endif
Christian Heimes36281872007-11-30 21:11:28 +0000194/*#ifdef HAVE_FCHMOD
195extern int fchmod(int, mode_t);
196#endif*/
197/*#ifdef HAVE_LCHMOD
198extern int lchmod(const char *, mode_t);
199#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000200extern int chown(const char *, uid_t, gid_t);
201extern char *getcwd(char *, int);
202extern char *strerror(int);
203extern int link(const char *, const char *);
204extern int rename(const char *, const char *);
205extern int stat(const char *, struct stat *);
206extern int unlink(const char *);
207extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000209extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000210#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000212extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000213#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000215
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000216#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000217
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218#ifdef HAVE_UTIME_H
219#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000220#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000222#ifdef HAVE_SYS_UTIME_H
223#include <sys/utime.h>
224#define HAVE_UTIME_H /* pretend we do for the rest of this file */
225#endif /* HAVE_SYS_UTIME_H */
226
Guido van Rossumb6775db1994-08-01 11:34:53 +0000227#ifdef HAVE_SYS_TIMES_H
228#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000229#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000230
231#ifdef HAVE_SYS_PARAM_H
232#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000233#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234
235#ifdef HAVE_SYS_UTSNAME_H
236#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000237#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000239#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000240#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000241#define NAMLEN(dirent) strlen((dirent)->d_name)
242#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000243#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000244#include <direct.h>
245#define NAMLEN(dirent) strlen((dirent)->d_name)
246#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000248#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000249#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000250#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000252#endif
253#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000255#endif
256#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000258#endif
259#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000261#ifdef _MSC_VER
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000262#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#include <direct.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000264#endif
265#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000266#include <io.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000267#endif
268#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000269#include <process.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000270#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000271#include "osdefs.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000273#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000274#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000275#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000276#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277
Guido van Rossumd48f2521997-12-05 22:19:34 +0000278#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000279#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000280#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000281
Tim Petersbc2e10e2002-03-03 23:17:02 +0000282#ifndef MAXPATHLEN
Thomas Wouters1ddba602006-04-25 15:29:46 +0000283#if defined(PATH_MAX) && PATH_MAX > 1024
284#define MAXPATHLEN PATH_MAX
285#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000286#define MAXPATHLEN 1024
Thomas Wouters1ddba602006-04-25 15:29:46 +0000287#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000288#endif /* MAXPATHLEN */
289
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000290#ifdef UNION_WAIT
291/* Emulate some macros on systems that have a union instead of macros */
292
293#ifndef WIFEXITED
294#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
295#endif
296
297#ifndef WEXITSTATUS
298#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
299#endif
300
301#ifndef WTERMSIG
302#define WTERMSIG(u_wait) ((u_wait).w_termsig)
303#endif
304
Neal Norwitzd5a37542006-03-20 06:48:34 +0000305#define WAIT_TYPE union wait
306#define WAIT_STATUS_INT(s) (s.w_status)
307
308#else /* !UNION_WAIT */
309#define WAIT_TYPE int
310#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000311#endif /* UNION_WAIT */
312
Greg Wardb48bc172000-03-01 21:51:56 +0000313/* Don't use the "_r" form if we don't need it (also, won't have a
314 prototype for it, at least on Solaris -- maybe others as well?). */
315#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
316#define USE_CTERMID_R
317#endif
318
319#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
320#define USE_TMPNAM_R
321#endif
322
Fred Drake699f3522000-06-29 21:12:41 +0000323/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000324#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000325#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000326# define STAT win32_stat
327# define FSTAT win32_fstat
328# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000329#else
330# define STAT stat
331# define FSTAT fstat
332# define STRUCT_STAT struct stat
333#endif
334
Tim Peters11b23062003-04-23 02:39:17 +0000335#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000336#include <sys/mkdev.h>
337#else
338#if defined(MAJOR_IN_SYSMACROS)
339#include <sys/sysmacros.h>
340#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000341#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
342#include <sys/mkdev.h>
343#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000344#endif
Fred Drake699f3522000-06-29 21:12:41 +0000345
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000346/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000347#ifdef WITH_NEXT_FRAMEWORK
348/* On Darwin/MacOSX a shared library or framework has no access to
349** environ directly, we must obtain it with _NSGetEnviron().
350*/
351#include <crt_externs.h>
352static char **environ;
353#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000354extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000355#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000356
Barry Warsaw53699e91996-12-10 23:23:01 +0000357static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000358convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000359{
Barry Warsaw53699e91996-12-10 23:23:01 +0000360 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000361 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000362 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000363 if (d == NULL)
364 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000365#ifdef WITH_NEXT_FRAMEWORK
366 if (environ == NULL)
367 environ = *_NSGetEnviron();
368#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000369 if (environ == NULL)
370 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000371 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000372 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000373 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000374 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000375 char *p = strchr(*e, '=');
376 if (p == NULL)
377 continue;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000378 k = PyString_FromStringAndSize(*e, (int)(p-*e));
Guido van Rossum6a619f41999-08-03 19:41:10 +0000379 if (k == NULL) {
380 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000381 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000382 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000383 v = PyString_FromString(p+1);
Guido van Rossum6a619f41999-08-03 19:41:10 +0000384 if (v == NULL) {
385 PyErr_Clear();
386 Py_DECREF(k);
387 continue;
388 }
389 if (PyDict_GetItem(d, k) == NULL) {
390 if (PyDict_SetItem(d, k, v) != 0)
391 PyErr_Clear();
392 }
393 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000394 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000395 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000396#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000397 {
398 APIRET rc;
399 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
400
401 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000402 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000403 PyObject *v = PyString_FromString(buffer);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000404 PyDict_SetItemString(d, "BEGINLIBPATH", v);
405 Py_DECREF(v);
406 }
407 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
408 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000409 PyObject *v = PyString_FromString(buffer);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000410 PyDict_SetItemString(d, "ENDLIBPATH", v);
411 Py_DECREF(v);
412 }
413 }
414#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000415 return d;
416}
417
418
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000419/* Set a POSIX-specific error from errno, and return NULL */
420
Barry Warsawd58d7641998-07-23 16:14:40 +0000421static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000422posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000423{
Barry Warsawca74da41999-02-09 19:31:45 +0000424 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000425}
Barry Warsawd58d7641998-07-23 16:14:40 +0000426static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000427posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000428{
Barry Warsawca74da41999-02-09 19:31:45 +0000429 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000430}
431
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000432#ifdef Py_WIN_WIDE_FILENAMES
433static PyObject *
434posix_error_with_unicode_filename(Py_UNICODE* name)
435{
436 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
437}
438#endif /* Py_WIN_WIDE_FILENAMES */
439
440
Mark Hammondef8b6542001-05-13 08:04:26 +0000441static PyObject *
442posix_error_with_allocated_filename(char* name)
443{
444 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
445 PyMem_Free(name);
446 return rc;
447}
448
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000449#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000450static PyObject *
451win32_error(char* function, char* filename)
452{
Mark Hammond33a6da92000-08-15 00:46:38 +0000453 /* XXX We should pass the function name along in the future.
454 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000455 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000456 Windows error object, which is non-trivial.
457 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000458 errno = GetLastError();
459 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000460 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000461 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000462 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000463}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000464
465#ifdef Py_WIN_WIDE_FILENAMES
466static PyObject *
467win32_error_unicode(char* function, Py_UNICODE* filename)
468{
469 /* XXX - see win32_error for comments on 'function' */
470 errno = GetLastError();
471 if (filename)
472 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
473 else
474 return PyErr_SetFromWindowsErr(errno);
475}
476
477static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
478{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000479}
480
481/* Function suitable for O& conversion */
482static int
483convert_to_unicode(PyObject *arg, void* _param)
484{
485 PyObject **param = (PyObject**)_param;
486 if (PyUnicode_CheckExact(arg)) {
487 Py_INCREF(arg);
488 *param = arg;
489 }
490 else if (PyUnicode_Check(arg)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000491 /* For a Unicode subtype that's not a Unicode object,
492 return a true Unicode object with the same data. */
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000493 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(arg),
494 PyUnicode_GET_SIZE(arg));
495 return *param != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000496 }
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000497 else
498 *param = PyUnicode_FromEncodedObject(arg,
499 Py_FileSystemDefaultEncoding,
500 "strict");
501 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000502}
503
504#endif /* Py_WIN_WIDE_FILENAMES */
505
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000506#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000507
Guido van Rossumd48f2521997-12-05 22:19:34 +0000508#if defined(PYOS_OS2)
509/**********************************************************************
510 * Helper Function to Trim and Format OS/2 Messages
511 **********************************************************************/
512 static void
513os2_formatmsg(char *msgbuf, int msglen, char *reason)
514{
515 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
516
517 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
518 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
519
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000520 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000521 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
522 }
523
524 /* Add Optional Reason Text */
525 if (reason) {
526 strcat(msgbuf, " : ");
527 strcat(msgbuf, reason);
528 }
529}
530
531/**********************************************************************
532 * Decode an OS/2 Operating System Error Code
533 *
534 * A convenience function to lookup an OS/2 error code and return a
535 * text message we can use to raise a Python exception.
536 *
537 * Notes:
538 * The messages for errors returned from the OS/2 kernel reside in
539 * the file OSO001.MSG in the \OS2 directory hierarchy.
540 *
541 **********************************************************************/
542 static char *
543os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
544{
545 APIRET rc;
546 ULONG msglen;
547
548 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
549 Py_BEGIN_ALLOW_THREADS
550 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
551 errorcode, "oso001.msg", &msglen);
552 Py_END_ALLOW_THREADS
553
554 if (rc == NO_ERROR)
555 os2_formatmsg(msgbuf, msglen, reason);
556 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000557 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000558 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000559
560 return msgbuf;
561}
562
563/* Set an OS/2-specific error and return NULL. OS/2 kernel
564 errors are not in a global variable e.g. 'errno' nor are
565 they congruent with posix error numbers. */
566
567static PyObject * os2_error(int code)
568{
569 char text[1024];
570 PyObject *v;
571
572 os2_strerror(text, sizeof(text), code, "");
573
574 v = Py_BuildValue("(is)", code, text);
575 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000576 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000577 Py_DECREF(v);
578 }
579 return NULL; /* Signal to Python that an Exception is Pending */
580}
581
582#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000583
584/* POSIX generic methods */
585
Barry Warsaw53699e91996-12-10 23:23:01 +0000586static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000587posix_fildes(PyObject *fdobj, int (*func)(int))
588{
589 int fd;
590 int res;
591 fd = PyObject_AsFileDescriptor(fdobj);
592 if (fd < 0)
593 return NULL;
594 Py_BEGIN_ALLOW_THREADS
595 res = (*func)(fd);
596 Py_END_ALLOW_THREADS
597 if (res < 0)
598 return posix_error();
599 Py_INCREF(Py_None);
600 return Py_None;
601}
Guido van Rossum21142a01999-01-08 21:05:37 +0000602
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000603#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000604static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000605unicode_file_names(void)
606{
607 static int canusewide = -1;
608 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000609 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000610 the Windows NT family. */
611 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
612 }
613 return canusewide;
614}
615#endif
Tim Peters11b23062003-04-23 02:39:17 +0000616
Guido van Rossum21142a01999-01-08 21:05:37 +0000617static PyObject *
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000618posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000619{
Mark Hammondef8b6542001-05-13 08:04:26 +0000620 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000621 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000622 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000623 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000624 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000625 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000626 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000627 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000628 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000629 return posix_error_with_allocated_filename(path1);
630 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000631 Py_INCREF(Py_None);
632 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000633}
634
Barry Warsaw53699e91996-12-10 23:23:01 +0000635static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000636posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000637 char *format,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000638 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000639{
Mark Hammondef8b6542001-05-13 08:04:26 +0000640 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000641 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000642 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000643 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000644 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000645 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000646 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000647 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000648 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000649 PyMem_Free(path1);
650 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000651 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000652 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000653 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000654 Py_INCREF(Py_None);
655 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000656}
657
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000658#ifdef Py_WIN_WIDE_FILENAMES
659static PyObject*
660win32_1str(PyObject* args, char* func,
661 char* format, BOOL (__stdcall *funcA)(LPCSTR),
662 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
663{
664 PyObject *uni;
665 char *ansi;
666 BOOL result;
667 if (unicode_file_names()) {
668 if (!PyArg_ParseTuple(args, wformat, &uni))
669 PyErr_Clear();
670 else {
671 Py_BEGIN_ALLOW_THREADS
672 result = funcW(PyUnicode_AsUnicode(uni));
673 Py_END_ALLOW_THREADS
674 if (!result)
675 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
676 Py_INCREF(Py_None);
677 return Py_None;
678 }
679 }
680 if (!PyArg_ParseTuple(args, format, &ansi))
681 return NULL;
682 Py_BEGIN_ALLOW_THREADS
683 result = funcA(ansi);
684 Py_END_ALLOW_THREADS
685 if (!result)
686 return win32_error(func, ansi);
687 Py_INCREF(Py_None);
688 return Py_None;
689
690}
691
692/* This is a reimplementation of the C library's chdir function,
693 but one that produces Win32 errors instead of DOS error codes.
694 chdir is essentially a wrapper around SetCurrentDirectory; however,
695 it also needs to set "magic" environment variables indicating
696 the per-drive current directory, which are of the form =<drive>: */
697BOOL __stdcall
698win32_chdir(LPCSTR path)
699{
700 char new_path[MAX_PATH+1];
701 int result;
702 char env[4] = "=x:";
703
704 if(!SetCurrentDirectoryA(path))
705 return FALSE;
706 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
707 if (!result)
708 return FALSE;
709 /* In the ANSI API, there should not be any paths longer
710 than MAX_PATH. */
711 assert(result <= MAX_PATH+1);
712 if (strncmp(new_path, "\\\\", 2) == 0 ||
713 strncmp(new_path, "//", 2) == 0)
714 /* UNC path, nothing to do. */
715 return TRUE;
716 env[1] = new_path[0];
717 return SetEnvironmentVariableA(env, new_path);
718}
719
720/* The Unicode version differs from the ANSI version
721 since the current directory might exceed MAX_PATH characters */
722BOOL __stdcall
723win32_wchdir(LPCWSTR path)
724{
725 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
726 int result;
727 wchar_t env[4] = L"=x:";
728
729 if(!SetCurrentDirectoryW(path))
730 return FALSE;
731 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
732 if (!result)
733 return FALSE;
734 if (result > MAX_PATH+1) {
735 new_path = malloc(result);
736 if (!new_path) {
737 SetLastError(ERROR_OUTOFMEMORY);
738 return FALSE;
739 }
740 }
741 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
742 wcsncmp(new_path, L"//", 2) == 0)
743 /* UNC path, nothing to do. */
744 return TRUE;
745 env[1] = new_path[0];
746 result = SetEnvironmentVariableW(env, new_path);
747 if (new_path != _new_path)
748 free(new_path);
749 return result;
750}
751#endif
752
Martin v. Löwis14694662006-02-03 12:54:16 +0000753#ifdef MS_WINDOWS
754/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
755 - time stamps are restricted to second resolution
756 - file modification times suffer from forth-and-back conversions between
757 UTC and local time
758 Therefore, we implement our own stat, based on the Win32 API directly.
759*/
760#define HAVE_STAT_NSEC 1
761
762struct win32_stat{
763 int st_dev;
764 __int64 st_ino;
765 unsigned short st_mode;
766 int st_nlink;
767 int st_uid;
768 int st_gid;
769 int st_rdev;
770 __int64 st_size;
771 int st_atime;
772 int st_atime_nsec;
773 int st_mtime;
774 int st_mtime_nsec;
775 int st_ctime;
776 int st_ctime_nsec;
777};
778
779static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
780
781static void
782FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
783{
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000784 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
785 /* Cannot simply cast and dereference in_ptr,
786 since it might not be aligned properly */
787 __int64 in;
788 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000789 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
790 /* XXX Win32 supports time stamps past 2038; we currently don't */
791 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
792}
793
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000794static void
795time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
796{
797 /* XXX endianness */
798 __int64 out;
799 out = time_in + secs_between_epochs;
Martin v. Löwisf43893a2006-10-09 20:44:25 +0000800 out = out * 10000000 + nsec_in / 100;
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000801 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000802}
803
Martin v. Löwis14694662006-02-03 12:54:16 +0000804/* Below, we *know* that ugo+r is 0444 */
805#if _S_IREAD != 0400
806#error Unsupported C library
807#endif
808static int
809attributes_to_mode(DWORD attr)
810{
811 int m = 0;
812 if (attr & FILE_ATTRIBUTE_DIRECTORY)
813 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
814 else
815 m |= _S_IFREG;
816 if (attr & FILE_ATTRIBUTE_READONLY)
817 m |= 0444;
818 else
819 m |= 0666;
820 return m;
821}
822
823static int
824attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
825{
826 memset(result, 0, sizeof(*result));
827 result->st_mode = attributes_to_mode(info->dwFileAttributes);
828 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
829 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
830 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
831 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
832
833 return 0;
834}
835
Martin v. Löwis012bc722006-10-15 09:43:39 +0000836/* Emulate GetFileAttributesEx[AW] on Windows 95 */
837static int checked = 0;
838static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
839static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
840static void
841check_gfax()
842{
843 HINSTANCE hKernel32;
844 if (checked)
845 return;
846 checked = 1;
847 hKernel32 = GetModuleHandle("KERNEL32");
848 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
849 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
850}
851
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000852static BOOL
853attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
854{
855 HANDLE hFindFile;
856 WIN32_FIND_DATAA FileData;
857 hFindFile = FindFirstFileA(pszFile, &FileData);
858 if (hFindFile == INVALID_HANDLE_VALUE)
859 return FALSE;
860 FindClose(hFindFile);
861 pfad->dwFileAttributes = FileData.dwFileAttributes;
862 pfad->ftCreationTime = FileData.ftCreationTime;
863 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
864 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
865 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
866 pfad->nFileSizeLow = FileData.nFileSizeLow;
867 return TRUE;
868}
869
870static BOOL
871attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
872{
873 HANDLE hFindFile;
874 WIN32_FIND_DATAW FileData;
875 hFindFile = FindFirstFileW(pszFile, &FileData);
876 if (hFindFile == INVALID_HANDLE_VALUE)
877 return FALSE;
878 FindClose(hFindFile);
879 pfad->dwFileAttributes = FileData.dwFileAttributes;
880 pfad->ftCreationTime = FileData.ftCreationTime;
881 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
882 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
883 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
884 pfad->nFileSizeLow = FileData.nFileSizeLow;
885 return TRUE;
886}
887
Martin v. Löwis012bc722006-10-15 09:43:39 +0000888static BOOL WINAPI
889Py_GetFileAttributesExA(LPCSTR pszFile,
890 GET_FILEEX_INFO_LEVELS level,
891 LPVOID pv)
892{
893 BOOL result;
Martin v. Löwis012bc722006-10-15 09:43:39 +0000894 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
895 /* First try to use the system's implementation, if that is
896 available and either succeeds to gives an error other than
897 that it isn't implemented. */
898 check_gfax();
899 if (gfaxa) {
900 result = gfaxa(pszFile, level, pv);
901 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
902 return result;
903 }
904 /* It's either not present, or not implemented.
905 Emulate using FindFirstFile. */
906 if (level != GetFileExInfoStandard) {
907 SetLastError(ERROR_INVALID_PARAMETER);
908 return FALSE;
909 }
910 /* Use GetFileAttributes to validate that the file name
911 does not contain wildcards (which FindFirstFile would
912 accept). */
913 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
914 return FALSE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000915 return attributes_from_dir(pszFile, pfad);
Martin v. Löwis012bc722006-10-15 09:43:39 +0000916}
917
918static BOOL WINAPI
919Py_GetFileAttributesExW(LPCWSTR pszFile,
920 GET_FILEEX_INFO_LEVELS level,
921 LPVOID pv)
922{
923 BOOL result;
Martin v. Löwis012bc722006-10-15 09:43:39 +0000924 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
925 /* First try to use the system's implementation, if that is
926 available and either succeeds to gives an error other than
927 that it isn't implemented. */
928 check_gfax();
929 if (gfaxa) {
930 result = gfaxw(pszFile, level, pv);
931 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
932 return result;
933 }
934 /* It's either not present, or not implemented.
935 Emulate using FindFirstFile. */
936 if (level != GetFileExInfoStandard) {
937 SetLastError(ERROR_INVALID_PARAMETER);
938 return FALSE;
939 }
940 /* Use GetFileAttributes to validate that the file name
941 does not contain wildcards (which FindFirstFile would
942 accept). */
943 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
944 return FALSE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000945 return attributes_from_dir_w(pszFile, pfad);
Martin v. Löwis012bc722006-10-15 09:43:39 +0000946}
947
Martin v. Löwis14694662006-02-03 12:54:16 +0000948static int
949win32_stat(const char* path, struct win32_stat *result)
950{
951 WIN32_FILE_ATTRIBUTE_DATA info;
952 int code;
953 char *dot;
954 /* XXX not supported on Win95 and NT 3.x */
Martin v. Löwis012bc722006-10-15 09:43:39 +0000955 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000956 if (GetLastError() != ERROR_SHARING_VIOLATION) {
957 /* Protocol violation: we explicitly clear errno, instead of
958 setting it to a POSIX error. Callers should use GetLastError. */
959 errno = 0;
960 return -1;
961 } else {
962 /* Could not get attributes on open file. Fall back to
963 reading the directory. */
964 if (!attributes_from_dir(path, &info)) {
965 /* Very strange. This should not fail now */
966 errno = 0;
967 return -1;
968 }
969 }
Martin v. Löwis14694662006-02-03 12:54:16 +0000970 }
971 code = attribute_data_to_stat(&info, result);
972 if (code != 0)
973 return code;
974 /* Set S_IFEXEC if it is an .exe, .bat, ... */
975 dot = strrchr(path, '.');
976 if (dot) {
977 if (stricmp(dot, ".bat") == 0 ||
978 stricmp(dot, ".cmd") == 0 ||
979 stricmp(dot, ".exe") == 0 ||
980 stricmp(dot, ".com") == 0)
981 result->st_mode |= 0111;
982 }
983 return code;
984}
985
986static int
987win32_wstat(const wchar_t* path, struct win32_stat *result)
988{
989 int code;
990 const wchar_t *dot;
991 WIN32_FILE_ATTRIBUTE_DATA info;
992 /* XXX not supported on Win95 and NT 3.x */
Martin v. Löwis012bc722006-10-15 09:43:39 +0000993 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000994 if (GetLastError() != ERROR_SHARING_VIOLATION) {
995 /* Protocol violation: we explicitly clear errno, instead of
996 setting it to a POSIX error. Callers should use GetLastError. */
997 errno = 0;
998 return -1;
999 } else {
1000 /* Could not get attributes on open file. Fall back to
1001 reading the directory. */
1002 if (!attributes_from_dir_w(path, &info)) {
1003 /* Very strange. This should not fail now */
1004 errno = 0;
1005 return -1;
1006 }
1007 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001008 }
1009 code = attribute_data_to_stat(&info, result);
1010 if (code < 0)
1011 return code;
1012 /* Set IFEXEC if it is an .exe, .bat, ... */
1013 dot = wcsrchr(path, '.');
1014 if (dot) {
1015 if (_wcsicmp(dot, L".bat") == 0 ||
1016 _wcsicmp(dot, L".cmd") == 0 ||
1017 _wcsicmp(dot, L".exe") == 0 ||
1018 _wcsicmp(dot, L".com") == 0)
1019 result->st_mode |= 0111;
1020 }
1021 return code;
1022}
1023
1024static int
1025win32_fstat(int file_number, struct win32_stat *result)
1026{
1027 BY_HANDLE_FILE_INFORMATION info;
1028 HANDLE h;
1029 int type;
1030
1031 h = (HANDLE)_get_osfhandle(file_number);
1032
1033 /* Protocol violation: we explicitly clear errno, instead of
1034 setting it to a POSIX error. Callers should use GetLastError. */
1035 errno = 0;
1036
1037 if (h == INVALID_HANDLE_VALUE) {
1038 /* This is really a C library error (invalid file handle).
1039 We set the Win32 error to the closes one matching. */
1040 SetLastError(ERROR_INVALID_HANDLE);
1041 return -1;
1042 }
1043 memset(result, 0, sizeof(*result));
1044
1045 type = GetFileType(h);
1046 if (type == FILE_TYPE_UNKNOWN) {
1047 DWORD error = GetLastError();
1048 if (error != 0) {
1049 return -1;
1050 }
1051 /* else: valid but unknown file */
1052 }
1053
1054 if (type != FILE_TYPE_DISK) {
1055 if (type == FILE_TYPE_CHAR)
1056 result->st_mode = _S_IFCHR;
1057 else if (type == FILE_TYPE_PIPE)
1058 result->st_mode = _S_IFIFO;
1059 return 0;
1060 }
1061
1062 if (!GetFileInformationByHandle(h, &info)) {
1063 return -1;
1064 }
1065
1066 /* similar to stat() */
1067 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1068 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1069 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1070 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1071 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1072 /* specific to fstat() */
1073 result->st_nlink = info.nNumberOfLinks;
1074 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1075 return 0;
1076}
1077
1078#endif /* MS_WINDOWS */
1079
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001080PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001081"stat_result: Result from stat or lstat.\n\n\
1082This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001083 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001084or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1085\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001086Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1087or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001088\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001089See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001090
1091static PyStructSequence_Field stat_result_fields[] = {
1092 {"st_mode", "protection bits"},
1093 {"st_ino", "inode"},
1094 {"st_dev", "device"},
1095 {"st_nlink", "number of hard links"},
1096 {"st_uid", "user ID of owner"},
1097 {"st_gid", "group ID of owner"},
1098 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001099 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1100 {NULL, "integer time of last access"},
1101 {NULL, "integer time of last modification"},
1102 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001103 {"st_atime", "time of last access"},
1104 {"st_mtime", "time of last modification"},
1105 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001106#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001107 {"st_blksize", "blocksize for filesystem I/O"},
1108#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001109#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001110 {"st_blocks", "number of blocks allocated"},
1111#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001112#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001113 {"st_rdev", "device type (if inode device)"},
1114#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001115#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1116 {"st_flags", "user defined flags for file"},
1117#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001118#ifdef HAVE_STRUCT_STAT_ST_GEN
1119 {"st_gen", "generation number"},
1120#endif
1121#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1122 {"st_birthtime", "time of creation"},
1123#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001124 {0}
1125};
1126
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001127#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001128#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001129#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001130#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001131#endif
1132
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001133#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001134#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1135#else
1136#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1137#endif
1138
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001139#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001140#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1141#else
1142#define ST_RDEV_IDX ST_BLOCKS_IDX
1143#endif
1144
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001145#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1146#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1147#else
1148#define ST_FLAGS_IDX ST_RDEV_IDX
1149#endif
1150
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001151#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001152#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001153#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001154#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001155#endif
1156
1157#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1158#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1159#else
1160#define ST_BIRTHTIME_IDX ST_GEN_IDX
1161#endif
1162
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001163static PyStructSequence_Desc stat_result_desc = {
1164 "stat_result", /* name */
1165 stat_result__doc__, /* doc */
1166 stat_result_fields,
1167 10
1168};
1169
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001170PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001171"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1172This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001173 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001174or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001175\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001176See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001177
1178static PyStructSequence_Field statvfs_result_fields[] = {
1179 {"f_bsize", },
1180 {"f_frsize", },
1181 {"f_blocks", },
1182 {"f_bfree", },
1183 {"f_bavail", },
1184 {"f_files", },
1185 {"f_ffree", },
1186 {"f_favail", },
1187 {"f_flag", },
1188 {"f_namemax",},
1189 {0}
1190};
1191
1192static PyStructSequence_Desc statvfs_result_desc = {
1193 "statvfs_result", /* name */
1194 statvfs_result__doc__, /* doc */
1195 statvfs_result_fields,
1196 10
1197};
1198
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001199static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001200static PyTypeObject StatResultType;
1201static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001202static newfunc structseq_new;
1203
1204static PyObject *
1205statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1206{
1207 PyStructSequence *result;
1208 int i;
1209
1210 result = (PyStructSequence*)structseq_new(type, args, kwds);
1211 if (!result)
1212 return NULL;
1213 /* If we have been initialized from a tuple,
1214 st_?time might be set to None. Initialize it
1215 from the int slots. */
1216 for (i = 7; i <= 9; i++) {
1217 if (result->ob_item[i+3] == Py_None) {
1218 Py_DECREF(Py_None);
1219 Py_INCREF(result->ob_item[i]);
1220 result->ob_item[i+3] = result->ob_item[i];
1221 }
1222 }
1223 return (PyObject*)result;
1224}
1225
1226
1227
1228/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001229static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001230
1231PyDoc_STRVAR(stat_float_times__doc__,
1232"stat_float_times([newval]) -> oldval\n\n\
1233Determine whether os.[lf]stat represents time stamps as float objects.\n\
1234If newval is True, future calls to stat() return floats, if it is False,\n\
1235future calls return ints. \n\
1236If newval is omitted, return the current setting.\n");
1237
1238static PyObject*
1239stat_float_times(PyObject* self, PyObject *args)
1240{
1241 int newval = -1;
1242 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1243 return NULL;
1244 if (newval == -1)
1245 /* Return old value */
1246 return PyBool_FromLong(_stat_float_times);
1247 _stat_float_times = newval;
1248 Py_INCREF(Py_None);
1249 return Py_None;
1250}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001251
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001252static void
1253fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1254{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001255 PyObject *fval,*ival;
1256#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001257 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001258#else
1259 ival = PyInt_FromLong((long)sec);
1260#endif
Neal Norwitze0a81af2006-08-12 01:50:38 +00001261 if (!ival)
1262 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001263 if (_stat_float_times) {
1264 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1265 } else {
1266 fval = ival;
1267 Py_INCREF(fval);
1268 }
1269 PyStructSequence_SET_ITEM(v, index, ival);
1270 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001271}
1272
Tim Peters5aa91602002-01-30 05:46:57 +00001273/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001274 (used by posix_stat() and posix_fstat()) */
1275static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001276_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001277{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001278 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001279 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001280 if (v == NULL)
1281 return NULL;
1282
Martin v. Löwis14694662006-02-03 12:54:16 +00001283 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001284#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001285 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001286 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001287#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001288 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001289#endif
1290#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001291 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001292 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001293#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001294 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001295#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001296 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1297 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1298 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001299#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001300 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001301 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001302#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001303 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001304#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001305
Martin v. Löwis14694662006-02-03 12:54:16 +00001306#if defined(HAVE_STAT_TV_NSEC)
1307 ansec = st->st_atim.tv_nsec;
1308 mnsec = st->st_mtim.tv_nsec;
1309 cnsec = st->st_ctim.tv_nsec;
1310#elif defined(HAVE_STAT_TV_NSEC2)
1311 ansec = st->st_atimespec.tv_nsec;
1312 mnsec = st->st_mtimespec.tv_nsec;
1313 cnsec = st->st_ctimespec.tv_nsec;
1314#elif defined(HAVE_STAT_NSEC)
1315 ansec = st->st_atime_nsec;
1316 mnsec = st->st_mtime_nsec;
1317 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001318#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001319 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001320#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001321 fill_time(v, 7, st->st_atime, ansec);
1322 fill_time(v, 8, st->st_mtime, mnsec);
1323 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001324
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001325#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001326 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001327 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001328#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001329#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001330 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001331 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001332#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001333#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001334 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001335 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001336#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001337#ifdef HAVE_STRUCT_STAT_ST_GEN
1338 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001339 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001340#endif
1341#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1342 {
1343 PyObject *val;
1344 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001345 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001346#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001347 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001348#else
1349 bnsec = 0;
1350#endif
1351 if (_stat_float_times) {
1352 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1353 } else {
1354 val = PyInt_FromLong((long)bsec);
1355 }
1356 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1357 val);
1358 }
1359#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001360#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1361 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001362 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001363#endif
Fred Drake699f3522000-06-29 21:12:41 +00001364
1365 if (PyErr_Occurred()) {
1366 Py_DECREF(v);
1367 return NULL;
1368 }
1369
1370 return v;
1371}
1372
Martin v. Löwisd8948722004-06-02 09:57:56 +00001373#ifdef MS_WINDOWS
1374
1375/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1376 where / can be used in place of \ and the trailing slash is optional.
1377 Both SERVER and SHARE must have at least one character.
1378*/
1379
1380#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1381#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001382#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001383#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001384#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001385
Tim Peters4ad82172004-08-30 17:02:04 +00001386static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001387IsUNCRootA(char *path, int pathlen)
1388{
1389 #define ISSLASH ISSLASHA
1390
1391 int i, share;
1392
1393 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1394 /* minimum UNCRoot is \\x\y */
1395 return FALSE;
1396 for (i = 2; i < pathlen ; i++)
1397 if (ISSLASH(path[i])) break;
1398 if (i == 2 || i == pathlen)
1399 /* do not allow \\\SHARE or \\SERVER */
1400 return FALSE;
1401 share = i+1;
1402 for (i = share; i < pathlen; i++)
1403 if (ISSLASH(path[i])) break;
1404 return (i != share && (i == pathlen || i == pathlen-1));
1405
1406 #undef ISSLASH
1407}
1408
1409#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001410static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001411IsUNCRootW(Py_UNICODE *path, int pathlen)
1412{
1413 #define ISSLASH ISSLASHW
1414
1415 int i, share;
1416
1417 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1418 /* minimum UNCRoot is \\x\y */
1419 return FALSE;
1420 for (i = 2; i < pathlen ; i++)
1421 if (ISSLASH(path[i])) break;
1422 if (i == 2 || i == pathlen)
1423 /* do not allow \\\SHARE or \\SERVER */
1424 return FALSE;
1425 share = i+1;
1426 for (i = share; i < pathlen; i++)
1427 if (ISSLASH(path[i])) break;
1428 return (i != share && (i == pathlen || i == pathlen-1));
1429
1430 #undef ISSLASH
1431}
1432#endif /* Py_WIN_WIDE_FILENAMES */
1433#endif /* MS_WINDOWS */
1434
Barry Warsaw53699e91996-12-10 23:23:01 +00001435static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001436posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001437 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001438#ifdef __VMS
1439 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1440#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001441 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001442#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001443 char *wformat,
1444 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001445{
Fred Drake699f3522000-06-29 21:12:41 +00001446 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001447 char *path = NULL; /* pass this to stat; do not free() it */
1448 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001449 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001450 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001451
1452#ifdef Py_WIN_WIDE_FILENAMES
1453 /* If on wide-character-capable OS see if argument
1454 is Unicode and if so use wide API. */
1455 if (unicode_file_names()) {
1456 PyUnicodeObject *po;
1457 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001458 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1459
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001460 Py_BEGIN_ALLOW_THREADS
1461 /* PyUnicode_AS_UNICODE result OK without
1462 thread lock as it is a simple dereference. */
1463 res = wstatfunc(wpath, &st);
1464 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001465
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001466 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001467 return win32_error_unicode("stat", wpath);
1468 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001469 }
1470 /* Drop the argument parsing error as narrow strings
1471 are also valid. */
1472 PyErr_Clear();
1473 }
1474#endif
1475
Tim Peters5aa91602002-01-30 05:46:57 +00001476 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001477 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001478 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001479 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001480
Barry Warsaw53699e91996-12-10 23:23:01 +00001481 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001482 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001483 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001484
1485 if (res != 0) {
1486#ifdef MS_WINDOWS
1487 result = win32_error("stat", pathfree);
1488#else
1489 result = posix_error_with_filename(pathfree);
1490#endif
1491 }
1492 else
1493 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001494
Tim Peters500bd032001-12-19 19:05:01 +00001495 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001496 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001497}
1498
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001499/* POSIX methods */
1500
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001501PyDoc_STRVAR(posix_access__doc__,
Georg Brandl7a284472007-01-27 19:38:50 +00001502"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001503Use the real uid/gid to test for access to a path. Note that most\n\
1504operations will use the effective uid/gid, therefore this routine can\n\
1505be used in a suid/sgid environment to test if the invoking user has the\n\
1506specified access to the path. The mode argument can be F_OK to test\n\
1507existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001508
1509static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001510posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001511{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001512 char *path;
1513 int mode;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001514
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001515#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001516 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001517 if (unicode_file_names()) {
1518 PyUnicodeObject *po;
1519 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1520 Py_BEGIN_ALLOW_THREADS
1521 /* PyUnicode_AS_UNICODE OK without thread lock as
1522 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001523 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001524 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001525 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001526 }
1527 /* Drop the argument parsing error as narrow strings
1528 are also valid. */
1529 PyErr_Clear();
1530 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001531 if (!PyArg_ParseTuple(args, "eti:access",
1532 Py_FileSystemDefaultEncoding, &path, &mode))
1533 return 0;
1534 Py_BEGIN_ALLOW_THREADS
1535 attr = GetFileAttributesA(path);
1536 Py_END_ALLOW_THREADS
1537 PyMem_Free(path);
1538finish:
1539 if (attr == 0xFFFFFFFF)
1540 /* File does not exist, or cannot read attributes */
1541 return PyBool_FromLong(0);
1542 /* Access is possible if either write access wasn't requested, or
Martin v. Löwis7b3cc062007-12-03 23:09:04 +00001543 the file isn't read-only, or if it's a directory, as there are
1544 no read-only directories on Windows. */
1545 return PyBool_FromLong(!(mode & 2)
1546 || !(attr & FILE_ATTRIBUTE_READONLY)
1547 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001548#else
1549 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001550 if (!PyArg_ParseTuple(args, "eti:access",
1551 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001552 return NULL;
1553 Py_BEGIN_ALLOW_THREADS
1554 res = access(path, mode);
1555 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001556 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001557 return PyBool_FromLong(res == 0);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001558#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001559}
1560
Guido van Rossumd371ff11999-01-25 16:12:23 +00001561#ifndef F_OK
1562#define F_OK 0
1563#endif
1564#ifndef R_OK
1565#define R_OK 4
1566#endif
1567#ifndef W_OK
1568#define W_OK 2
1569#endif
1570#ifndef X_OK
1571#define X_OK 1
1572#endif
1573
1574#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001575PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001576"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001577Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001578
1579static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001580posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001581{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001582 int id;
1583 char *ret;
1584
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001585 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001586 return NULL;
1587
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001588#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001589 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001590 if (id == 0) {
1591 ret = ttyname();
1592 }
1593 else {
1594 ret = NULL;
1595 }
1596#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001597 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001598#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001599 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001600 return posix_error();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001601 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001602}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001603#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001604
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001605#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001606PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001607"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001608Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001609
1610static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001611posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001612{
1613 char *ret;
1614 char buffer[L_ctermid];
1615
Greg Wardb48bc172000-03-01 21:51:56 +00001616#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001617 ret = ctermid_r(buffer);
1618#else
1619 ret = ctermid(buffer);
1620#endif
1621 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001622 return posix_error();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001623 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001624}
1625#endif
1626
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001627PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001628"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001629Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001630
Barry Warsaw53699e91996-12-10 23:23:01 +00001631static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001632posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001633{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001634#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001635 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001636#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001637 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001638#elif defined(__VMS)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001639 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001640#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001641 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001642#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001643}
1644
Fred Drake4d1e64b2002-04-15 19:40:07 +00001645#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001646PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001647"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001648Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001649opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001650
1651static PyObject *
1652posix_fchdir(PyObject *self, PyObject *fdobj)
1653{
1654 return posix_fildes(fdobj, fchdir);
1655}
1656#endif /* HAVE_FCHDIR */
1657
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001658
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001659PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001660"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001661Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001662
Barry Warsaw53699e91996-12-10 23:23:01 +00001663static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001664posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001665{
Mark Hammondef8b6542001-05-13 08:04:26 +00001666 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001667 int i;
1668 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001669#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001670 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001671 if (unicode_file_names()) {
1672 PyUnicodeObject *po;
1673 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1674 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001675 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1676 if (attr != 0xFFFFFFFF) {
1677 if (i & _S_IWRITE)
1678 attr &= ~FILE_ATTRIBUTE_READONLY;
1679 else
1680 attr |= FILE_ATTRIBUTE_READONLY;
1681 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1682 }
1683 else
1684 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001685 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001686 if (!res)
1687 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001688 PyUnicode_AS_UNICODE(po));
1689 Py_INCREF(Py_None);
1690 return Py_None;
1691 }
1692 /* Drop the argument parsing error as narrow strings
1693 are also valid. */
1694 PyErr_Clear();
1695 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001696 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1697 &path, &i))
1698 return NULL;
1699 Py_BEGIN_ALLOW_THREADS
1700 attr = GetFileAttributesA(path);
1701 if (attr != 0xFFFFFFFF) {
1702 if (i & _S_IWRITE)
1703 attr &= ~FILE_ATTRIBUTE_READONLY;
1704 else
1705 attr |= FILE_ATTRIBUTE_READONLY;
1706 res = SetFileAttributesA(path, attr);
1707 }
1708 else
1709 res = 0;
1710 Py_END_ALLOW_THREADS
1711 if (!res) {
1712 win32_error("chmod", path);
1713 PyMem_Free(path);
1714 return NULL;
1715 }
Martin v. Löwis9f485bc2006-05-08 05:25:56 +00001716 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001717 Py_INCREF(Py_None);
1718 return Py_None;
1719#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001720 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001721 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001722 return NULL;
1723 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001724 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001725 Py_END_ALLOW_THREADS
1726 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001727 return posix_error_with_allocated_filename(path);
1728 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001729 Py_INCREF(Py_None);
1730 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001731#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001732}
1733
Christian Heimes36281872007-11-30 21:11:28 +00001734#ifdef HAVE_FCHMOD
1735PyDoc_STRVAR(posix_fchmod__doc__,
1736"fchmod(fd, mode)\n\n\
1737Change the access permissions of the file given by file\n\
1738descriptor fd.");
1739
1740static PyObject *
1741posix_fchmod(PyObject *self, PyObject *args)
1742{
1743 int fd, mode, res;
1744 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1745 return NULL;
1746 Py_BEGIN_ALLOW_THREADS
1747 res = fchmod(fd, mode);
1748 Py_END_ALLOW_THREADS
1749 if (res < 0)
1750 return posix_error();
1751 Py_RETURN_NONE;
1752}
1753#endif /* HAVE_FCHMOD */
1754
1755#ifdef HAVE_LCHMOD
1756PyDoc_STRVAR(posix_lchmod__doc__,
1757"lchmod(path, mode)\n\n\
1758Change the access permissions of a file. If path is a symlink, this\n\
1759affects the link itself rather than the target.");
1760
1761static PyObject *
1762posix_lchmod(PyObject *self, PyObject *args)
1763{
1764 char *path = NULL;
1765 int i;
1766 int res;
1767 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1768 &path, &i))
1769 return NULL;
1770 Py_BEGIN_ALLOW_THREADS
1771 res = lchmod(path, i);
1772 Py_END_ALLOW_THREADS
1773 if (res < 0)
1774 return posix_error_with_allocated_filename(path);
1775 PyMem_Free(path);
1776 Py_RETURN_NONE;
1777}
1778#endif /* HAVE_LCHMOD */
1779
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001780
Martin v. Löwis382abef2007-02-19 10:55:19 +00001781#ifdef HAVE_CHFLAGS
1782PyDoc_STRVAR(posix_chflags__doc__,
1783"chflags(path, flags)\n\n\
1784Set file flags.");
1785
1786static PyObject *
1787posix_chflags(PyObject *self, PyObject *args)
1788{
1789 char *path;
1790 unsigned long flags;
1791 int res;
1792 if (!PyArg_ParseTuple(args, "etk:chflags",
1793 Py_FileSystemDefaultEncoding, &path, &flags))
1794 return NULL;
1795 Py_BEGIN_ALLOW_THREADS
1796 res = chflags(path, flags);
1797 Py_END_ALLOW_THREADS
1798 if (res < 0)
1799 return posix_error_with_allocated_filename(path);
1800 PyMem_Free(path);
1801 Py_INCREF(Py_None);
1802 return Py_None;
1803}
1804#endif /* HAVE_CHFLAGS */
1805
1806#ifdef HAVE_LCHFLAGS
1807PyDoc_STRVAR(posix_lchflags__doc__,
1808"lchflags(path, flags)\n\n\
1809Set file flags.\n\
1810This function will not follow symbolic links.");
1811
1812static PyObject *
1813posix_lchflags(PyObject *self, PyObject *args)
1814{
1815 char *path;
1816 unsigned long flags;
1817 int res;
1818 if (!PyArg_ParseTuple(args, "etk:lchflags",
1819 Py_FileSystemDefaultEncoding, &path, &flags))
1820 return NULL;
1821 Py_BEGIN_ALLOW_THREADS
1822 res = lchflags(path, flags);
1823 Py_END_ALLOW_THREADS
1824 if (res < 0)
1825 return posix_error_with_allocated_filename(path);
1826 PyMem_Free(path);
1827 Py_INCREF(Py_None);
1828 return Py_None;
1829}
1830#endif /* HAVE_LCHFLAGS */
1831
Martin v. Löwis244edc82001-10-04 22:44:26 +00001832#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001833PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001834"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001835Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001836
1837static PyObject *
1838posix_chroot(PyObject *self, PyObject *args)
1839{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001840 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001841}
1842#endif
1843
Guido van Rossum21142a01999-01-08 21:05:37 +00001844#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001845PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001846"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001847force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001848
1849static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001850posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001851{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001852 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001853}
1854#endif /* HAVE_FSYNC */
1855
1856#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001857
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001858#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001859extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1860#endif
1861
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001862PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001863"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001864force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001865 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001866
1867static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001868posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001869{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001870 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001871}
1872#endif /* HAVE_FDATASYNC */
1873
1874
Fredrik Lundh10723342000-07-10 16:38:09 +00001875#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001876PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001877"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001878Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001879
Barry Warsaw53699e91996-12-10 23:23:01 +00001880static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001881posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001882{
Mark Hammondef8b6542001-05-13 08:04:26 +00001883 char *path = NULL;
Gregory P. Smithf48da8f2008-03-18 19:05:32 +00001884 long uid, gid;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001885 int res;
Gregory P. Smithf48da8f2008-03-18 19:05:32 +00001886 if (!PyArg_ParseTuple(args, "etll:chown",
Tim Peters5aa91602002-01-30 05:46:57 +00001887 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001888 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001889 return NULL;
1890 Py_BEGIN_ALLOW_THREADS
1891 res = chown(path, (uid_t) uid, (gid_t) gid);
1892 Py_END_ALLOW_THREADS
1893 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001894 return posix_error_with_allocated_filename(path);
1895 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001896 Py_INCREF(Py_None);
1897 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001898}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001899#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001900
Christian Heimes36281872007-11-30 21:11:28 +00001901#ifdef HAVE_FCHOWN
1902PyDoc_STRVAR(posix_fchown__doc__,
1903"fchown(fd, uid, gid)\n\n\
1904Change the owner and group id of the file given by file descriptor\n\
1905fd to the numeric uid and gid.");
1906
1907static PyObject *
1908posix_fchown(PyObject *self, PyObject *args)
1909{
1910 int fd, uid, gid;
1911 int res;
1912 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
1913 return NULL;
1914 Py_BEGIN_ALLOW_THREADS
1915 res = fchown(fd, (uid_t) uid, (gid_t) gid);
1916 Py_END_ALLOW_THREADS
1917 if (res < 0)
1918 return posix_error();
1919 Py_RETURN_NONE;
1920}
1921#endif /* HAVE_FCHOWN */
1922
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001923#ifdef HAVE_LCHOWN
1924PyDoc_STRVAR(posix_lchown__doc__,
1925"lchown(path, uid, gid)\n\n\
1926Change the owner and group id of path to the numeric uid and gid.\n\
1927This function will not follow symbolic links.");
1928
1929static PyObject *
1930posix_lchown(PyObject *self, PyObject *args)
1931{
1932 char *path = NULL;
1933 int uid, gid;
1934 int res;
1935 if (!PyArg_ParseTuple(args, "etii:lchown",
1936 Py_FileSystemDefaultEncoding, &path,
1937 &uid, &gid))
1938 return NULL;
1939 Py_BEGIN_ALLOW_THREADS
1940 res = lchown(path, (uid_t) uid, (gid_t) gid);
1941 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001942 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001943 return posix_error_with_allocated_filename(path);
1944 PyMem_Free(path);
1945 Py_INCREF(Py_None);
1946 return Py_None;
1947}
1948#endif /* HAVE_LCHOWN */
1949
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001950
Guido van Rossum36bc6801995-06-14 22:54:23 +00001951#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001952PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001953"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001954Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001955
Barry Warsaw53699e91996-12-10 23:23:01 +00001956static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001957posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001958{
Facundo Batista5596b0c2008-06-22 13:36:20 +00001959 int bufsize_incr = 1024;
1960 int bufsize = 0;
1961 char *tmpbuf = NULL;
1962 char *res = NULL;
1963 PyObject *dynamic_return;
Neal Norwitze241ce82003-02-17 18:17:05 +00001964
Barry Warsaw53699e91996-12-10 23:23:01 +00001965 Py_BEGIN_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00001966 do {
1967 bufsize = bufsize + bufsize_incr;
1968 tmpbuf = malloc(bufsize);
1969 if (tmpbuf == NULL) {
1970 break;
1971 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001972#if defined(PYOS_OS2) && defined(PYCC_GCC)
Facundo Batista5596b0c2008-06-22 13:36:20 +00001973 res = _getcwd2(tmpbuf, bufsize);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001974#else
Facundo Batista5596b0c2008-06-22 13:36:20 +00001975 res = getcwd(tmpbuf, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001976#endif
Facundo Batista5596b0c2008-06-22 13:36:20 +00001977
1978 if (res == NULL) {
1979 free(tmpbuf);
1980 }
1981 } while ((res == NULL) && (errno == ERANGE));
Barry Warsaw53699e91996-12-10 23:23:01 +00001982 Py_END_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00001983
Guido van Rossumff4949e1992-08-05 19:58:53 +00001984 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001985 return posix_error();
Facundo Batista5596b0c2008-06-22 13:36:20 +00001986
1987 dynamic_return = PyString_FromString(tmpbuf);
1988 free(tmpbuf);
1989
1990 return dynamic_return;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001991}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001992
Walter Dörwald3b918c32002-11-21 20:18:46 +00001993#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001994PyDoc_STRVAR(posix_getcwdu__doc__,
1995"getcwdu() -> path\n\n\
1996Return a unicode string representing the current working directory.");
1997
1998static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001999posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002000{
2001 char buf[1026];
2002 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002003
2004#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002005 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002006 if (unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002007 wchar_t wbuf[1026];
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002008 wchar_t *wbuf2 = wbuf;
2009 PyObject *resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002010 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002011 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2012 /* If the buffer is large enough, len does not include the
2013 terminating \0. If the buffer is too small, len includes
2014 the space needed for the terminator. */
2015 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2016 wbuf2 = malloc(len * sizeof(wchar_t));
2017 if (wbuf2)
2018 len = GetCurrentDirectoryW(len, wbuf2);
2019 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002020 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002021 if (!wbuf2) {
2022 PyErr_NoMemory();
2023 return NULL;
2024 }
2025 if (!len) {
2026 if (wbuf2 != wbuf) free(wbuf2);
2027 return win32_error("getcwdu", NULL);
2028 }
2029 resobj = PyUnicode_FromWideChar(wbuf2, len);
2030 if (wbuf2 != wbuf) free(wbuf2);
2031 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002032 }
2033#endif
2034
2035 Py_BEGIN_ALLOW_THREADS
2036#if defined(PYOS_OS2) && defined(PYCC_GCC)
2037 res = _getcwd2(buf, sizeof buf);
2038#else
2039 res = getcwd(buf, sizeof buf);
2040#endif
2041 Py_END_ALLOW_THREADS
2042 if (res == NULL)
2043 return posix_error();
2044 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
2045}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002046#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00002047#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002048
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002049
Guido van Rossumb6775db1994-08-01 11:34:53 +00002050#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002051PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002052"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002053Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002054
Barry Warsaw53699e91996-12-10 23:23:01 +00002055static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002056posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002057{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002058 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002059}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002060#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002061
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002062
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002063PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002064"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002065Return a list containing the names of the entries in the directory.\n\
2066\n\
2067 path: path of directory to list\n\
2068\n\
2069The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002070entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002071
Barry Warsaw53699e91996-12-10 23:23:01 +00002072static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002073posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002074{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002075 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002076 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002077#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002078
Barry Warsaw53699e91996-12-10 23:23:01 +00002079 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002080 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002081 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002082 WIN32_FIND_DATA FileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002083 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00002084 char *bufptr = namebuf;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002085 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002086
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002087#ifdef Py_WIN_WIDE_FILENAMES
2088 /* If on wide-character-capable OS see if argument
2089 is Unicode and if so use wide API. */
2090 if (unicode_file_names()) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002091 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002092 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2093 WIN32_FIND_DATAW wFileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002094 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002095 Py_UNICODE wch;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002096 /* Overallocate for \\*.*\0 */
2097 len = PyUnicode_GET_SIZE(po);
2098 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2099 if (!wnamebuf) {
2100 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002101 return NULL;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002102 }
2103 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2104 wch = len > 0 ? wnamebuf[len-1] : '\0';
2105 if (wch != L'/' && wch != L'\\' && wch != L':')
2106 wnamebuf[len++] = L'\\';
2107 wcscpy(wnamebuf + len, L"*.*");
2108 if ((d = PyList_New(0)) == NULL) {
2109 free(wnamebuf);
2110 return NULL;
2111 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002112 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2113 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002114 int error = GetLastError();
2115 if (error == ERROR_FILE_NOT_FOUND) {
2116 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002117 return d;
2118 }
2119 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002120 win32_error_unicode("FindFirstFileW", wnamebuf);
2121 free(wnamebuf);
2122 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002123 }
2124 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002125 /* Skip over . and .. */
2126 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2127 wcscmp(wFileData.cFileName, L"..") != 0) {
2128 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2129 if (v == NULL) {
2130 Py_DECREF(d);
2131 d = NULL;
2132 break;
2133 }
2134 if (PyList_Append(d, v) != 0) {
2135 Py_DECREF(v);
2136 Py_DECREF(d);
2137 d = NULL;
2138 break;
2139 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002140 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002141 }
Georg Brandl622927b2006-03-07 12:48:03 +00002142 Py_BEGIN_ALLOW_THREADS
2143 result = FindNextFileW(hFindFile, &wFileData);
2144 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00002145 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2146 it got to the end of the directory. */
2147 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2148 Py_DECREF(d);
2149 win32_error_unicode("FindNextFileW", wnamebuf);
2150 FindClose(hFindFile);
2151 free(wnamebuf);
2152 return NULL;
2153 }
Georg Brandl622927b2006-03-07 12:48:03 +00002154 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002155
2156 if (FindClose(hFindFile) == FALSE) {
2157 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002158 win32_error_unicode("FindClose", wnamebuf);
2159 free(wnamebuf);
2160 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002161 }
Martin v. Löwise3edaea2006-05-15 05:51:36 +00002162 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002163 return d;
2164 }
2165 /* Drop the argument parsing error as narrow strings
2166 are also valid. */
2167 PyErr_Clear();
2168 }
2169#endif
2170
Tim Peters5aa91602002-01-30 05:46:57 +00002171 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002172 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002173 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002174 if (len > 0) {
2175 char ch = namebuf[len-1];
2176 if (ch != SEP && ch != ALTSEP && ch != ':')
2177 namebuf[len++] = '/';
2178 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002179 strcpy(namebuf + len, "*.*");
2180
Barry Warsaw53699e91996-12-10 23:23:01 +00002181 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002182 return NULL;
2183
2184 hFindFile = FindFirstFile(namebuf, &FileData);
2185 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002186 int error = GetLastError();
2187 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002188 return d;
2189 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002190 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002191 }
2192 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002193 /* Skip over . and .. */
2194 if (strcmp(FileData.cFileName, ".") != 0 &&
2195 strcmp(FileData.cFileName, "..") != 0) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002196 v = PyString_FromString(FileData.cFileName);
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002197 if (v == NULL) {
2198 Py_DECREF(d);
2199 d = NULL;
2200 break;
2201 }
2202 if (PyList_Append(d, v) != 0) {
2203 Py_DECREF(v);
2204 Py_DECREF(d);
2205 d = NULL;
2206 break;
2207 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002208 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002209 }
Georg Brandl622927b2006-03-07 12:48:03 +00002210 Py_BEGIN_ALLOW_THREADS
2211 result = FindNextFile(hFindFile, &FileData);
2212 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00002213 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2214 it got to the end of the directory. */
2215 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2216 Py_DECREF(d);
2217 win32_error("FindNextFile", namebuf);
2218 FindClose(hFindFile);
2219 return NULL;
2220 }
Georg Brandl622927b2006-03-07 12:48:03 +00002221 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002222
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002223 if (FindClose(hFindFile) == FALSE) {
2224 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002225 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002226 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002227
2228 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002229
Tim Peters0bb44a42000-09-15 07:44:49 +00002230#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002231
2232#ifndef MAX_PATH
2233#define MAX_PATH CCHMAXPATH
2234#endif
2235 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002236 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002237 PyObject *d, *v;
2238 char namebuf[MAX_PATH+5];
2239 HDIR hdir = 1;
2240 ULONG srchcnt = 1;
2241 FILEFINDBUF3 ep;
2242 APIRET rc;
2243
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002244 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002245 return NULL;
2246 if (len >= MAX_PATH) {
2247 PyErr_SetString(PyExc_ValueError, "path too long");
2248 return NULL;
2249 }
2250 strcpy(namebuf, name);
2251 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002252 if (*pt == ALTSEP)
2253 *pt = SEP;
2254 if (namebuf[len-1] != SEP)
2255 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002256 strcpy(namebuf + len, "*.*");
2257
2258 if ((d = PyList_New(0)) == NULL)
2259 return NULL;
2260
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002261 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2262 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002263 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002264 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2265 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2266 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002267
2268 if (rc != NO_ERROR) {
2269 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002270 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002271 }
2272
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002273 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002274 do {
2275 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002276 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002277 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002278
2279 strcpy(namebuf, ep.achName);
2280
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002281 /* Leave Case of Name Alone -- In Native Form */
2282 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002283
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002284 v = PyString_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002285 if (v == NULL) {
2286 Py_DECREF(d);
2287 d = NULL;
2288 break;
2289 }
2290 if (PyList_Append(d, v) != 0) {
2291 Py_DECREF(v);
2292 Py_DECREF(d);
2293 d = NULL;
2294 break;
2295 }
2296 Py_DECREF(v);
2297 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2298 }
2299
2300 return d;
2301#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002302
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002303 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002304 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002305 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002306 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002307 int arg_is_unicode = 1;
2308
Georg Brandl05e89b82006-04-11 07:04:06 +00002309 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002310 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2311 arg_is_unicode = 0;
2312 PyErr_Clear();
2313 }
2314 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002315 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002316 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002317 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002318 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002319 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002320 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002321 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002322 return NULL;
2323 }
Georg Brandl622927b2006-03-07 12:48:03 +00002324 for (;;) {
Georg Brandl86cbf812008-07-16 21:31:41 +00002325 errno = 0;
Georg Brandl622927b2006-03-07 12:48:03 +00002326 Py_BEGIN_ALLOW_THREADS
2327 ep = readdir(dirp);
2328 Py_END_ALLOW_THREADS
Georg Brandl86cbf812008-07-16 21:31:41 +00002329 if (ep == NULL) {
2330 if (errno == 0) {
2331 break;
2332 } else {
2333 closedir(dirp);
2334 Py_DECREF(d);
2335 return posix_error_with_allocated_filename(name);
2336 }
2337 }
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002338 if (ep->d_name[0] == '.' &&
2339 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002340 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002341 continue;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002342 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002343 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002344 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002345 d = NULL;
2346 break;
2347 }
Just van Rossum46c97842003-02-25 21:42:15 +00002348#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00002349 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002350 PyObject *w;
2351
2352 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002353 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002354 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002355 if (w != NULL) {
2356 Py_DECREF(v);
2357 v = w;
2358 }
2359 else {
2360 /* fall back to the original byte string, as
2361 discussed in patch #683592 */
2362 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002363 }
Just van Rossum46c97842003-02-25 21:42:15 +00002364 }
2365#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002366 if (PyList_Append(d, v) != 0) {
2367 Py_DECREF(v);
2368 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002369 d = NULL;
2370 break;
2371 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002372 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002373 }
2374 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002375 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002376
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002377 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002378
Tim Peters0bb44a42000-09-15 07:44:49 +00002379#endif /* which OS */
2380} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002381
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002382#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002383/* A helper function for abspath on win32 */
2384static PyObject *
2385posix__getfullpathname(PyObject *self, PyObject *args)
2386{
2387 /* assume encoded strings wont more than double no of chars */
2388 char inbuf[MAX_PATH*2];
2389 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002390 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002391 char outbuf[MAX_PATH*2];
2392 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002393#ifdef Py_WIN_WIDE_FILENAMES
2394 if (unicode_file_names()) {
2395 PyUnicodeObject *po;
2396 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2397 Py_UNICODE woutbuf[MAX_PATH*2];
2398 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00002399 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002400 sizeof(woutbuf)/sizeof(woutbuf[0]),
2401 woutbuf, &wtemp))
2402 return win32_error("GetFullPathName", "");
2403 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
2404 }
2405 /* Drop the argument parsing error as narrow strings
2406 are also valid. */
2407 PyErr_Clear();
2408 }
2409#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002410 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2411 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002412 &insize))
2413 return NULL;
2414 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2415 outbuf, &temp))
2416 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002417 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2418 return PyUnicode_Decode(outbuf, strlen(outbuf),
2419 Py_FileSystemDefaultEncoding, NULL);
2420 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002421 return PyString_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002422} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002423#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002424
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002425PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002426"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002427Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002428
Barry Warsaw53699e91996-12-10 23:23:01 +00002429static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002430posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002431{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002432 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002433 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002434 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002435
2436#ifdef Py_WIN_WIDE_FILENAMES
2437 if (unicode_file_names()) {
2438 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002439 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002440 Py_BEGIN_ALLOW_THREADS
2441 /* PyUnicode_AS_UNICODE OK without thread lock as
2442 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002443 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002444 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002445 if (!res)
2446 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002447 Py_INCREF(Py_None);
2448 return Py_None;
2449 }
2450 /* Drop the argument parsing error as narrow strings
2451 are also valid. */
2452 PyErr_Clear();
2453 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002454 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2455 Py_FileSystemDefaultEncoding, &path, &mode))
2456 return NULL;
2457 Py_BEGIN_ALLOW_THREADS
2458 /* PyUnicode_AS_UNICODE OK without thread lock as
2459 it is a simple dereference. */
2460 res = CreateDirectoryA(path, NULL);
2461 Py_END_ALLOW_THREADS
2462 if (!res) {
2463 win32_error("mkdir", path);
2464 PyMem_Free(path);
2465 return NULL;
2466 }
2467 PyMem_Free(path);
2468 Py_INCREF(Py_None);
2469 return Py_None;
2470#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002471
Tim Peters5aa91602002-01-30 05:46:57 +00002472 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002473 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002474 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002475 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002476#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002477 res = mkdir(path);
2478#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002479 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002480#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002481 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002482 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002483 return posix_error_with_allocated_filename(path);
2484 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002485 Py_INCREF(Py_None);
2486 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002487#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002488}
2489
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002490
Neal Norwitz1818ed72006-03-26 00:29:48 +00002491/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2492#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002493#include <sys/resource.h>
2494#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002495
Neal Norwitz1818ed72006-03-26 00:29:48 +00002496
2497#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002498PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002499"nice(inc) -> new_priority\n\n\
2500Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002501
Barry Warsaw53699e91996-12-10 23:23:01 +00002502static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002503posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002504{
2505 int increment, value;
2506
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002507 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002508 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002509
2510 /* There are two flavours of 'nice': one that returns the new
2511 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002512 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2513 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002514
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002515 If we are of the nice family that returns the new priority, we
2516 need to clear errno before the call, and check if errno is filled
2517 before calling posix_error() on a returnvalue of -1, because the
2518 -1 may be the actual new priority! */
2519
2520 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002521 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002522#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002523 if (value == 0)
2524 value = getpriority(PRIO_PROCESS, 0);
2525#endif
2526 if (value == -1 && errno != 0)
2527 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002528 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002529 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002530}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002531#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002532
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002533PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002534"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002535Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002536
Barry Warsaw53699e91996-12-10 23:23:01 +00002537static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002538posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002539{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002540#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002541 PyObject *o1, *o2;
2542 char *p1, *p2;
2543 BOOL result;
2544 if (unicode_file_names()) {
2545 if (!PyArg_ParseTuple(args, "O&O&:rename",
2546 convert_to_unicode, &o1,
2547 convert_to_unicode, &o2))
2548 PyErr_Clear();
2549 else {
2550 Py_BEGIN_ALLOW_THREADS
2551 result = MoveFileW(PyUnicode_AsUnicode(o1),
2552 PyUnicode_AsUnicode(o2));
2553 Py_END_ALLOW_THREADS
2554 Py_DECREF(o1);
2555 Py_DECREF(o2);
2556 if (!result)
2557 return win32_error("rename", NULL);
2558 Py_INCREF(Py_None);
2559 return Py_None;
2560 }
2561 }
2562 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2563 return NULL;
2564 Py_BEGIN_ALLOW_THREADS
2565 result = MoveFileA(p1, p2);
2566 Py_END_ALLOW_THREADS
2567 if (!result)
2568 return win32_error("rename", NULL);
2569 Py_INCREF(Py_None);
2570 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002571#else
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002572 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002573#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002574}
2575
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002576
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002577PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002578"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002579Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002580
Barry Warsaw53699e91996-12-10 23:23:01 +00002581static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002582posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002583{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002584#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002585 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002586#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002587 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002588#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002589}
2590
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002591
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002592PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002593"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002594Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002595
Barry Warsaw53699e91996-12-10 23:23:01 +00002596static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002597posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002598{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002599#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002600 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002601#else
2602 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2603#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002604}
2605
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002606
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002607#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002608PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002609"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002610Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002611
Barry Warsaw53699e91996-12-10 23:23:01 +00002612static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002613posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002614{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002615 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002616 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002617 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002618 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002619 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002620 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002621 Py_END_ALLOW_THREADS
2622 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002623}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002624#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002625
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002626
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002627PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002628"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002629Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002630
Barry Warsaw53699e91996-12-10 23:23:01 +00002631static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002632posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002633{
2634 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002635 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002636 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002637 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002638 if (i < 0)
2639 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002640 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002641}
2642
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002643
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002644PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002645"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002646Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002647
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002648PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002649"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002650Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002651
Barry Warsaw53699e91996-12-10 23:23:01 +00002652static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002653posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002654{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002655#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002656 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002657#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002658 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002659#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002660}
2661
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002662
Guido van Rossumb6775db1994-08-01 11:34:53 +00002663#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002664PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002665"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002666Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002667
Barry Warsaw53699e91996-12-10 23:23:01 +00002668static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002669posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002670{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002671 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002672 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002673
Barry Warsaw53699e91996-12-10 23:23:01 +00002674 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002675 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002676 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002677 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002678 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002679 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002680 u.sysname,
2681 u.nodename,
2682 u.release,
2683 u.version,
2684 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002685}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002686#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002687
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002688static int
2689extract_time(PyObject *t, long* sec, long* usec)
2690{
2691 long intval;
2692 if (PyFloat_Check(t)) {
2693 double tval = PyFloat_AsDouble(t);
Christian Heimese93237d2007-12-19 02:37:44 +00002694 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002695 if (!intobj)
2696 return -1;
2697 intval = PyInt_AsLong(intobj);
2698 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002699 if (intval == -1 && PyErr_Occurred())
2700 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002701 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002702 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002703 if (*usec < 0)
2704 /* If rounding gave us a negative number,
2705 truncate. */
2706 *usec = 0;
2707 return 0;
2708 }
2709 intval = PyInt_AsLong(t);
2710 if (intval == -1 && PyErr_Occurred())
2711 return -1;
2712 *sec = intval;
2713 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002714 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002715}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002716
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002717PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002718"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002719utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002720Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002721second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002722
Barry Warsaw53699e91996-12-10 23:23:01 +00002723static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002724posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002725{
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002726#ifdef Py_WIN_WIDE_FILENAMES
2727 PyObject *arg;
2728 PyUnicodeObject *obwpath;
2729 wchar_t *wpath = NULL;
2730 char *apath = NULL;
2731 HANDLE hFile;
2732 long atimesec, mtimesec, ausec, musec;
2733 FILETIME atime, mtime;
2734 PyObject *result = NULL;
2735
2736 if (unicode_file_names()) {
2737 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2738 wpath = PyUnicode_AS_UNICODE(obwpath);
2739 Py_BEGIN_ALLOW_THREADS
2740 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002741 NULL, OPEN_EXISTING,
2742 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002743 Py_END_ALLOW_THREADS
2744 if (hFile == INVALID_HANDLE_VALUE)
2745 return win32_error_unicode("utime", wpath);
2746 } else
2747 /* Drop the argument parsing error as narrow strings
2748 are also valid. */
2749 PyErr_Clear();
2750 }
2751 if (!wpath) {
2752 if (!PyArg_ParseTuple(args, "etO:utime",
2753 Py_FileSystemDefaultEncoding, &apath, &arg))
2754 return NULL;
2755 Py_BEGIN_ALLOW_THREADS
2756 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002757 NULL, OPEN_EXISTING,
2758 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002759 Py_END_ALLOW_THREADS
2760 if (hFile == INVALID_HANDLE_VALUE) {
2761 win32_error("utime", apath);
2762 PyMem_Free(apath);
2763 return NULL;
2764 }
2765 PyMem_Free(apath);
2766 }
2767
2768 if (arg == Py_None) {
2769 SYSTEMTIME now;
2770 GetSystemTime(&now);
2771 if (!SystemTimeToFileTime(&now, &mtime) ||
2772 !SystemTimeToFileTime(&now, &atime)) {
2773 win32_error("utime", NULL);
2774 goto done;
2775 }
2776 }
2777 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2778 PyErr_SetString(PyExc_TypeError,
2779 "utime() arg 2 must be a tuple (atime, mtime)");
2780 goto done;
2781 }
2782 else {
2783 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2784 &atimesec, &ausec) == -1)
2785 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002786 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002787 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2788 &mtimesec, &musec) == -1)
2789 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002790 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002791 }
2792 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2793 /* Avoid putting the file name into the error here,
2794 as that may confuse the user into believing that
2795 something is wrong with the file, when it also
2796 could be the time stamp that gives a problem. */
2797 win32_error("utime", NULL);
2798 }
2799 Py_INCREF(Py_None);
2800 result = Py_None;
2801done:
2802 CloseHandle(hFile);
2803 return result;
2804#else /* Py_WIN_WIDE_FILENAMES */
2805
Neal Norwitz2adf2102004-06-09 01:46:02 +00002806 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002807 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002808 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002809 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002810
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002811#if defined(HAVE_UTIMES)
2812 struct timeval buf[2];
2813#define ATIME buf[0].tv_sec
2814#define MTIME buf[1].tv_sec
2815#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002816/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002817 struct utimbuf buf;
2818#define ATIME buf.actime
2819#define MTIME buf.modtime
2820#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002821#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002822 time_t buf[2];
2823#define ATIME buf[0]
2824#define MTIME buf[1]
2825#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002826#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002827
Mark Hammond817c9292003-12-03 01:22:38 +00002828
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002829 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002830 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002831 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002832 if (arg == Py_None) {
2833 /* optional time values not given */
2834 Py_BEGIN_ALLOW_THREADS
2835 res = utime(path, NULL);
2836 Py_END_ALLOW_THREADS
2837 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002838 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002839 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002840 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002841 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002842 return NULL;
2843 }
2844 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002845 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002846 &atime, &ausec) == -1) {
2847 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002848 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002849 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002850 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002851 &mtime, &musec) == -1) {
2852 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002853 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002854 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002855 ATIME = atime;
2856 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002857#ifdef HAVE_UTIMES
2858 buf[0].tv_usec = ausec;
2859 buf[1].tv_usec = musec;
2860 Py_BEGIN_ALLOW_THREADS
2861 res = utimes(path, buf);
2862 Py_END_ALLOW_THREADS
2863#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002864 Py_BEGIN_ALLOW_THREADS
2865 res = utime(path, UTIME_ARG);
2866 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002867#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002868 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002869 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002870 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002871 }
Neal Norwitz96652712004-06-06 20:40:27 +00002872 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002873 Py_INCREF(Py_None);
2874 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002875#undef UTIME_ARG
2876#undef ATIME
2877#undef MTIME
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002878#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002879}
2880
Guido van Rossum85e3b011991-06-03 12:42:10 +00002881
Guido van Rossum3b066191991-06-04 19:40:25 +00002882/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002883
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002884PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002885"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002886Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002887
Barry Warsaw53699e91996-12-10 23:23:01 +00002888static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002889posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002890{
2891 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002892 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002893 return NULL;
2894 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002895 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002896}
2897
Martin v. Löwis114619e2002-10-07 06:44:21 +00002898#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2899static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002900free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002901{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002902 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002903 for (i = 0; i < count; i++)
2904 PyMem_Free(array[i]);
2905 PyMem_DEL(array);
2906}
2907#endif
2908
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002909
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002910#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002911PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002912"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002913Execute an executable path with arguments, replacing current process.\n\
2914\n\
2915 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002916 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002917
Barry Warsaw53699e91996-12-10 23:23:01 +00002918static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002919posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002920{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002921 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002922 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002923 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002924 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002925 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002926
Guido van Rossum89b33251993-10-22 14:26:06 +00002927 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002928 argv is a list or tuple of strings. */
2929
Martin v. Löwis114619e2002-10-07 06:44:21 +00002930 if (!PyArg_ParseTuple(args, "etO:execv",
2931 Py_FileSystemDefaultEncoding,
2932 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002933 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002934 if (PyList_Check(argv)) {
2935 argc = PyList_Size(argv);
2936 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002937 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002938 else if (PyTuple_Check(argv)) {
2939 argc = PyTuple_Size(argv);
2940 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002941 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002942 else {
Fred Drake661ea262000-10-24 19:57:45 +00002943 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002944 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002945 return NULL;
2946 }
2947
Barry Warsaw53699e91996-12-10 23:23:01 +00002948 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002949 if (argvlist == NULL) {
2950 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002951 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002952 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002953 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002954 if (!PyArg_Parse((*getitem)(argv, i), "et",
2955 Py_FileSystemDefaultEncoding,
2956 &argvlist[i])) {
2957 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002958 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002959 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002960 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002961 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002962
Guido van Rossum85e3b011991-06-03 12:42:10 +00002963 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002964 }
2965 argvlist[argc] = NULL;
2966
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002967 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002968
Guido van Rossum85e3b011991-06-03 12:42:10 +00002969 /* If we get here it's definitely an error */
2970
Martin v. Löwis114619e2002-10-07 06:44:21 +00002971 free_string_array(argvlist, argc);
2972 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002973 return posix_error();
2974}
2975
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002976
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002977PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002978"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002979Execute a path with arguments and environment, replacing current process.\n\
2980\n\
2981 path: path of executable file\n\
2982 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002983 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002984
Barry Warsaw53699e91996-12-10 23:23:01 +00002985static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002986posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002987{
2988 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002989 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002990 char **argvlist;
2991 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002992 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002993 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002994 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002995 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002996
2997 /* execve has three arguments: (path, argv, env), where
2998 argv is a list or tuple of strings and env is a dictionary
2999 like posix.environ. */
3000
Martin v. Löwis114619e2002-10-07 06:44:21 +00003001 if (!PyArg_ParseTuple(args, "etOO:execve",
3002 Py_FileSystemDefaultEncoding,
3003 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003004 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003005 if (PyList_Check(argv)) {
3006 argc = PyList_Size(argv);
3007 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003008 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003009 else if (PyTuple_Check(argv)) {
3010 argc = PyTuple_Size(argv);
3011 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003012 }
3013 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003014 PyErr_SetString(PyExc_TypeError,
3015 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003016 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003017 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003018 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003019 PyErr_SetString(PyExc_TypeError,
3020 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003021 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003022 }
3023
Barry Warsaw53699e91996-12-10 23:23:01 +00003024 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003025 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003026 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003027 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003028 }
3029 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003030 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00003031 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00003032 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00003033 &argvlist[i]))
3034 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003035 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003036 goto fail_1;
3037 }
3038 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003039 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003040 argvlist[argc] = NULL;
3041
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003042 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003043 if (i < 0)
3044 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00003045 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003046 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003047 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003048 goto fail_1;
3049 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003050 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003051 keys = PyMapping_Keys(env);
3052 vals = PyMapping_Values(env);
3053 if (!keys || !vals)
3054 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003055 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3056 PyErr_SetString(PyExc_TypeError,
3057 "execve(): env.keys() or env.values() is not a list");
3058 goto fail_2;
3059 }
Tim Peters5aa91602002-01-30 05:46:57 +00003060
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003061 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003062 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003063 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003064
3065 key = PyList_GetItem(keys, pos);
3066 val = PyList_GetItem(vals, pos);
3067 if (!key || !val)
3068 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003069
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003070 if (!PyArg_Parse(
3071 key,
3072 "s;execve() arg 3 contains a non-string key",
3073 &k) ||
3074 !PyArg_Parse(
3075 val,
3076 "s;execve() arg 3 contains a non-string value",
3077 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003078 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003079 goto fail_2;
3080 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003081
3082#if defined(PYOS_OS2)
3083 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3084 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3085#endif
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003086 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003087 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003088 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003089 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003090 goto fail_2;
3091 }
Tim Petersc8996f52001-12-03 20:41:00 +00003092 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003093 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003094#if defined(PYOS_OS2)
3095 }
3096#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003097 }
3098 envlist[envc] = 0;
3099
3100 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003101
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003102 /* If we get here it's definitely an error */
3103
3104 (void) posix_error();
3105
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003106 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003107 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003108 PyMem_DEL(envlist[envc]);
3109 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003110 fail_1:
3111 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003112 Py_XDECREF(vals);
3113 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003114 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003115 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003116 return NULL;
3117}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003118#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003119
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003120
Guido van Rossuma1065681999-01-25 23:20:23 +00003121#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003122PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003123"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003124Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003125\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003126 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003127 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003128 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003129
3130static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003131posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003132{
3133 char *path;
3134 PyObject *argv;
3135 char **argvlist;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003136 int mode, i;
3137 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003138 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003139 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003140
3141 /* spawnv has three arguments: (mode, path, argv), where
3142 argv is a list or tuple of strings. */
3143
Martin v. Löwis114619e2002-10-07 06:44:21 +00003144 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3145 Py_FileSystemDefaultEncoding,
3146 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003147 return NULL;
3148 if (PyList_Check(argv)) {
3149 argc = PyList_Size(argv);
3150 getitem = PyList_GetItem;
3151 }
3152 else if (PyTuple_Check(argv)) {
3153 argc = PyTuple_Size(argv);
3154 getitem = PyTuple_GetItem;
3155 }
3156 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003157 PyErr_SetString(PyExc_TypeError,
3158 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003159 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003160 return NULL;
3161 }
3162
3163 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003164 if (argvlist == NULL) {
3165 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003166 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003167 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003168 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003169 if (!PyArg_Parse((*getitem)(argv, i), "et",
3170 Py_FileSystemDefaultEncoding,
3171 &argvlist[i])) {
3172 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003173 PyErr_SetString(
3174 PyExc_TypeError,
3175 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003176 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00003177 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003178 }
3179 }
3180 argvlist[argc] = NULL;
3181
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003182#if defined(PYOS_OS2) && defined(PYCC_GCC)
3183 Py_BEGIN_ALLOW_THREADS
3184 spawnval = spawnv(mode, path, argvlist);
3185 Py_END_ALLOW_THREADS
3186#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003187 if (mode == _OLD_P_OVERLAY)
3188 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003189
Tim Peters25059d32001-12-07 20:35:43 +00003190 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003191 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003192 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003193#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003194
Martin v. Löwis114619e2002-10-07 06:44:21 +00003195 free_string_array(argvlist, argc);
3196 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003197
Fred Drake699f3522000-06-29 21:12:41 +00003198 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003199 return posix_error();
3200 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003201#if SIZEOF_LONG == SIZEOF_VOID_P
3202 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003203#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003204 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003205#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003206}
3207
3208
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003209PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003210"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003211Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003212\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003213 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003214 path: path of executable file\n\
3215 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003216 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003217
3218static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003219posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003220{
3221 char *path;
3222 PyObject *argv, *env;
3223 char **argvlist;
3224 char **envlist;
3225 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003226 int mode, pos, envc;
3227 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003228 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003229 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003230 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003231
3232 /* spawnve has four arguments: (mode, path, argv, env), where
3233 argv is a list or tuple of strings and env is a dictionary
3234 like posix.environ. */
3235
Martin v. Löwis114619e2002-10-07 06:44:21 +00003236 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3237 Py_FileSystemDefaultEncoding,
3238 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003239 return NULL;
3240 if (PyList_Check(argv)) {
3241 argc = PyList_Size(argv);
3242 getitem = PyList_GetItem;
3243 }
3244 else if (PyTuple_Check(argv)) {
3245 argc = PyTuple_Size(argv);
3246 getitem = PyTuple_GetItem;
3247 }
3248 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003249 PyErr_SetString(PyExc_TypeError,
3250 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003251 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003252 }
3253 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003254 PyErr_SetString(PyExc_TypeError,
3255 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003256 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003257 }
3258
3259 argvlist = PyMem_NEW(char *, argc+1);
3260 if (argvlist == NULL) {
3261 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003262 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003263 }
3264 for (i = 0; i < argc; i++) {
3265 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003266 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00003267 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00003268 &argvlist[i]))
3269 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003270 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003271 goto fail_1;
3272 }
3273 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003274 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003275 argvlist[argc] = NULL;
3276
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003277 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003278 if (i < 0)
3279 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003280 envlist = PyMem_NEW(char *, i + 1);
3281 if (envlist == NULL) {
3282 PyErr_NoMemory();
3283 goto fail_1;
3284 }
3285 envc = 0;
3286 keys = PyMapping_Keys(env);
3287 vals = PyMapping_Values(env);
3288 if (!keys || !vals)
3289 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003290 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3291 PyErr_SetString(PyExc_TypeError,
3292 "spawnve(): env.keys() or env.values() is not a list");
3293 goto fail_2;
3294 }
Tim Peters5aa91602002-01-30 05:46:57 +00003295
Guido van Rossuma1065681999-01-25 23:20:23 +00003296 for (pos = 0; pos < i; pos++) {
3297 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003298 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003299
3300 key = PyList_GetItem(keys, pos);
3301 val = PyList_GetItem(vals, pos);
3302 if (!key || !val)
3303 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003304
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003305 if (!PyArg_Parse(
3306 key,
3307 "s;spawnve() arg 3 contains a non-string key",
3308 &k) ||
3309 !PyArg_Parse(
3310 val,
3311 "s;spawnve() arg 3 contains a non-string value",
3312 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003313 {
3314 goto fail_2;
3315 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003316 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003317 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003318 if (p == NULL) {
3319 PyErr_NoMemory();
3320 goto fail_2;
3321 }
Tim Petersc8996f52001-12-03 20:41:00 +00003322 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003323 envlist[envc++] = p;
3324 }
3325 envlist[envc] = 0;
3326
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003327#if defined(PYOS_OS2) && defined(PYCC_GCC)
3328 Py_BEGIN_ALLOW_THREADS
3329 spawnval = spawnve(mode, path, argvlist, envlist);
3330 Py_END_ALLOW_THREADS
3331#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003332 if (mode == _OLD_P_OVERLAY)
3333 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003334
3335 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003336 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003337 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003338#endif
Tim Peters25059d32001-12-07 20:35:43 +00003339
Fred Drake699f3522000-06-29 21:12:41 +00003340 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003341 (void) posix_error();
3342 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003343#if SIZEOF_LONG == SIZEOF_VOID_P
3344 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003345#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003346 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003347#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003348
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003349 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003350 while (--envc >= 0)
3351 PyMem_DEL(envlist[envc]);
3352 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003353 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003354 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003355 Py_XDECREF(vals);
3356 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003357 fail_0:
3358 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003359 return res;
3360}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003361
3362/* OS/2 supports spawnvp & spawnvpe natively */
3363#if defined(PYOS_OS2)
3364PyDoc_STRVAR(posix_spawnvp__doc__,
3365"spawnvp(mode, file, args)\n\n\
3366Execute the program 'file' in a new process, using the environment\n\
3367search path to find the file.\n\
3368\n\
3369 mode: mode of process creation\n\
3370 file: executable file name\n\
3371 args: tuple or list of strings");
3372
3373static PyObject *
3374posix_spawnvp(PyObject *self, PyObject *args)
3375{
3376 char *path;
3377 PyObject *argv;
3378 char **argvlist;
3379 int mode, i, argc;
3380 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003381 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003382
3383 /* spawnvp has three arguments: (mode, path, argv), where
3384 argv is a list or tuple of strings. */
3385
3386 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3387 Py_FileSystemDefaultEncoding,
3388 &path, &argv))
3389 return NULL;
3390 if (PyList_Check(argv)) {
3391 argc = PyList_Size(argv);
3392 getitem = PyList_GetItem;
3393 }
3394 else if (PyTuple_Check(argv)) {
3395 argc = PyTuple_Size(argv);
3396 getitem = PyTuple_GetItem;
3397 }
3398 else {
3399 PyErr_SetString(PyExc_TypeError,
3400 "spawnvp() arg 2 must be a tuple or list");
3401 PyMem_Free(path);
3402 return NULL;
3403 }
3404
3405 argvlist = PyMem_NEW(char *, argc+1);
3406 if (argvlist == NULL) {
3407 PyMem_Free(path);
3408 return PyErr_NoMemory();
3409 }
3410 for (i = 0; i < argc; i++) {
3411 if (!PyArg_Parse((*getitem)(argv, i), "et",
3412 Py_FileSystemDefaultEncoding,
3413 &argvlist[i])) {
3414 free_string_array(argvlist, i);
3415 PyErr_SetString(
3416 PyExc_TypeError,
3417 "spawnvp() arg 2 must contain only strings");
3418 PyMem_Free(path);
3419 return NULL;
3420 }
3421 }
3422 argvlist[argc] = NULL;
3423
3424 Py_BEGIN_ALLOW_THREADS
3425#if defined(PYCC_GCC)
3426 spawnval = spawnvp(mode, path, argvlist);
3427#else
3428 spawnval = _spawnvp(mode, path, argvlist);
3429#endif
3430 Py_END_ALLOW_THREADS
3431
3432 free_string_array(argvlist, argc);
3433 PyMem_Free(path);
3434
3435 if (spawnval == -1)
3436 return posix_error();
3437 else
3438 return Py_BuildValue("l", (long) spawnval);
3439}
3440
3441
3442PyDoc_STRVAR(posix_spawnvpe__doc__,
3443"spawnvpe(mode, file, args, env)\n\n\
3444Execute the program 'file' in a new process, using the environment\n\
3445search path to find the file.\n\
3446\n\
3447 mode: mode of process creation\n\
3448 file: executable file name\n\
3449 args: tuple or list of arguments\n\
3450 env: dictionary of strings mapping to strings");
3451
3452static PyObject *
3453posix_spawnvpe(PyObject *self, PyObject *args)
3454{
3455 char *path;
3456 PyObject *argv, *env;
3457 char **argvlist;
3458 char **envlist;
3459 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3460 int mode, i, pos, argc, envc;
3461 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003462 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003463 int lastarg = 0;
3464
3465 /* spawnvpe has four arguments: (mode, path, argv, env), where
3466 argv is a list or tuple of strings and env is a dictionary
3467 like posix.environ. */
3468
3469 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3470 Py_FileSystemDefaultEncoding,
3471 &path, &argv, &env))
3472 return NULL;
3473 if (PyList_Check(argv)) {
3474 argc = PyList_Size(argv);
3475 getitem = PyList_GetItem;
3476 }
3477 else if (PyTuple_Check(argv)) {
3478 argc = PyTuple_Size(argv);
3479 getitem = PyTuple_GetItem;
3480 }
3481 else {
3482 PyErr_SetString(PyExc_TypeError,
3483 "spawnvpe() arg 2 must be a tuple or list");
3484 goto fail_0;
3485 }
3486 if (!PyMapping_Check(env)) {
3487 PyErr_SetString(PyExc_TypeError,
3488 "spawnvpe() arg 3 must be a mapping object");
3489 goto fail_0;
3490 }
3491
3492 argvlist = PyMem_NEW(char *, argc+1);
3493 if (argvlist == NULL) {
3494 PyErr_NoMemory();
3495 goto fail_0;
3496 }
3497 for (i = 0; i < argc; i++) {
3498 if (!PyArg_Parse((*getitem)(argv, i),
3499 "et;spawnvpe() arg 2 must contain only strings",
3500 Py_FileSystemDefaultEncoding,
3501 &argvlist[i]))
3502 {
3503 lastarg = i;
3504 goto fail_1;
3505 }
3506 }
3507 lastarg = argc;
3508 argvlist[argc] = NULL;
3509
3510 i = PyMapping_Size(env);
3511 if (i < 0)
3512 goto fail_1;
3513 envlist = PyMem_NEW(char *, i + 1);
3514 if (envlist == NULL) {
3515 PyErr_NoMemory();
3516 goto fail_1;
3517 }
3518 envc = 0;
3519 keys = PyMapping_Keys(env);
3520 vals = PyMapping_Values(env);
3521 if (!keys || !vals)
3522 goto fail_2;
3523 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3524 PyErr_SetString(PyExc_TypeError,
3525 "spawnvpe(): env.keys() or env.values() is not a list");
3526 goto fail_2;
3527 }
3528
3529 for (pos = 0; pos < i; pos++) {
3530 char *p, *k, *v;
3531 size_t len;
3532
3533 key = PyList_GetItem(keys, pos);
3534 val = PyList_GetItem(vals, pos);
3535 if (!key || !val)
3536 goto fail_2;
3537
3538 if (!PyArg_Parse(
3539 key,
3540 "s;spawnvpe() arg 3 contains a non-string key",
3541 &k) ||
3542 !PyArg_Parse(
3543 val,
3544 "s;spawnvpe() arg 3 contains a non-string value",
3545 &v))
3546 {
3547 goto fail_2;
3548 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003549 len = PyString_Size(key) + PyString_Size(val) + 2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003550 p = PyMem_NEW(char, len);
3551 if (p == NULL) {
3552 PyErr_NoMemory();
3553 goto fail_2;
3554 }
3555 PyOS_snprintf(p, len, "%s=%s", k, v);
3556 envlist[envc++] = p;
3557 }
3558 envlist[envc] = 0;
3559
3560 Py_BEGIN_ALLOW_THREADS
3561#if defined(PYCC_GCC)
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003562 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003563#else
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003564 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003565#endif
3566 Py_END_ALLOW_THREADS
3567
3568 if (spawnval == -1)
3569 (void) posix_error();
3570 else
3571 res = Py_BuildValue("l", (long) spawnval);
3572
3573 fail_2:
3574 while (--envc >= 0)
3575 PyMem_DEL(envlist[envc]);
3576 PyMem_DEL(envlist);
3577 fail_1:
3578 free_string_array(argvlist, lastarg);
3579 Py_XDECREF(vals);
3580 Py_XDECREF(keys);
3581 fail_0:
3582 PyMem_Free(path);
3583 return res;
3584}
3585#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003586#endif /* HAVE_SPAWNV */
3587
3588
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003589#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003590PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003591"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003592Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3593\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003594Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003595
3596static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003597posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003598{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003599 pid_t pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003600 if (pid == -1)
3601 return posix_error();
Gregory P. Smithfb7a50f2008-07-14 06:06:48 +00003602 if (pid == 0)
3603 PyOS_AfterFork();
Christian Heimes951cc0f2008-01-31 23:08:23 +00003604 return PyInt_FromLong(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003605}
3606#endif
3607
3608
Guido van Rossumad0ee831995-03-01 10:34:45 +00003609#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003610PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003611"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003612Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003613Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003614
Barry Warsaw53699e91996-12-10 23:23:01 +00003615static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003616posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003617{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003618 pid_t pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003619 if (pid == -1)
3620 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003621 if (pid == 0)
3622 PyOS_AfterFork();
Christian Heimes951cc0f2008-01-31 23:08:23 +00003623 return PyInt_FromLong(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003624}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003625#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003626
Neal Norwitzb59798b2003-03-21 01:43:31 +00003627/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003628/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3629#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003630#define DEV_PTY_FILE "/dev/ptc"
3631#define HAVE_DEV_PTMX
3632#else
3633#define DEV_PTY_FILE "/dev/ptmx"
3634#endif
3635
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003636#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003637#ifdef HAVE_PTY_H
3638#include <pty.h>
3639#else
3640#ifdef HAVE_LIBUTIL_H
3641#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003642#endif /* HAVE_LIBUTIL_H */
3643#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003644#ifdef HAVE_STROPTS_H
3645#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003646#endif
3647#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003648
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003649#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003650PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003651"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003652Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003653
3654static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003655posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003656{
3657 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003658#ifndef HAVE_OPENPTY
3659 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003660#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003661#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003662 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003663#ifdef sun
Neal Norwitz84a98e02006-04-10 07:44:23 +00003664 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003665#endif
3666#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003667
Thomas Wouters70c21a12000-07-14 14:28:33 +00003668#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003669 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3670 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003671#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003672 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3673 if (slave_name == NULL)
3674 return posix_error();
3675
3676 slave_fd = open(slave_name, O_RDWR);
3677 if (slave_fd < 0)
3678 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003679#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003680 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003681 if (master_fd < 0)
3682 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003683 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003684 /* change permission of slave */
3685 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003686 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003687 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003688 }
3689 /* unlock slave */
3690 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003691 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003692 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003693 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003694 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003695 slave_name = ptsname(master_fd); /* get name of slave */
3696 if (slave_name == NULL)
3697 return posix_error();
3698 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3699 if (slave_fd < 0)
3700 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003701#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003702 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3703 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003704#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003705 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003706#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003707#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003708#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003709
Fred Drake8cef4cf2000-06-28 16:40:38 +00003710 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003711
Fred Drake8cef4cf2000-06-28 16:40:38 +00003712}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003713#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003714
3715#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003716PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003717"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003718Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3719Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003720To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003721
3722static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003723posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003724{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003725 int master_fd = -1;
3726 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003727
Fred Drake8cef4cf2000-06-28 16:40:38 +00003728 pid = forkpty(&master_fd, NULL, NULL, NULL);
3729 if (pid == -1)
3730 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003731 if (pid == 0)
3732 PyOS_AfterFork();
Christian Heimes951cc0f2008-01-31 23:08:23 +00003733 return Py_BuildValue("(li)", pid, master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003734}
3735#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003736
Guido van Rossumad0ee831995-03-01 10:34:45 +00003737#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003738PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003739"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003740Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003741
Barry Warsaw53699e91996-12-10 23:23:01 +00003742static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003743posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003744{
Barry Warsaw53699e91996-12-10 23:23:01 +00003745 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003746}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003747#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003748
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003749
Guido van Rossumad0ee831995-03-01 10:34:45 +00003750#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003751PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003752"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003753Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003754
Barry Warsaw53699e91996-12-10 23:23:01 +00003755static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003756posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003757{
Barry Warsaw53699e91996-12-10 23:23:01 +00003758 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003759}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003760#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003761
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003762
Guido van Rossumad0ee831995-03-01 10:34:45 +00003763#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003764PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003765"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003766Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003767
Barry Warsaw53699e91996-12-10 23:23:01 +00003768static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003769posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003770{
Barry Warsaw53699e91996-12-10 23:23:01 +00003771 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003772}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003773#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003774
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003775
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003776PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003777"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003778Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003779
Barry Warsaw53699e91996-12-10 23:23:01 +00003780static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003781posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003782{
Barry Warsaw53699e91996-12-10 23:23:01 +00003783 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003784}
3785
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003786
Fred Drakec9680921999-12-13 16:37:25 +00003787#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003788PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003789"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003790Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003791
3792static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003793posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003794{
3795 PyObject *result = NULL;
3796
Fred Drakec9680921999-12-13 16:37:25 +00003797#ifdef NGROUPS_MAX
3798#define MAX_GROUPS NGROUPS_MAX
3799#else
3800 /* defined to be 16 on Solaris7, so this should be a small number */
3801#define MAX_GROUPS 64
3802#endif
3803 gid_t grouplist[MAX_GROUPS];
3804 int n;
3805
3806 n = getgroups(MAX_GROUPS, grouplist);
3807 if (n < 0)
3808 posix_error();
3809 else {
3810 result = PyList_New(n);
3811 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003812 int i;
3813 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003814 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003815 if (o == NULL) {
3816 Py_DECREF(result);
3817 result = NULL;
3818 break;
3819 }
3820 PyList_SET_ITEM(result, i, o);
3821 }
3822 }
3823 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003824
Fred Drakec9680921999-12-13 16:37:25 +00003825 return result;
3826}
3827#endif
3828
Martin v. Löwis606edc12002-06-13 21:09:11 +00003829#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003830PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003831"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003832Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003833
3834static PyObject *
3835posix_getpgid(PyObject *self, PyObject *args)
3836{
3837 int pid, pgid;
3838 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3839 return NULL;
3840 pgid = getpgid(pid);
3841 if (pgid < 0)
3842 return posix_error();
3843 return PyInt_FromLong((long)pgid);
3844}
3845#endif /* HAVE_GETPGID */
3846
3847
Guido van Rossumb6775db1994-08-01 11:34:53 +00003848#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003849PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003850"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003851Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003852
Barry Warsaw53699e91996-12-10 23:23:01 +00003853static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003854posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003855{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003856#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003857 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003858#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003859 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003860#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003861}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003862#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003863
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003864
Guido van Rossumb6775db1994-08-01 11:34:53 +00003865#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003866PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003867"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003868Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003869
Barry Warsaw53699e91996-12-10 23:23:01 +00003870static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003871posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003872{
Guido van Rossum64933891994-10-20 21:56:42 +00003873#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003874 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003875#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003876 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003877#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003878 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003879 Py_INCREF(Py_None);
3880 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003881}
3882
Guido van Rossumb6775db1994-08-01 11:34:53 +00003883#endif /* HAVE_SETPGRP */
3884
Guido van Rossumad0ee831995-03-01 10:34:45 +00003885#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003886PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003887"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003888Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003889
Barry Warsaw53699e91996-12-10 23:23:01 +00003890static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003891posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003892{
Christian Heimesd491d712008-02-01 18:49:26 +00003893 return PyInt_FromLong(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003894}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003895#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003896
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003897
Fred Drake12c6e2d1999-12-14 21:25:03 +00003898#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003899PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003900"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003901Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003902
3903static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003904posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003905{
Neal Norwitze241ce82003-02-17 18:17:05 +00003906 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003907 char *name;
3908 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003909
Fred Drakea30680b2000-12-06 21:24:28 +00003910 errno = 0;
3911 name = getlogin();
3912 if (name == NULL) {
3913 if (errno)
3914 posix_error();
3915 else
3916 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003917 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003918 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003919 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003920 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003921 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003922
Fred Drake12c6e2d1999-12-14 21:25:03 +00003923 return result;
3924}
3925#endif
3926
Guido van Rossumad0ee831995-03-01 10:34:45 +00003927#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003928PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003929"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003930Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003931
Barry Warsaw53699e91996-12-10 23:23:01 +00003932static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003933posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003934{
Barry Warsaw53699e91996-12-10 23:23:01 +00003935 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003936}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003937#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003938
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003939
Guido van Rossumad0ee831995-03-01 10:34:45 +00003940#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003941PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003942"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003943Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003944
Barry Warsaw53699e91996-12-10 23:23:01 +00003945static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003946posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003947{
Christian Heimesd491d712008-02-01 18:49:26 +00003948 pid_t pid;
3949 int sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003950 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003951 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003952#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003953 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3954 APIRET rc;
3955 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003956 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003957
3958 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3959 APIRET rc;
3960 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003961 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003962
3963 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003964 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003965#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003966 if (kill(pid, sig) == -1)
3967 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003968#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003969 Py_INCREF(Py_None);
3970 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003971}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003972#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003973
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003974#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003975PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003976"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003977Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003978
3979static PyObject *
3980posix_killpg(PyObject *self, PyObject *args)
3981{
3982 int pgid, sig;
3983 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3984 return NULL;
3985 if (killpg(pgid, sig) == -1)
3986 return posix_error();
3987 Py_INCREF(Py_None);
3988 return Py_None;
3989}
3990#endif
3991
Guido van Rossumc0125471996-06-28 18:55:32 +00003992#ifdef HAVE_PLOCK
3993
3994#ifdef HAVE_SYS_LOCK_H
3995#include <sys/lock.h>
3996#endif
3997
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003998PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003999"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004000Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004001
Barry Warsaw53699e91996-12-10 23:23:01 +00004002static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004003posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004004{
4005 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004006 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00004007 return NULL;
4008 if (plock(op) == -1)
4009 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004010 Py_INCREF(Py_None);
4011 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004012}
4013#endif
4014
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004015
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004016#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004017PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004018"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004019Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004020
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004021#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004022#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004023static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004024async_system(const char *command)
4025{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004026 char errormsg[256], args[1024];
4027 RESULTCODES rcodes;
4028 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004029
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004030 char *shell = getenv("COMSPEC");
4031 if (!shell)
4032 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004033
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004034 /* avoid overflowing the argument buffer */
4035 if (strlen(shell) + 3 + strlen(command) >= 1024)
4036 return ERROR_NOT_ENOUGH_MEMORY
4037
4038 args[0] = '\0';
4039 strcat(args, shell);
4040 strcat(args, "/c ");
4041 strcat(args, command);
4042
4043 /* execute asynchronously, inheriting the environment */
4044 rc = DosExecPgm(errormsg,
4045 sizeof(errormsg),
4046 EXEC_ASYNC,
4047 args,
4048 NULL,
4049 &rcodes,
4050 shell);
4051 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004052}
4053
Guido van Rossumd48f2521997-12-05 22:19:34 +00004054static FILE *
4055popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004056{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004057 int oldfd, tgtfd;
4058 HFILE pipeh[2];
4059 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004060
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004061 /* mode determines which of stdin or stdout is reconnected to
4062 * the pipe to the child
4063 */
4064 if (strchr(mode, 'r') != NULL) {
4065 tgt_fd = 1; /* stdout */
4066 } else if (strchr(mode, 'w')) {
4067 tgt_fd = 0; /* stdin */
4068 } else {
4069 *err = ERROR_INVALID_ACCESS;
4070 return NULL;
4071 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004072
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00004073 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004074 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4075 *err = rc;
4076 return NULL;
4077 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004078
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004079 /* prevent other threads accessing stdio */
4080 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004081
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004082 /* reconnect stdio and execute child */
4083 oldfd = dup(tgtfd);
4084 close(tgtfd);
4085 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4086 DosClose(pipeh[tgtfd]);
4087 rc = async_system(command);
4088 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004089
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004090 /* restore stdio */
4091 dup2(oldfd, tgtfd);
4092 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004093
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004094 /* allow other threads access to stdio */
4095 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004096
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004097 /* if execution of child was successful return file stream */
4098 if (rc == NO_ERROR)
4099 return fdopen(pipeh[1 - tgtfd], mode);
4100 else {
4101 DosClose(pipeh[1 - tgtfd]);
4102 *err = rc;
4103 return NULL;
4104 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004105}
4106
4107static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004108posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004109{
4110 char *name;
4111 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00004112 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004113 FILE *fp;
4114 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004115 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004116 return NULL;
4117 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00004118 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004119 Py_END_ALLOW_THREADS
4120 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004121 return os2_error(err);
4122
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004123 f = PyFile_FromFile(fp, name, mode, fclose);
4124 if (f != NULL)
4125 PyFile_SetBufSize(f, bufsize);
4126 return f;
4127}
4128
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004129#elif defined(PYCC_GCC)
4130
4131/* standard posix version of popen() support */
4132static PyObject *
4133posix_popen(PyObject *self, PyObject *args)
4134{
4135 char *name;
4136 char *mode = "r";
4137 int bufsize = -1;
4138 FILE *fp;
4139 PyObject *f;
4140 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4141 return NULL;
4142 Py_BEGIN_ALLOW_THREADS
4143 fp = popen(name, mode);
4144 Py_END_ALLOW_THREADS
4145 if (fp == NULL)
4146 return posix_error();
4147 f = PyFile_FromFile(fp, name, mode, pclose);
4148 if (f != NULL)
4149 PyFile_SetBufSize(f, bufsize);
4150 return f;
4151}
4152
4153/* fork() under OS/2 has lots'o'warts
4154 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4155 * most of this code is a ripoff of the win32 code, but using the
4156 * capabilities of EMX's C library routines
4157 */
4158
4159/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4160#define POPEN_1 1
4161#define POPEN_2 2
4162#define POPEN_3 3
4163#define POPEN_4 4
4164
4165static PyObject *_PyPopen(char *, int, int, int);
4166static int _PyPclose(FILE *file);
4167
4168/*
4169 * Internal dictionary mapping popen* file pointers to process handles,
4170 * for use when retrieving the process exit code. See _PyPclose() below
4171 * for more information on this dictionary's use.
4172 */
4173static PyObject *_PyPopenProcs = NULL;
4174
4175/* os2emx version of popen2()
4176 *
4177 * The result of this function is a pipe (file) connected to the
4178 * process's stdin, and a pipe connected to the process's stdout.
4179 */
4180
4181static PyObject *
4182os2emx_popen2(PyObject *self, PyObject *args)
4183{
4184 PyObject *f;
4185 int tm=0;
4186
4187 char *cmdstring;
4188 char *mode = "t";
4189 int bufsize = -1;
4190 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4191 return NULL;
4192
4193 if (*mode == 't')
4194 tm = O_TEXT;
4195 else if (*mode != 'b') {
4196 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4197 return NULL;
4198 } else
4199 tm = O_BINARY;
4200
4201 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
4202
4203 return f;
4204}
4205
4206/*
4207 * Variation on os2emx.popen2
4208 *
4209 * The result of this function is 3 pipes - the process's stdin,
4210 * stdout and stderr
4211 */
4212
4213static PyObject *
4214os2emx_popen3(PyObject *self, PyObject *args)
4215{
4216 PyObject *f;
4217 int tm = 0;
4218
4219 char *cmdstring;
4220 char *mode = "t";
4221 int bufsize = -1;
4222 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4223 return NULL;
4224
4225 if (*mode == 't')
4226 tm = O_TEXT;
4227 else if (*mode != 'b') {
4228 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4229 return NULL;
4230 } else
4231 tm = O_BINARY;
4232
4233 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
4234
4235 return f;
4236}
4237
4238/*
4239 * Variation on os2emx.popen2
4240 *
Tim Peters11b23062003-04-23 02:39:17 +00004241 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004242 * and stdout+stderr combined as a single pipe.
4243 */
4244
4245static PyObject *
4246os2emx_popen4(PyObject *self, PyObject *args)
4247{
4248 PyObject *f;
4249 int tm = 0;
4250
4251 char *cmdstring;
4252 char *mode = "t";
4253 int bufsize = -1;
4254 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4255 return NULL;
4256
4257 if (*mode == 't')
4258 tm = O_TEXT;
4259 else if (*mode != 'b') {
4260 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4261 return NULL;
4262 } else
4263 tm = O_BINARY;
4264
4265 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
4266
4267 return f;
4268}
4269
4270/* a couple of structures for convenient handling of multiple
4271 * file handles and pipes
4272 */
4273struct file_ref
4274{
4275 int handle;
4276 int flags;
4277};
4278
4279struct pipe_ref
4280{
4281 int rd;
4282 int wr;
4283};
4284
4285/* The following code is derived from the win32 code */
4286
4287static PyObject *
4288_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4289{
4290 struct file_ref stdio[3];
4291 struct pipe_ref p_fd[3];
4292 FILE *p_s[3];
Christian Heimesd491d712008-02-01 18:49:26 +00004293 int file_count, i, pipe_err;
4294 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004295 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4296 PyObject *f, *p_f[3];
4297
4298 /* file modes for subsequent fdopen's on pipe handles */
4299 if (mode == O_TEXT)
4300 {
4301 rd_mode = "rt";
4302 wr_mode = "wt";
4303 }
4304 else
4305 {
4306 rd_mode = "rb";
4307 wr_mode = "wb";
4308 }
4309
4310 /* prepare shell references */
4311 if ((shell = getenv("EMXSHELL")) == NULL)
4312 if ((shell = getenv("COMSPEC")) == NULL)
4313 {
4314 errno = ENOENT;
4315 return posix_error();
4316 }
4317
4318 sh_name = _getname(shell);
4319 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4320 opt = "/c";
4321 else
4322 opt = "-c";
4323
4324 /* save current stdio fds + their flags, and set not inheritable */
4325 i = pipe_err = 0;
4326 while (pipe_err >= 0 && i < 3)
4327 {
4328 pipe_err = stdio[i].handle = dup(i);
4329 stdio[i].flags = fcntl(i, F_GETFD, 0);
4330 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4331 i++;
4332 }
4333 if (pipe_err < 0)
4334 {
4335 /* didn't get them all saved - clean up and bail out */
4336 int saved_err = errno;
4337 while (i-- > 0)
4338 {
4339 close(stdio[i].handle);
4340 }
4341 errno = saved_err;
4342 return posix_error();
4343 }
4344
4345 /* create pipe ends */
4346 file_count = 2;
4347 if (n == POPEN_3)
4348 file_count = 3;
4349 i = pipe_err = 0;
4350 while ((pipe_err == 0) && (i < file_count))
4351 pipe_err = pipe((int *)&p_fd[i++]);
4352 if (pipe_err < 0)
4353 {
4354 /* didn't get them all made - clean up and bail out */
4355 while (i-- > 0)
4356 {
4357 close(p_fd[i].wr);
4358 close(p_fd[i].rd);
4359 }
4360 errno = EPIPE;
4361 return posix_error();
4362 }
4363
4364 /* change the actual standard IO streams over temporarily,
4365 * making the retained pipe ends non-inheritable
4366 */
4367 pipe_err = 0;
4368
4369 /* - stdin */
4370 if (dup2(p_fd[0].rd, 0) == 0)
4371 {
4372 close(p_fd[0].rd);
4373 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4374 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4375 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4376 {
4377 close(p_fd[0].wr);
4378 pipe_err = -1;
4379 }
4380 }
4381 else
4382 {
4383 pipe_err = -1;
4384 }
4385
4386 /* - stdout */
4387 if (pipe_err == 0)
4388 {
4389 if (dup2(p_fd[1].wr, 1) == 1)
4390 {
4391 close(p_fd[1].wr);
4392 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4393 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4394 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4395 {
4396 close(p_fd[1].rd);
4397 pipe_err = -1;
4398 }
4399 }
4400 else
4401 {
4402 pipe_err = -1;
4403 }
4404 }
4405
4406 /* - stderr, as required */
4407 if (pipe_err == 0)
4408 switch (n)
4409 {
4410 case POPEN_3:
4411 {
4412 if (dup2(p_fd[2].wr, 2) == 2)
4413 {
4414 close(p_fd[2].wr);
4415 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4416 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4417 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4418 {
4419 close(p_fd[2].rd);
4420 pipe_err = -1;
4421 }
4422 }
4423 else
4424 {
4425 pipe_err = -1;
4426 }
4427 break;
4428 }
4429
4430 case POPEN_4:
4431 {
4432 if (dup2(1, 2) != 2)
4433 {
4434 pipe_err = -1;
4435 }
4436 break;
4437 }
4438 }
4439
4440 /* spawn the child process */
4441 if (pipe_err == 0)
4442 {
4443 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4444 if (pipe_pid == -1)
4445 {
4446 pipe_err = -1;
4447 }
4448 else
4449 {
4450 /* save the PID into the FILE structure
4451 * NOTE: this implementation doesn't actually
4452 * take advantage of this, but do it for
4453 * completeness - AIM Apr01
4454 */
4455 for (i = 0; i < file_count; i++)
4456 p_s[i]->_pid = pipe_pid;
4457 }
4458 }
4459
4460 /* reset standard IO to normal */
4461 for (i = 0; i < 3; i++)
4462 {
4463 dup2(stdio[i].handle, i);
4464 fcntl(i, F_SETFD, stdio[i].flags);
4465 close(stdio[i].handle);
4466 }
4467
4468 /* if any remnant problems, clean up and bail out */
4469 if (pipe_err < 0)
4470 {
4471 for (i = 0; i < 3; i++)
4472 {
4473 close(p_fd[i].rd);
4474 close(p_fd[i].wr);
4475 }
4476 errno = EPIPE;
4477 return posix_error_with_filename(cmdstring);
4478 }
4479
4480 /* build tuple of file objects to return */
4481 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4482 PyFile_SetBufSize(p_f[0], bufsize);
4483 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4484 PyFile_SetBufSize(p_f[1], bufsize);
4485 if (n == POPEN_3)
4486 {
4487 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4488 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004489 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004490 }
4491 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004492 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004493
4494 /*
4495 * Insert the files we've created into the process dictionary
4496 * all referencing the list with the process handle and the
4497 * initial number of files (see description below in _PyPclose).
4498 * Since if _PyPclose later tried to wait on a process when all
4499 * handles weren't closed, it could create a deadlock with the
4500 * child, we spend some energy here to try to ensure that we
4501 * either insert all file handles into the dictionary or none
4502 * at all. It's a little clumsy with the various popen modes
4503 * and variable number of files involved.
4504 */
4505 if (!_PyPopenProcs)
4506 {
4507 _PyPopenProcs = PyDict_New();
4508 }
4509
4510 if (_PyPopenProcs)
4511 {
4512 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4513 int ins_rc[3];
4514
4515 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4516 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4517
4518 procObj = PyList_New(2);
4519 pidObj = PyInt_FromLong((long) pipe_pid);
4520 intObj = PyInt_FromLong((long) file_count);
4521
4522 if (procObj && pidObj && intObj)
4523 {
4524 PyList_SetItem(procObj, 0, pidObj);
4525 PyList_SetItem(procObj, 1, intObj);
4526
4527 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4528 if (fileObj[0])
4529 {
4530 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4531 fileObj[0],
4532 procObj);
4533 }
4534 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4535 if (fileObj[1])
4536 {
4537 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4538 fileObj[1],
4539 procObj);
4540 }
4541 if (file_count >= 3)
4542 {
4543 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4544 if (fileObj[2])
4545 {
4546 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4547 fileObj[2],
4548 procObj);
4549 }
4550 }
4551
4552 if (ins_rc[0] < 0 || !fileObj[0] ||
4553 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4554 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4555 {
4556 /* Something failed - remove any dictionary
4557 * entries that did make it.
4558 */
4559 if (!ins_rc[0] && fileObj[0])
4560 {
4561 PyDict_DelItem(_PyPopenProcs,
4562 fileObj[0]);
4563 }
4564 if (!ins_rc[1] && fileObj[1])
4565 {
4566 PyDict_DelItem(_PyPopenProcs,
4567 fileObj[1]);
4568 }
4569 if (!ins_rc[2] && fileObj[2])
4570 {
4571 PyDict_DelItem(_PyPopenProcs,
4572 fileObj[2]);
4573 }
4574 }
4575 }
Tim Peters11b23062003-04-23 02:39:17 +00004576
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004577 /*
4578 * Clean up our localized references for the dictionary keys
4579 * and value since PyDict_SetItem will Py_INCREF any copies
4580 * that got placed in the dictionary.
4581 */
4582 Py_XDECREF(procObj);
4583 Py_XDECREF(fileObj[0]);
4584 Py_XDECREF(fileObj[1]);
4585 Py_XDECREF(fileObj[2]);
4586 }
4587
4588 /* Child is launched. */
4589 return f;
4590}
4591
4592/*
4593 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4594 * exit code for the child process and return as a result of the close.
4595 *
4596 * This function uses the _PyPopenProcs dictionary in order to map the
4597 * input file pointer to information about the process that was
4598 * originally created by the popen* call that created the file pointer.
4599 * The dictionary uses the file pointer as a key (with one entry
4600 * inserted for each file returned by the original popen* call) and a
4601 * single list object as the value for all files from a single call.
4602 * The list object contains the Win32 process handle at [0], and a file
4603 * count at [1], which is initialized to the total number of file
4604 * handles using that list.
4605 *
4606 * This function closes whichever handle it is passed, and decrements
4607 * the file count in the dictionary for the process handle pointed to
4608 * by this file. On the last close (when the file count reaches zero),
4609 * this function will wait for the child process and then return its
4610 * exit code as the result of the close() operation. This permits the
4611 * files to be closed in any order - it is always the close() of the
4612 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004613 *
4614 * NOTE: This function is currently called with the GIL released.
4615 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004616 */
4617
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004618static int _PyPclose(FILE *file)
4619{
4620 int result;
4621 int exit_code;
Christian Heimesd491d712008-02-01 18:49:26 +00004622 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004623 PyObject *procObj, *pidObj, *intObj, *fileObj;
4624 int file_count;
4625#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004626 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004627#endif
4628
4629 /* Close the file handle first, to ensure it can't block the
4630 * child from exiting if it's the last handle.
4631 */
4632 result = fclose(file);
4633
4634#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004635 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004636#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004637 if (_PyPopenProcs)
4638 {
4639 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4640 (procObj = PyDict_GetItem(_PyPopenProcs,
4641 fileObj)) != NULL &&
4642 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4643 (intObj = PyList_GetItem(procObj,1)) != NULL)
4644 {
4645 pipe_pid = (int) PyInt_AsLong(pidObj);
4646 file_count = (int) PyInt_AsLong(intObj);
4647
4648 if (file_count > 1)
4649 {
4650 /* Still other files referencing process */
4651 file_count--;
4652 PyList_SetItem(procObj,1,
4653 PyInt_FromLong((long) file_count));
4654 }
4655 else
4656 {
4657 /* Last file for this process */
4658 if (result != EOF &&
4659 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4660 {
4661 /* extract exit status */
4662 if (WIFEXITED(exit_code))
4663 {
4664 result = WEXITSTATUS(exit_code);
4665 }
4666 else
4667 {
4668 errno = EPIPE;
4669 result = -1;
4670 }
4671 }
4672 else
4673 {
4674 /* Indicate failure - this will cause the file object
4675 * to raise an I/O error and translate the last
4676 * error code from errno. We do have a problem with
4677 * last errors that overlap the normal errno table,
4678 * but that's a consistent problem with the file object.
4679 */
4680 result = -1;
4681 }
4682 }
4683
4684 /* Remove this file pointer from dictionary */
4685 PyDict_DelItem(_PyPopenProcs, fileObj);
4686
4687 if (PyDict_Size(_PyPopenProcs) == 0)
4688 {
4689 Py_DECREF(_PyPopenProcs);
4690 _PyPopenProcs = NULL;
4691 }
4692
4693 } /* if object retrieval ok */
4694
4695 Py_XDECREF(fileObj);
4696 } /* if _PyPopenProcs */
4697
4698#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004699 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004700#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004701 return result;
4702}
4703
4704#endif /* PYCC_??? */
4705
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004706#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004707
4708/*
4709 * Portable 'popen' replacement for Win32.
4710 *
4711 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4712 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004713 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004714 */
4715
4716#include <malloc.h>
4717#include <io.h>
4718#include <fcntl.h>
4719
4720/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4721#define POPEN_1 1
4722#define POPEN_2 2
4723#define POPEN_3 3
4724#define POPEN_4 4
4725
4726static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004727static int _PyPclose(FILE *file);
4728
4729/*
4730 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004731 * for use when retrieving the process exit code. See _PyPclose() below
4732 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004733 */
4734static PyObject *_PyPopenProcs = NULL;
4735
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004736
4737/* popen that works from a GUI.
4738 *
4739 * The result of this function is a pipe (file) connected to the
4740 * processes stdin or stdout, depending on the requested mode.
4741 */
4742
4743static PyObject *
4744posix_popen(PyObject *self, PyObject *args)
4745{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004746 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004747 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004748
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004749 char *cmdstring;
4750 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004751 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004752 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004753 return NULL;
4754
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004755 if (*mode == 'r')
4756 tm = _O_RDONLY;
4757 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004758 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004759 return NULL;
4760 } else
4761 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004762
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004763 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004764 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004765 return NULL;
4766 }
4767
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004768 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004769 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004770 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004771 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004772 else
4773 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4774
4775 return f;
4776}
4777
4778/* Variation on win32pipe.popen
4779 *
4780 * The result of this function is a pipe (file) connected to the
4781 * process's stdin, and a pipe connected to the process's stdout.
4782 */
4783
4784static PyObject *
4785win32_popen2(PyObject *self, PyObject *args)
4786{
4787 PyObject *f;
4788 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004789
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004790 char *cmdstring;
4791 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004792 int bufsize = -1;
4793 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004794 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004795
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004796 if (*mode == 't')
4797 tm = _O_TEXT;
4798 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004799 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004800 return NULL;
4801 } else
4802 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004803
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004804 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004805 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004806 return NULL;
4807 }
4808
4809 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004810
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004811 return f;
4812}
4813
4814/*
4815 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004816 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004817 * The result of this function is 3 pipes - the process's stdin,
4818 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004819 */
4820
4821static PyObject *
4822win32_popen3(PyObject *self, PyObject *args)
4823{
4824 PyObject *f;
4825 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004826
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004827 char *cmdstring;
4828 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004829 int bufsize = -1;
4830 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004831 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004832
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004833 if (*mode == 't')
4834 tm = _O_TEXT;
4835 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004836 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004837 return NULL;
4838 } else
4839 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004840
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004841 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004842 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004843 return NULL;
4844 }
4845
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004846 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004847
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004848 return f;
4849}
4850
4851/*
4852 * Variation on win32pipe.popen
4853 *
Tim Peters5aa91602002-01-30 05:46:57 +00004854 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004855 * and stdout+stderr combined as a single pipe.
4856 */
4857
4858static PyObject *
4859win32_popen4(PyObject *self, PyObject *args)
4860{
4861 PyObject *f;
4862 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004863
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004864 char *cmdstring;
4865 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004866 int bufsize = -1;
4867 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004868 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004869
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004870 if (*mode == 't')
4871 tm = _O_TEXT;
4872 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004873 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004874 return NULL;
4875 } else
4876 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004877
4878 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004879 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004880 return NULL;
4881 }
4882
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004883 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004884
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004885 return f;
4886}
4887
Mark Hammond08501372001-01-31 07:30:29 +00004888static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004889_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004890 HANDLE hStdin,
4891 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004892 HANDLE hStderr,
4893 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004894{
4895 PROCESS_INFORMATION piProcInfo;
4896 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004897 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004898 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004899 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004900 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004901 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004902
4903 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004904 char *comshell;
4905
Tim Peters92e4dd82002-10-05 01:47:34 +00004906 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004907 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004908 /* x < i, so x fits into an integer */
4909 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004910
4911 /* Explicitly check if we are using COMMAND.COM. If we are
4912 * then use the w9xpopen hack.
4913 */
4914 comshell = s1 + x;
4915 while (comshell >= s1 && *comshell != '\\')
4916 --comshell;
4917 ++comshell;
4918
4919 if (GetVersion() < 0x80000000 &&
4920 _stricmp(comshell, "command.com") != 0) {
4921 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004922 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004923 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004924 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004925 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004926 }
4927 else {
4928 /*
Tim Peters402d5982001-08-27 06:37:48 +00004929 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4930 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004931 */
Mark Hammond08501372001-01-31 07:30:29 +00004932 char modulepath[_MAX_PATH];
4933 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004934 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Martin v. Löwis26fd9602006-04-22 11:15:41 +00004935 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004936 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004937 x = i+1;
4938 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004939 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004940 strncat(modulepath,
4941 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004942 (sizeof(modulepath)/sizeof(modulepath[0]))
4943 -strlen(modulepath));
4944 if (stat(modulepath, &statinfo) != 0) {
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00004945 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
Tim Peters5aa91602002-01-30 05:46:57 +00004946 /* Eeek - file-not-found - possibly an embedding
4947 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004948 */
Tim Peters5aa91602002-01-30 05:46:57 +00004949 strncpy(modulepath,
4950 Py_GetExecPrefix(),
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00004951 mplen);
4952 modulepath[mplen-1] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004953 if (modulepath[strlen(modulepath)-1] != '\\')
4954 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004955 strncat(modulepath,
4956 szConsoleSpawn,
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00004957 mplen-strlen(modulepath));
Mark Hammond08501372001-01-31 07:30:29 +00004958 /* No where else to look - raise an easily identifiable
4959 error, rather than leaving Windows to report
4960 "file not found" - as the user is probably blissfully
4961 unaware this shim EXE is used, and it will confuse them.
4962 (well, it confused me for a while ;-)
4963 */
4964 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004965 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004966 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004967 "for popen to work with your shell "
4968 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004969 szConsoleSpawn);
4970 return FALSE;
4971 }
4972 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004973 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004974 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004975 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004976
Tim Peters92e4dd82002-10-05 01:47:34 +00004977 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004978 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004979 /* To maintain correct argument passing semantics,
4980 we pass the command-line as it stands, and allow
4981 quoting to be applied. w9xpopen.exe will then
4982 use its argv vector, and re-quote the necessary
4983 args for the ultimate child process.
4984 */
Tim Peters75cdad52001-11-28 22:07:30 +00004985 PyOS_snprintf(
4986 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004987 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004988 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004989 s1,
4990 s3,
4991 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004992 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004993 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004994 dialog:
4995 "Your program accessed mem currently in use at xxx"
4996 and a hopeful warning about the stability of your
4997 system.
4998 Cost is Ctrl+C wont kill children, but anyone
4999 who cares can have a go!
5000 */
5001 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005002 }
5003 }
5004
5005 /* Could be an else here to try cmd.exe / command.com in the path
5006 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00005007 else {
Tim Peters402d5982001-08-27 06:37:48 +00005008 PyErr_SetString(PyExc_RuntimeError,
5009 "Cannot locate a COMSPEC environment variable to "
5010 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00005011 return FALSE;
5012 }
Tim Peters5aa91602002-01-30 05:46:57 +00005013
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005014 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5015 siStartInfo.cb = sizeof(STARTUPINFO);
5016 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5017 siStartInfo.hStdInput = hStdin;
5018 siStartInfo.hStdOutput = hStdout;
5019 siStartInfo.hStdError = hStderr;
5020 siStartInfo.wShowWindow = SW_HIDE;
5021
5022 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005023 s2,
5024 NULL,
5025 NULL,
5026 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005027 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005028 NULL,
5029 NULL,
5030 &siStartInfo,
5031 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005032 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005033 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005034
Mark Hammondb37a3732000-08-14 04:47:33 +00005035 /* Return process handle */
5036 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005037 return TRUE;
5038 }
Tim Peters402d5982001-08-27 06:37:48 +00005039 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005040 return FALSE;
5041}
5042
5043/* The following code is based off of KB: Q190351 */
5044
5045static PyObject *
5046_PyPopen(char *cmdstring, int mode, int n)
5047{
5048 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5049 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00005050 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005051
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005052 SECURITY_ATTRIBUTES saAttr;
5053 BOOL fSuccess;
5054 int fd1, fd2, fd3;
5055 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00005056 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005057 PyObject *f;
5058
5059 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5060 saAttr.bInheritHandle = TRUE;
5061 saAttr.lpSecurityDescriptor = NULL;
5062
5063 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5064 return win32_error("CreatePipe", NULL);
5065
5066 /* Create new output read handle and the input write handle. Set
5067 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005068 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005069 * being created. */
5070 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005071 GetCurrentProcess(), &hChildStdinWrDup, 0,
5072 FALSE,
5073 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005074 if (!fSuccess)
5075 return win32_error("DuplicateHandle", NULL);
5076
5077 /* Close the inheritable version of ChildStdin
5078 that we're using. */
5079 CloseHandle(hChildStdinWr);
5080
5081 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5082 return win32_error("CreatePipe", NULL);
5083
5084 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005085 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5086 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005087 if (!fSuccess)
5088 return win32_error("DuplicateHandle", NULL);
5089
5090 /* Close the inheritable version of ChildStdout
5091 that we're using. */
5092 CloseHandle(hChildStdoutRd);
5093
5094 if (n != POPEN_4) {
5095 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5096 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005097 fSuccess = DuplicateHandle(GetCurrentProcess(),
5098 hChildStderrRd,
5099 GetCurrentProcess(),
5100 &hChildStderrRdDup, 0,
5101 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005102 if (!fSuccess)
5103 return win32_error("DuplicateHandle", NULL);
5104 /* Close the inheritable version of ChildStdErr that we're using. */
5105 CloseHandle(hChildStderrRd);
5106 }
Tim Peters5aa91602002-01-30 05:46:57 +00005107
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005108 switch (n) {
5109 case POPEN_1:
5110 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5111 case _O_WRONLY | _O_TEXT:
5112 /* Case for writing to child Stdin in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005113 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005114 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005115 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005116 PyFile_SetBufSize(f, 0);
5117 /* We don't care about these pipes anymore, so close them. */
5118 CloseHandle(hChildStdoutRdDup);
5119 CloseHandle(hChildStderrRdDup);
5120 break;
5121
5122 case _O_RDONLY | _O_TEXT:
5123 /* Case for reading from child Stdout in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005124 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005125 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005126 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005127 PyFile_SetBufSize(f, 0);
5128 /* We don't care about these pipes anymore, so close them. */
5129 CloseHandle(hChildStdinWrDup);
5130 CloseHandle(hChildStderrRdDup);
5131 break;
5132
5133 case _O_RDONLY | _O_BINARY:
5134 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005135 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005136 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005137 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005138 PyFile_SetBufSize(f, 0);
5139 /* We don't care about these pipes anymore, so close them. */
5140 CloseHandle(hChildStdinWrDup);
5141 CloseHandle(hChildStderrRdDup);
5142 break;
5143
5144 case _O_WRONLY | _O_BINARY:
5145 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005146 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005147 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005148 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005149 PyFile_SetBufSize(f, 0);
5150 /* We don't care about these pipes anymore, so close them. */
5151 CloseHandle(hChildStdoutRdDup);
5152 CloseHandle(hChildStderrRdDup);
5153 break;
5154 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005155 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005156 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005157
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005158 case POPEN_2:
5159 case POPEN_4:
5160 {
5161 char *m1, *m2;
5162 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005163
Tim Peters7dca21e2002-08-19 00:42:29 +00005164 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005165 m1 = "r";
5166 m2 = "w";
5167 } else {
5168 m1 = "rb";
5169 m2 = "wb";
5170 }
5171
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005172 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005173 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005174 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005175 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005176 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005177 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00005178 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005179 PyFile_SetBufSize(p2, 0);
5180
5181 if (n != 4)
5182 CloseHandle(hChildStderrRdDup);
5183
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005184 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00005185 Py_XDECREF(p1);
5186 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00005187 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005188 break;
5189 }
Tim Peters5aa91602002-01-30 05:46:57 +00005190
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005191 case POPEN_3:
5192 {
5193 char *m1, *m2;
5194 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005195
Tim Peters7dca21e2002-08-19 00:42:29 +00005196 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005197 m1 = "r";
5198 m2 = "w";
5199 } else {
5200 m1 = "rb";
5201 m2 = "wb";
5202 }
5203
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005204 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005205 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005206 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005207 f2 = _fdopen(fd2, m1);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005208 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005209 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005210 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00005211 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5212 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005213 PyFile_SetBufSize(p1, 0);
5214 PyFile_SetBufSize(p2, 0);
5215 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005216 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00005217 Py_XDECREF(p1);
5218 Py_XDECREF(p2);
5219 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00005220 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005221 break;
5222 }
5223 }
5224
5225 if (n == POPEN_4) {
5226 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005227 hChildStdinRd,
5228 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005229 hChildStdoutWr,
5230 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005231 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005232 }
5233 else {
5234 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005235 hChildStdinRd,
5236 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005237 hChildStderrWr,
5238 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005239 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005240 }
5241
Mark Hammondb37a3732000-08-14 04:47:33 +00005242 /*
5243 * Insert the files we've created into the process dictionary
5244 * all referencing the list with the process handle and the
5245 * initial number of files (see description below in _PyPclose).
5246 * Since if _PyPclose later tried to wait on a process when all
5247 * handles weren't closed, it could create a deadlock with the
5248 * child, we spend some energy here to try to ensure that we
5249 * either insert all file handles into the dictionary or none
5250 * at all. It's a little clumsy with the various popen modes
5251 * and variable number of files involved.
5252 */
5253 if (!_PyPopenProcs) {
5254 _PyPopenProcs = PyDict_New();
5255 }
5256
5257 if (_PyPopenProcs) {
5258 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5259 int ins_rc[3];
5260
5261 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5262 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
5263
5264 procObj = PyList_New(2);
5265 hProcessObj = PyLong_FromVoidPtr(hProcess);
5266 intObj = PyInt_FromLong(file_count);
5267
5268 if (procObj && hProcessObj && intObj) {
5269 PyList_SetItem(procObj,0,hProcessObj);
5270 PyList_SetItem(procObj,1,intObj);
5271
5272 fileObj[0] = PyLong_FromVoidPtr(f1);
5273 if (fileObj[0]) {
5274 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5275 fileObj[0],
5276 procObj);
5277 }
5278 if (file_count >= 2) {
5279 fileObj[1] = PyLong_FromVoidPtr(f2);
5280 if (fileObj[1]) {
5281 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5282 fileObj[1],
5283 procObj);
5284 }
5285 }
5286 if (file_count >= 3) {
5287 fileObj[2] = PyLong_FromVoidPtr(f3);
5288 if (fileObj[2]) {
5289 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5290 fileObj[2],
5291 procObj);
5292 }
5293 }
5294
5295 if (ins_rc[0] < 0 || !fileObj[0] ||
5296 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5297 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5298 /* Something failed - remove any dictionary
5299 * entries that did make it.
5300 */
5301 if (!ins_rc[0] && fileObj[0]) {
5302 PyDict_DelItem(_PyPopenProcs,
5303 fileObj[0]);
5304 }
5305 if (!ins_rc[1] && fileObj[1]) {
5306 PyDict_DelItem(_PyPopenProcs,
5307 fileObj[1]);
5308 }
5309 if (!ins_rc[2] && fileObj[2]) {
5310 PyDict_DelItem(_PyPopenProcs,
5311 fileObj[2]);
5312 }
5313 }
5314 }
Tim Peters5aa91602002-01-30 05:46:57 +00005315
Mark Hammondb37a3732000-08-14 04:47:33 +00005316 /*
5317 * Clean up our localized references for the dictionary keys
5318 * and value since PyDict_SetItem will Py_INCREF any copies
5319 * that got placed in the dictionary.
5320 */
5321 Py_XDECREF(procObj);
5322 Py_XDECREF(fileObj[0]);
5323 Py_XDECREF(fileObj[1]);
5324 Py_XDECREF(fileObj[2]);
5325 }
5326
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005327 /* Child is launched. Close the parents copy of those pipe
5328 * handles that only the child should have open. You need to
5329 * make sure that no handles to the write end of the output pipe
5330 * are maintained in this process or else the pipe will not close
5331 * when the child process exits and the ReadFile will hang. */
5332
5333 if (!CloseHandle(hChildStdinRd))
5334 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005335
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005336 if (!CloseHandle(hChildStdoutWr))
5337 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005338
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005339 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5340 return win32_error("CloseHandle", NULL);
5341
5342 return f;
5343}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005344
5345/*
5346 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5347 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005348 *
5349 * This function uses the _PyPopenProcs dictionary in order to map the
5350 * input file pointer to information about the process that was
5351 * originally created by the popen* call that created the file pointer.
5352 * The dictionary uses the file pointer as a key (with one entry
5353 * inserted for each file returned by the original popen* call) and a
5354 * single list object as the value for all files from a single call.
5355 * The list object contains the Win32 process handle at [0], and a file
5356 * count at [1], which is initialized to the total number of file
5357 * handles using that list.
5358 *
5359 * This function closes whichever handle it is passed, and decrements
5360 * the file count in the dictionary for the process handle pointed to
5361 * by this file. On the last close (when the file count reaches zero),
5362 * this function will wait for the child process and then return its
5363 * exit code as the result of the close() operation. This permits the
5364 * files to be closed in any order - it is always the close() of the
5365 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005366 *
5367 * NOTE: This function is currently called with the GIL released.
5368 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005369 */
Tim Peters736aa322000-09-01 06:51:24 +00005370
Fredrik Lundh56055a42000-07-23 19:47:12 +00005371static int _PyPclose(FILE *file)
5372{
Fredrik Lundh20318932000-07-26 17:29:12 +00005373 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005374 DWORD exit_code;
5375 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00005376 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5377 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005378#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005379 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005380#endif
5381
Fredrik Lundh20318932000-07-26 17:29:12 +00005382 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00005383 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00005384 */
5385 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005386#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005387 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005388#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005389 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005390 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5391 (procObj = PyDict_GetItem(_PyPopenProcs,
5392 fileObj)) != NULL &&
5393 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5394 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5395
5396 hProcess = PyLong_AsVoidPtr(hProcessObj);
5397 file_count = PyInt_AsLong(intObj);
5398
5399 if (file_count > 1) {
5400 /* Still other files referencing process */
5401 file_count--;
5402 PyList_SetItem(procObj,1,
5403 PyInt_FromLong(file_count));
5404 } else {
5405 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00005406 if (result != EOF &&
5407 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5408 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00005409 /* Possible truncation here in 16-bit environments, but
5410 * real exit codes are just the lower byte in any event.
5411 */
5412 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005413 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00005414 /* Indicate failure - this will cause the file object
5415 * to raise an I/O error and translate the last Win32
5416 * error code from errno. We do have a problem with
5417 * last errors that overlap the normal errno table,
5418 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005419 */
Fredrik Lundh20318932000-07-26 17:29:12 +00005420 if (result != EOF) {
5421 /* If the error wasn't from the fclose(), then
5422 * set errno for the file object error handling.
5423 */
5424 errno = GetLastError();
5425 }
5426 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005427 }
5428
5429 /* Free up the native handle at this point */
5430 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00005431 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005432
Mark Hammondb37a3732000-08-14 04:47:33 +00005433 /* Remove this file pointer from dictionary */
5434 PyDict_DelItem(_PyPopenProcs, fileObj);
5435
5436 if (PyDict_Size(_PyPopenProcs) == 0) {
5437 Py_DECREF(_PyPopenProcs);
5438 _PyPopenProcs = NULL;
5439 }
5440
5441 } /* if object retrieval ok */
5442
5443 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005444 } /* if _PyPopenProcs */
5445
Tim Peters736aa322000-09-01 06:51:24 +00005446#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005447 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005448#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005449 return result;
5450}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005451
5452#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005453static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005454posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005455{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005456 char *name;
5457 char *mode = "r";
5458 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00005459 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005460 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005461 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00005462 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00005463 /* Strip mode of binary or text modifiers */
5464 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5465 mode = "r";
5466 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5467 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00005468 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005469 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005470 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00005471 if (fp == NULL)
5472 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005473 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005474 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005475 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005476 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005477}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005478
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005479#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005480#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005481
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005482
Guido van Rossumb6775db1994-08-01 11:34:53 +00005483#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005484PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005485"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005486Set the current process's user id.");
5487
Barry Warsaw53699e91996-12-10 23:23:01 +00005488static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005489posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005490{
5491 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005492 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005493 return NULL;
5494 if (setuid(uid) < 0)
5495 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005496 Py_INCREF(Py_None);
5497 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005498}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005499#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005500
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005501
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005502#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005503PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005504"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005505Set the current process's effective user id.");
5506
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005507static PyObject *
5508posix_seteuid (PyObject *self, PyObject *args)
5509{
5510 int euid;
5511 if (!PyArg_ParseTuple(args, "i", &euid)) {
5512 return NULL;
5513 } else if (seteuid(euid) < 0) {
5514 return posix_error();
5515 } else {
5516 Py_INCREF(Py_None);
5517 return Py_None;
5518 }
5519}
5520#endif /* HAVE_SETEUID */
5521
5522#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005523PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005524"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005525Set the current process's effective group id.");
5526
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005527static PyObject *
5528posix_setegid (PyObject *self, PyObject *args)
5529{
5530 int egid;
5531 if (!PyArg_ParseTuple(args, "i", &egid)) {
5532 return NULL;
5533 } else if (setegid(egid) < 0) {
5534 return posix_error();
5535 } else {
5536 Py_INCREF(Py_None);
5537 return Py_None;
5538 }
5539}
5540#endif /* HAVE_SETEGID */
5541
5542#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005543PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005544"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005545Set the current process's real and effective user ids.");
5546
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005547static PyObject *
5548posix_setreuid (PyObject *self, PyObject *args)
5549{
5550 int ruid, euid;
5551 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
5552 return NULL;
5553 } else if (setreuid(ruid, euid) < 0) {
5554 return posix_error();
5555 } else {
5556 Py_INCREF(Py_None);
5557 return Py_None;
5558 }
5559}
5560#endif /* HAVE_SETREUID */
5561
5562#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005563PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005564"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005565Set the current process's real and effective group ids.");
5566
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005567static PyObject *
5568posix_setregid (PyObject *self, PyObject *args)
5569{
5570 int rgid, egid;
5571 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
5572 return NULL;
5573 } else if (setregid(rgid, egid) < 0) {
5574 return posix_error();
5575 } else {
5576 Py_INCREF(Py_None);
5577 return Py_None;
5578 }
5579}
5580#endif /* HAVE_SETREGID */
5581
Guido van Rossumb6775db1994-08-01 11:34:53 +00005582#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005583PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005584"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005585Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005586
Barry Warsaw53699e91996-12-10 23:23:01 +00005587static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005588posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005589{
5590 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005591 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005592 return NULL;
5593 if (setgid(gid) < 0)
5594 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005595 Py_INCREF(Py_None);
5596 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005597}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005598#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005599
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005600#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005601PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005602"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005603Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005604
5605static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005606posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005607{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005608 int i, len;
5609 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005610
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005611 if (!PySequence_Check(groups)) {
5612 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5613 return NULL;
5614 }
5615 len = PySequence_Size(groups);
5616 if (len > MAX_GROUPS) {
5617 PyErr_SetString(PyExc_ValueError, "too many groups");
5618 return NULL;
5619 }
5620 for(i = 0; i < len; i++) {
5621 PyObject *elem;
5622 elem = PySequence_GetItem(groups, i);
5623 if (!elem)
5624 return NULL;
5625 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005626 if (!PyLong_Check(elem)) {
5627 PyErr_SetString(PyExc_TypeError,
5628 "groups must be integers");
5629 Py_DECREF(elem);
5630 return NULL;
5631 } else {
5632 unsigned long x = PyLong_AsUnsignedLong(elem);
5633 if (PyErr_Occurred()) {
5634 PyErr_SetString(PyExc_TypeError,
5635 "group id too big");
5636 Py_DECREF(elem);
5637 return NULL;
5638 }
5639 grouplist[i] = x;
5640 /* read back the value to see if it fitted in gid_t */
5641 if (grouplist[i] != x) {
5642 PyErr_SetString(PyExc_TypeError,
5643 "group id too big");
5644 Py_DECREF(elem);
5645 return NULL;
5646 }
5647 }
5648 } else {
5649 long x = PyInt_AsLong(elem);
5650 grouplist[i] = x;
5651 if (grouplist[i] != x) {
5652 PyErr_SetString(PyExc_TypeError,
5653 "group id too big");
5654 Py_DECREF(elem);
5655 return NULL;
5656 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005657 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005658 Py_DECREF(elem);
5659 }
5660
5661 if (setgroups(len, grouplist) < 0)
5662 return posix_error();
5663 Py_INCREF(Py_None);
5664 return Py_None;
5665}
5666#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005667
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005668#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005669static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00005670wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00005671{
5672 PyObject *result;
5673 static PyObject *struct_rusage;
5674
5675 if (pid == -1)
5676 return posix_error();
5677
5678 if (struct_rusage == NULL) {
Christian Heimes000a0742008-01-03 22:16:32 +00005679 PyObject *m = PyImport_ImportModuleNoBlock("resource");
Neal Norwitz05a45592006-03-20 06:30:08 +00005680 if (m == NULL)
5681 return NULL;
5682 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5683 Py_DECREF(m);
5684 if (struct_rusage == NULL)
5685 return NULL;
5686 }
5687
5688 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5689 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5690 if (!result)
5691 return NULL;
5692
5693#ifndef doubletime
5694#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5695#endif
5696
5697 PyStructSequence_SET_ITEM(result, 0,
5698 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5699 PyStructSequence_SET_ITEM(result, 1,
5700 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5701#define SET_INT(result, index, value)\
5702 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5703 SET_INT(result, 2, ru->ru_maxrss);
5704 SET_INT(result, 3, ru->ru_ixrss);
5705 SET_INT(result, 4, ru->ru_idrss);
5706 SET_INT(result, 5, ru->ru_isrss);
5707 SET_INT(result, 6, ru->ru_minflt);
5708 SET_INT(result, 7, ru->ru_majflt);
5709 SET_INT(result, 8, ru->ru_nswap);
5710 SET_INT(result, 9, ru->ru_inblock);
5711 SET_INT(result, 10, ru->ru_oublock);
5712 SET_INT(result, 11, ru->ru_msgsnd);
5713 SET_INT(result, 12, ru->ru_msgrcv);
5714 SET_INT(result, 13, ru->ru_nsignals);
5715 SET_INT(result, 14, ru->ru_nvcsw);
5716 SET_INT(result, 15, ru->ru_nivcsw);
5717#undef SET_INT
5718
5719 if (PyErr_Occurred()) {
5720 Py_DECREF(result);
5721 return NULL;
5722 }
5723
Neal Norwitz9b00a562006-03-20 08:47:12 +00005724 return Py_BuildValue("iiN", pid, status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005725}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005726#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005727
5728#ifdef HAVE_WAIT3
5729PyDoc_STRVAR(posix_wait3__doc__,
5730"wait3(options) -> (pid, status, rusage)\n\n\
5731Wait for completion of a child process.");
5732
5733static PyObject *
5734posix_wait3(PyObject *self, PyObject *args)
5735{
Christian Heimesd491d712008-02-01 18:49:26 +00005736 pid_t pid;
5737 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005738 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005739 WAIT_TYPE status;
5740 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005741
5742 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5743 return NULL;
5744
5745 Py_BEGIN_ALLOW_THREADS
5746 pid = wait3(&status, options, &ru);
5747 Py_END_ALLOW_THREADS
5748
Neal Norwitzd5a37542006-03-20 06:48:34 +00005749 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005750}
5751#endif /* HAVE_WAIT3 */
5752
5753#ifdef HAVE_WAIT4
5754PyDoc_STRVAR(posix_wait4__doc__,
5755"wait4(pid, options) -> (pid, status, rusage)\n\n\
5756Wait for completion of a given child process.");
5757
5758static PyObject *
5759posix_wait4(PyObject *self, PyObject *args)
5760{
Christian Heimesd491d712008-02-01 18:49:26 +00005761 pid_t pid;
5762 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005763 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005764 WAIT_TYPE status;
5765 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005766
5767 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5768 return NULL;
5769
5770 Py_BEGIN_ALLOW_THREADS
5771 pid = wait4(pid, &status, options, &ru);
5772 Py_END_ALLOW_THREADS
5773
Neal Norwitzd5a37542006-03-20 06:48:34 +00005774 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005775}
5776#endif /* HAVE_WAIT4 */
5777
Guido van Rossumb6775db1994-08-01 11:34:53 +00005778#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005779PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005780"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005781Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005782
Barry Warsaw53699e91996-12-10 23:23:01 +00005783static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005784posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005785{
Christian Heimesd491d712008-02-01 18:49:26 +00005786 pid_t pid;
5787 int options;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005788 WAIT_TYPE status;
5789 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005790
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005791 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005792 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005793 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005794 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005795 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005796 if (pid == -1)
5797 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005798
5799 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005800}
5801
Tim Petersab034fa2002-02-01 11:27:43 +00005802#elif defined(HAVE_CWAIT)
5803
5804/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005805PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005806"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005807"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005808
5809static PyObject *
5810posix_waitpid(PyObject *self, PyObject *args)
5811{
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005812 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005813 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005814
5815 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5816 return NULL;
5817 Py_BEGIN_ALLOW_THREADS
5818 pid = _cwait(&status, pid, options);
5819 Py_END_ALLOW_THREADS
5820 if (pid == -1)
5821 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005822
5823 /* shift the status left a byte so this is more like the POSIX waitpid */
5824 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005825}
5826#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005827
Guido van Rossumad0ee831995-03-01 10:34:45 +00005828#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005829PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005830"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005831Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005832
Barry Warsaw53699e91996-12-10 23:23:01 +00005833static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005834posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005835{
Christian Heimesd491d712008-02-01 18:49:26 +00005836 pid_t pid;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005837 WAIT_TYPE status;
5838 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005839
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005840 Py_BEGIN_ALLOW_THREADS
5841 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005842 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005843 if (pid == -1)
5844 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005845
5846 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005847}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005848#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005849
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005850
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005851PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005852"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005853Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005854
Barry Warsaw53699e91996-12-10 23:23:01 +00005855static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005856posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005857{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005858#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005859 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005860#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005861#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005862 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005863#else
5864 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5865#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005866#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005867}
5868
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005869
Guido van Rossumb6775db1994-08-01 11:34:53 +00005870#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005871PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005872"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005873Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005874
Barry Warsaw53699e91996-12-10 23:23:01 +00005875static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005876posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005877{
Ronald Oussoren10168f22006-10-22 10:45:18 +00005878 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005879 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005880 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005881 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00005882#ifdef Py_USING_UNICODE
5883 int arg_is_unicode = 0;
5884#endif
5885
5886 if (!PyArg_ParseTuple(args, "et:readlink",
5887 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005888 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00005889#ifdef Py_USING_UNICODE
5890 v = PySequence_GetItem(args, 0);
Neal Norwitz91a57212007-08-12 17:11:13 +00005891 if (v == NULL) {
5892 PyMem_Free(path);
5893 return NULL;
5894 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00005895
5896 if (PyUnicode_Check(v)) {
5897 arg_is_unicode = 1;
5898 }
5899 Py_DECREF(v);
5900#endif
5901
Barry Warsaw53699e91996-12-10 23:23:01 +00005902 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005903 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005904 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005905 if (n < 0)
Neal Norwitz91a57212007-08-12 17:11:13 +00005906 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00005907
Neal Norwitz91a57212007-08-12 17:11:13 +00005908 PyMem_Free(path);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00005909 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00005910#ifdef Py_USING_UNICODE
5911 if (arg_is_unicode) {
5912 PyObject *w;
5913
5914 w = PyUnicode_FromEncodedObject(v,
5915 Py_FileSystemDefaultEncoding,
5916 "strict");
5917 if (w != NULL) {
5918 Py_DECREF(v);
5919 v = w;
5920 }
5921 else {
5922 /* fall back to the original byte string, as
5923 discussed in patch #683592 */
5924 PyErr_Clear();
5925 }
5926 }
5927#endif
5928 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005929}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005930#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005931
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005932
Guido van Rossumb6775db1994-08-01 11:34:53 +00005933#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005934PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005935"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005936Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005937
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005938static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005939posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005940{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00005941 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005942}
5943#endif /* HAVE_SYMLINK */
5944
5945
5946#ifdef HAVE_TIMES
5947#ifndef HZ
5948#define HZ 60 /* Universal constant :-) */
5949#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005950
Guido van Rossumd48f2521997-12-05 22:19:34 +00005951#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5952static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005953system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005954{
5955 ULONG value = 0;
5956
5957 Py_BEGIN_ALLOW_THREADS
5958 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5959 Py_END_ALLOW_THREADS
5960
5961 return value;
5962}
5963
5964static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005965posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005966{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005967 /* Currently Only Uptime is Provided -- Others Later */
5968 return Py_BuildValue("ddddd",
5969 (double)0 /* t.tms_utime / HZ */,
5970 (double)0 /* t.tms_stime / HZ */,
5971 (double)0 /* t.tms_cutime / HZ */,
5972 (double)0 /* t.tms_cstime / HZ */,
5973 (double)system_uptime() / 1000);
5974}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005975#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005976static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005977posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005978{
5979 struct tms t;
5980 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005981 errno = 0;
5982 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005983 if (c == (clock_t) -1)
5984 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005985 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005986 (double)t.tms_utime / HZ,
5987 (double)t.tms_stime / HZ,
5988 (double)t.tms_cutime / HZ,
5989 (double)t.tms_cstime / HZ,
5990 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005991}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005992#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005993#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005994
5995
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005996#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005997#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005998static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005999posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006000{
6001 FILETIME create, exit, kernel, user;
6002 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006003 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006004 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6005 /* The fields of a FILETIME structure are the hi and lo part
6006 of a 64-bit value expressed in 100 nanosecond units.
6007 1e7 is one second in such units; 1e-7 the inverse.
6008 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6009 */
Barry Warsaw53699e91996-12-10 23:23:01 +00006010 return Py_BuildValue(
6011 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006012 (double)(user.dwHighDateTime*429.4967296 +
6013 user.dwLowDateTime*1e-7),
Georg Brandl0a40ffb2008-02-13 07:20:22 +00006014 (double)(kernel.dwHighDateTime*429.4967296 +
6015 kernel.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00006016 (double)0,
6017 (double)0,
6018 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006019}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006020#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006021
6022#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006023PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006024"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006025Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006026#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006027
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006028
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006029#ifdef HAVE_GETSID
6030PyDoc_STRVAR(posix_getsid__doc__,
6031"getsid(pid) -> sid\n\n\
6032Call the system call getsid().");
6033
6034static PyObject *
6035posix_getsid(PyObject *self, PyObject *args)
6036{
Christian Heimesd491d712008-02-01 18:49:26 +00006037 pid_t pid;
6038 int sid;
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006039 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
6040 return NULL;
6041 sid = getsid(pid);
6042 if (sid < 0)
6043 return posix_error();
6044 return PyInt_FromLong((long)sid);
6045}
6046#endif /* HAVE_GETSID */
6047
6048
Guido van Rossumb6775db1994-08-01 11:34:53 +00006049#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006050PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006051"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006052Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006053
Barry Warsaw53699e91996-12-10 23:23:01 +00006054static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006055posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006056{
Guido van Rossum687dd131993-05-17 08:34:16 +00006057 if (setsid() < 0)
6058 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006059 Py_INCREF(Py_None);
6060 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006061}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006062#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006063
Guido van Rossumb6775db1994-08-01 11:34:53 +00006064#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006065PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006066"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006067Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006068
Barry Warsaw53699e91996-12-10 23:23:01 +00006069static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006070posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006071{
Christian Heimesd491d712008-02-01 18:49:26 +00006072 pid_t pid;
6073 int pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006074 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00006075 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006076 if (setpgid(pid, pgrp) < 0)
6077 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006078 Py_INCREF(Py_None);
6079 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006080}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006081#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006082
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006083
Guido van Rossumb6775db1994-08-01 11:34:53 +00006084#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006085PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006086"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006087Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006088
Barry Warsaw53699e91996-12-10 23:23:01 +00006089static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006090posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006091{
Christian Heimese6a80742008-02-03 19:51:13 +00006092 int fd;
6093 pid_t pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006094 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006095 return NULL;
6096 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006097 if (pgid < 0)
6098 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006099 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006100}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006101#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006102
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006103
Guido van Rossumb6775db1994-08-01 11:34:53 +00006104#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006105PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006106"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006107Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006108
Barry Warsaw53699e91996-12-10 23:23:01 +00006109static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006110posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006111{
6112 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006113 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006114 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006115 if (tcsetpgrp(fd, pgid) < 0)
6116 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00006117 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00006118 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006119}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006120#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006121
Guido van Rossum687dd131993-05-17 08:34:16 +00006122/* Functions acting on file descriptors */
6123
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006124PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006125"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006126Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006127
Barry Warsaw53699e91996-12-10 23:23:01 +00006128static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006129posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006130{
Mark Hammondef8b6542001-05-13 08:04:26 +00006131 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006132 int flag;
6133 int mode = 0777;
6134 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006135
6136#ifdef MS_WINDOWS
6137 if (unicode_file_names()) {
6138 PyUnicodeObject *po;
6139 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6140 Py_BEGIN_ALLOW_THREADS
6141 /* PyUnicode_AS_UNICODE OK without thread
6142 lock as it is a simple dereference. */
6143 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6144 Py_END_ALLOW_THREADS
6145 if (fd < 0)
6146 return posix_error();
6147 return PyInt_FromLong((long)fd);
6148 }
6149 /* Drop the argument parsing error as narrow strings
6150 are also valid. */
6151 PyErr_Clear();
6152 }
6153#endif
6154
Tim Peters5aa91602002-01-30 05:46:57 +00006155 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00006156 Py_FileSystemDefaultEncoding, &file,
6157 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00006158 return NULL;
6159
Barry Warsaw53699e91996-12-10 23:23:01 +00006160 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006161 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00006162 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006163 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00006164 return posix_error_with_allocated_filename(file);
6165 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00006166 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006167}
6168
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006169
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006170PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006171"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006172Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006173
Barry Warsaw53699e91996-12-10 23:23:01 +00006174static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006175posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006176{
6177 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006178 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006179 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006180 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006181 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006182 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006183 if (res < 0)
6184 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006185 Py_INCREF(Py_None);
6186 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006187}
6188
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006189
Georg Brandl309501a2008-01-19 20:22:13 +00006190PyDoc_STRVAR(posix_closerange__doc__,
6191"closerange(fd_low, fd_high)\n\n\
6192Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6193
6194static PyObject *
6195posix_closerange(PyObject *self, PyObject *args)
6196{
6197 int fd_from, fd_to, i;
6198 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6199 return NULL;
6200 Py_BEGIN_ALLOW_THREADS
6201 for (i = fd_from; i < fd_to; i++)
6202 close(i);
6203 Py_END_ALLOW_THREADS
6204 Py_RETURN_NONE;
6205}
6206
6207
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006208PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006209"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006210Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006211
Barry Warsaw53699e91996-12-10 23:23:01 +00006212static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006213posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006214{
6215 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006216 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006217 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006218 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006219 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006220 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006221 if (fd < 0)
6222 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006223 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006224}
6225
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006226
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006227PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006228"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006229Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006230
Barry Warsaw53699e91996-12-10 23:23:01 +00006231static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006232posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006233{
6234 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006235 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00006236 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006237 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006238 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00006239 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006240 if (res < 0)
6241 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006242 Py_INCREF(Py_None);
6243 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006244}
6245
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006246
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006247PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006248"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006249Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006250
Barry Warsaw53699e91996-12-10 23:23:01 +00006251static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006252posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006253{
6254 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006255#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006256 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006257#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00006258 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006259#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006260 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006261 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00006262 return NULL;
6263#ifdef SEEK_SET
6264 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6265 switch (how) {
6266 case 0: how = SEEK_SET; break;
6267 case 1: how = SEEK_CUR; break;
6268 case 2: how = SEEK_END; break;
6269 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006270#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006271
6272#if !defined(HAVE_LARGEFILE_SUPPORT)
6273 pos = PyInt_AsLong(posobj);
6274#else
6275 pos = PyLong_Check(posobj) ?
6276 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
6277#endif
6278 if (PyErr_Occurred())
6279 return NULL;
6280
Barry Warsaw53699e91996-12-10 23:23:01 +00006281 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006282#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00006283 res = _lseeki64(fd, pos, how);
6284#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006285 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006286#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006287 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006288 if (res < 0)
6289 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006290
6291#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00006292 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006293#else
6294 return PyLong_FromLongLong(res);
6295#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006296}
6297
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006298
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006299PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006300"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006301Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006302
Barry Warsaw53699e91996-12-10 23:23:01 +00006303static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006304posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006305{
Guido van Rossum8bac5461996-06-11 18:38:48 +00006306 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00006307 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006308 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00006309 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00006310 if (size < 0) {
6311 errno = EINVAL;
6312 return posix_error();
6313 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006314 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006315 if (buffer == NULL)
6316 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006317 Py_BEGIN_ALLOW_THREADS
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006318 n = read(fd, PyString_AsString(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00006319 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00006320 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006321 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00006322 return posix_error();
6323 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00006324 if (n != size)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006325 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00006326 return buffer;
6327}
6328
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006329
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006330PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006331"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006332Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006333
Barry Warsaw53699e91996-12-10 23:23:01 +00006334static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006335posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006336{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006337 int fd;
6338 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00006339 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006340
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006341 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00006342 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006343 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006344 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00006345 Py_END_ALLOW_THREADS
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