blob: 5858b4af127e6657aa416ad56f28dc11fb26e336 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Ronald Oussorend06b6f22006-04-23 11:59:25 +000016#ifdef __APPLE__
17 /*
18 * Step 1 of support for weak-linking a number of symbols existing on
19 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
20 * at the end of this file for more information.
21 */
22# pragma weak lchown
23# pragma weak statvfs
24# pragma weak fstatvfs
25
26#endif /* __APPLE__ */
27
Thomas Wouters68bc4f92006-03-01 01:05:10 +000028#define PY_SSIZE_T_CLEAN
29
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000030#include "Python.h"
31#include "structseq.h"
32
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000034# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000035#endif /* defined(__VMS) */
36
Anthony Baxterac6bd462006-04-13 02:06:09 +000037#ifdef __cplusplus
38extern "C" {
39#endif
40
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000041PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000042"This module provides access to operating system functionality that is\n\
43standardized by the C Standard and the POSIX standard (a thinly\n\
44disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000045corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000047#ifndef Py_USING_UNICODE
48/* This is used in signatures of functions. */
49#define Py_UNICODE void
50#endif
51
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000052#if defined(PYOS_OS2)
53#define INCL_DOS
54#define INCL_DOSERRORS
55#define INCL_DOSPROCESS
56#define INCL_NOPMAPI
57#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000058#if defined(PYCC_GCC)
59#include <ctype.h>
60#include <io.h>
61#include <stdio.h>
62#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000063#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000064#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000065#endif
66
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000067#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000068#include <sys/types.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000069#endif /* HAVE_SYS_TYPES_H */
70
71#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000072#include <sys/stat.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000073#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000074
Guido van Rossum36bc6801995-06-14 22:54:23 +000075#ifdef HAVE_SYS_WAIT_H
76#include <sys/wait.h> /* For WNOHANG */
77#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000078
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000079#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000080#include <signal.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000081#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000082
Guido van Rossumb6775db1994-08-01 11:34:53 +000083#ifdef HAVE_FCNTL_H
84#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000085#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000086
Guido van Rossuma6535fd2001-10-18 19:44:10 +000087#ifdef HAVE_GRP_H
88#include <grp.h>
89#endif
90
Barry Warsaw5676bd12003-01-07 20:57:09 +000091#ifdef HAVE_SYSEXITS_H
92#include <sysexits.h>
93#endif /* HAVE_SYSEXITS_H */
94
Anthony Baxter8a560de2004-10-13 15:30:56 +000095#ifdef HAVE_SYS_LOADAVG_H
96#include <sys/loadavg.h>
97#endif
98
Guido van Rossuma4916fa1996-05-23 22:58:55 +000099/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000100/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000101#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000102#include <process.h>
103#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000104#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000105#define HAVE_GETCWD 1
106#define HAVE_OPENDIR 1
107#define HAVE_SYSTEM 1
108#if defined(__OS2__)
109#define HAVE_EXECV 1
110#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000111#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000112#include <process.h>
113#else
114#ifdef __BORLANDC__ /* Borland compiler */
115#define HAVE_EXECV 1
116#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000117#define HAVE_OPENDIR 1
118#define HAVE_PIPE 1
119#define HAVE_POPEN 1
120#define HAVE_SYSTEM 1
121#define HAVE_WAIT 1
122#else
123#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000124#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000125#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000126#define HAVE_EXECV 1
127#define HAVE_PIPE 1
128#define HAVE_POPEN 1
129#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000130#define HAVE_CWAIT 1
Tim Peters11b23062003-04-23 02:39:17 +0000131#define HAVE_FSYNC 1
132#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000133#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000134#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
135/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000136#else /* all other compilers */
137/* Unix functions that the configure script doesn't check for */
138#define HAVE_EXECV 1
139#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000140#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
141#define HAVE_FORK1 1
142#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000143#define HAVE_GETCWD 1
144#define HAVE_GETEGID 1
145#define HAVE_GETEUID 1
146#define HAVE_GETGID 1
147#define HAVE_GETPPID 1
148#define HAVE_GETUID 1
149#define HAVE_KILL 1
150#define HAVE_OPENDIR 1
151#define HAVE_PIPE 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000152#ifndef __rtems__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#define HAVE_POPEN 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000154#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#define HAVE_SYSTEM 1
156#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000157#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000158#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000159#endif /* _MSC_VER */
160#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000161#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000162#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000163
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000164#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000165
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000166#if defined(__sgi)&&_COMPILER_VERSION>=700
167/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
168 (default) */
169extern char *ctermid_r(char *);
170#endif
171
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000172#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000173#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000174extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000175#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000176#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000177extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000178#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000179extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000180#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000181#endif
182#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000183extern int chdir(char *);
184extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000185#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000186extern int chdir(const char *);
187extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000188#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000189#ifdef __BORLANDC__
190extern int chmod(const char *, int);
191#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000192extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000193#endif
Christian Heimes36281872007-11-30 21:11:28 +0000194/*#ifdef HAVE_FCHMOD
195extern int fchmod(int, mode_t);
196#endif*/
197/*#ifdef HAVE_LCHMOD
198extern int lchmod(const char *, mode_t);
199#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000200extern int chown(const char *, uid_t, gid_t);
201extern char *getcwd(char *, int);
202extern char *strerror(int);
203extern int link(const char *, const char *);
204extern int rename(const char *, const char *);
205extern int stat(const char *, struct stat *);
206extern int unlink(const char *);
207extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000209extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000210#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000212extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000213#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000215
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000216#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000217
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218#ifdef HAVE_UTIME_H
219#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000220#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000222#ifdef HAVE_SYS_UTIME_H
223#include <sys/utime.h>
224#define HAVE_UTIME_H /* pretend we do for the rest of this file */
225#endif /* HAVE_SYS_UTIME_H */
226
Guido van Rossumb6775db1994-08-01 11:34:53 +0000227#ifdef HAVE_SYS_TIMES_H
228#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000229#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000230
231#ifdef HAVE_SYS_PARAM_H
232#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000233#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234
235#ifdef HAVE_SYS_UTSNAME_H
236#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000237#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000239#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000240#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000241#define NAMLEN(dirent) strlen((dirent)->d_name)
242#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000243#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000244#include <direct.h>
245#define NAMLEN(dirent) strlen((dirent)->d_name)
246#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000248#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000249#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000250#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000252#endif
253#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000255#endif
256#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000258#endif
259#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000261#ifdef _MSC_VER
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000262#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#include <direct.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000264#endif
265#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000266#include <io.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000267#endif
268#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000269#include <process.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000270#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000271#include "osdefs.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000273#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000274#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000275#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000276#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277
Guido van Rossumd48f2521997-12-05 22:19:34 +0000278#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000279#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000280#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000281
Tim Petersbc2e10e2002-03-03 23:17:02 +0000282#ifndef MAXPATHLEN
Thomas Wouters1ddba602006-04-25 15:29:46 +0000283#if defined(PATH_MAX) && PATH_MAX > 1024
284#define MAXPATHLEN PATH_MAX
285#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000286#define MAXPATHLEN 1024
Thomas Wouters1ddba602006-04-25 15:29:46 +0000287#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000288#endif /* MAXPATHLEN */
289
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000290#ifdef UNION_WAIT
291/* Emulate some macros on systems that have a union instead of macros */
292
293#ifndef WIFEXITED
294#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
295#endif
296
297#ifndef WEXITSTATUS
298#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
299#endif
300
301#ifndef WTERMSIG
302#define WTERMSIG(u_wait) ((u_wait).w_termsig)
303#endif
304
Neal Norwitzd5a37542006-03-20 06:48:34 +0000305#define WAIT_TYPE union wait
306#define WAIT_STATUS_INT(s) (s.w_status)
307
308#else /* !UNION_WAIT */
309#define WAIT_TYPE int
310#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000311#endif /* UNION_WAIT */
312
Greg Wardb48bc172000-03-01 21:51:56 +0000313/* Don't use the "_r" form if we don't need it (also, won't have a
314 prototype for it, at least on Solaris -- maybe others as well?). */
315#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
316#define USE_CTERMID_R
317#endif
318
319#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
320#define USE_TMPNAM_R
321#endif
322
Fred Drake699f3522000-06-29 21:12:41 +0000323/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000324#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000325#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000326# define STAT win32_stat
327# define FSTAT win32_fstat
328# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000329#else
330# define STAT stat
331# define FSTAT fstat
332# define STRUCT_STAT struct stat
333#endif
334
Tim Peters11b23062003-04-23 02:39:17 +0000335#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000336#include <sys/mkdev.h>
337#else
338#if defined(MAJOR_IN_SYSMACROS)
339#include <sys/sysmacros.h>
340#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000341#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
342#include <sys/mkdev.h>
343#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000344#endif
Fred Drake699f3522000-06-29 21:12:41 +0000345
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000346/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000347#ifdef WITH_NEXT_FRAMEWORK
348/* On Darwin/MacOSX a shared library or framework has no access to
349** environ directly, we must obtain it with _NSGetEnviron().
350*/
351#include <crt_externs.h>
352static char **environ;
353#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000354extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000355#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000356
Barry Warsaw53699e91996-12-10 23:23:01 +0000357static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000358convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000359{
Barry Warsaw53699e91996-12-10 23:23:01 +0000360 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000361 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000362 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000363 if (d == NULL)
364 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000365#ifdef WITH_NEXT_FRAMEWORK
366 if (environ == NULL)
367 environ = *_NSGetEnviron();
368#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000369 if (environ == NULL)
370 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000371 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000372 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000373 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000374 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000375 char *p = strchr(*e, '=');
376 if (p == NULL)
377 continue;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000378 k = PyString_FromStringAndSize(*e, (int)(p-*e));
Guido van Rossum6a619f41999-08-03 19:41:10 +0000379 if (k == NULL) {
380 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000381 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000382 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000383 v = PyString_FromString(p+1);
Guido van Rossum6a619f41999-08-03 19:41:10 +0000384 if (v == NULL) {
385 PyErr_Clear();
386 Py_DECREF(k);
387 continue;
388 }
389 if (PyDict_GetItem(d, k) == NULL) {
390 if (PyDict_SetItem(d, k, v) != 0)
391 PyErr_Clear();
392 }
393 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000394 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000395 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000396#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000397 {
398 APIRET rc;
399 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
400
401 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000402 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000403 PyObject *v = PyString_FromString(buffer);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000404 PyDict_SetItemString(d, "BEGINLIBPATH", v);
405 Py_DECREF(v);
406 }
407 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
408 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000409 PyObject *v = PyString_FromString(buffer);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000410 PyDict_SetItemString(d, "ENDLIBPATH", v);
411 Py_DECREF(v);
412 }
413 }
414#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000415 return d;
416}
417
418
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000419/* Set a POSIX-specific error from errno, and return NULL */
420
Barry Warsawd58d7641998-07-23 16:14:40 +0000421static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000422posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000423{
Barry Warsawca74da41999-02-09 19:31:45 +0000424 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000425}
Barry Warsawd58d7641998-07-23 16:14:40 +0000426static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000427posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000428{
Barry Warsawca74da41999-02-09 19:31:45 +0000429 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000430}
431
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000432#ifdef Py_WIN_WIDE_FILENAMES
433static PyObject *
434posix_error_with_unicode_filename(Py_UNICODE* name)
435{
436 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
437}
438#endif /* Py_WIN_WIDE_FILENAMES */
439
440
Mark Hammondef8b6542001-05-13 08:04:26 +0000441static PyObject *
442posix_error_with_allocated_filename(char* name)
443{
444 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
445 PyMem_Free(name);
446 return rc;
447}
448
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000449#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000450static PyObject *
451win32_error(char* function, char* filename)
452{
Mark Hammond33a6da92000-08-15 00:46:38 +0000453 /* XXX We should pass the function name along in the future.
454 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000455 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000456 Windows error object, which is non-trivial.
457 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000458 errno = GetLastError();
459 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000460 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000461 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000462 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000463}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000464
465#ifdef Py_WIN_WIDE_FILENAMES
466static PyObject *
467win32_error_unicode(char* function, Py_UNICODE* filename)
468{
469 /* XXX - see win32_error for comments on 'function' */
470 errno = GetLastError();
471 if (filename)
472 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
473 else
474 return PyErr_SetFromWindowsErr(errno);
475}
476
477static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
478{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000479}
480
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000481static int
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000482convert_to_unicode(PyObject **param)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000483{
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000484 if (PyUnicode_CheckExact(*param))
485 Py_INCREF(*param);
486 else if (PyUnicode_Check(*param))
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000487 /* For a Unicode subtype that's not a Unicode object,
488 return a true Unicode object with the same data. */
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000489 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
490 PyUnicode_GET_SIZE(*param));
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000491 else
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000492 *param = PyUnicode_FromEncodedObject(*param,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000493 Py_FileSystemDefaultEncoding,
494 "strict");
495 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000496}
497
498#endif /* Py_WIN_WIDE_FILENAMES */
499
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000500#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000501
Guido van Rossumd48f2521997-12-05 22:19:34 +0000502#if defined(PYOS_OS2)
503/**********************************************************************
504 * Helper Function to Trim and Format OS/2 Messages
505 **********************************************************************/
506 static void
507os2_formatmsg(char *msgbuf, int msglen, char *reason)
508{
509 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
510
511 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
512 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
513
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000514 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000515 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
516 }
517
518 /* Add Optional Reason Text */
519 if (reason) {
520 strcat(msgbuf, " : ");
521 strcat(msgbuf, reason);
522 }
523}
524
525/**********************************************************************
526 * Decode an OS/2 Operating System Error Code
527 *
528 * A convenience function to lookup an OS/2 error code and return a
529 * text message we can use to raise a Python exception.
530 *
531 * Notes:
532 * The messages for errors returned from the OS/2 kernel reside in
533 * the file OSO001.MSG in the \OS2 directory hierarchy.
534 *
535 **********************************************************************/
536 static char *
537os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
538{
539 APIRET rc;
540 ULONG msglen;
541
542 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
543 Py_BEGIN_ALLOW_THREADS
544 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
545 errorcode, "oso001.msg", &msglen);
546 Py_END_ALLOW_THREADS
547
548 if (rc == NO_ERROR)
549 os2_formatmsg(msgbuf, msglen, reason);
550 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000551 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000552 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000553
554 return msgbuf;
555}
556
557/* Set an OS/2-specific error and return NULL. OS/2 kernel
558 errors are not in a global variable e.g. 'errno' nor are
559 they congruent with posix error numbers. */
560
561static PyObject * os2_error(int code)
562{
563 char text[1024];
564 PyObject *v;
565
566 os2_strerror(text, sizeof(text), code, "");
567
568 v = Py_BuildValue("(is)", code, text);
569 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000570 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000571 Py_DECREF(v);
572 }
573 return NULL; /* Signal to Python that an Exception is Pending */
574}
575
576#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000577
578/* POSIX generic methods */
579
Barry Warsaw53699e91996-12-10 23:23:01 +0000580static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000581posix_fildes(PyObject *fdobj, int (*func)(int))
582{
583 int fd;
584 int res;
585 fd = PyObject_AsFileDescriptor(fdobj);
586 if (fd < 0)
587 return NULL;
588 Py_BEGIN_ALLOW_THREADS
589 res = (*func)(fd);
590 Py_END_ALLOW_THREADS
591 if (res < 0)
592 return posix_error();
593 Py_INCREF(Py_None);
594 return Py_None;
595}
Guido van Rossum21142a01999-01-08 21:05:37 +0000596
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000597#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000598static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000599unicode_file_names(void)
600{
601 static int canusewide = -1;
602 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000603 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000604 the Windows NT family. */
605 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
606 }
607 return canusewide;
608}
609#endif
Tim Peters11b23062003-04-23 02:39:17 +0000610
Guido van Rossum21142a01999-01-08 21:05:37 +0000611static PyObject *
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000612posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000613{
Mark Hammondef8b6542001-05-13 08:04:26 +0000614 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000615 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000616 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000617 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000618 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000619 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000620 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000621 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000622 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000623 return posix_error_with_allocated_filename(path1);
624 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000625 Py_INCREF(Py_None);
626 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000627}
628
Barry Warsaw53699e91996-12-10 23:23:01 +0000629static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000630posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000631 char *format,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000632 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000633{
Mark Hammondef8b6542001-05-13 08:04:26 +0000634 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000635 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000636 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000637 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000638 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000639 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000640 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000641 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000642 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000643 PyMem_Free(path1);
644 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000645 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000646 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000647 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000648 Py_INCREF(Py_None);
649 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000650}
651
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000652#ifdef Py_WIN_WIDE_FILENAMES
653static PyObject*
654win32_1str(PyObject* args, char* func,
655 char* format, BOOL (__stdcall *funcA)(LPCSTR),
656 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
657{
658 PyObject *uni;
659 char *ansi;
660 BOOL result;
661 if (unicode_file_names()) {
662 if (!PyArg_ParseTuple(args, wformat, &uni))
663 PyErr_Clear();
664 else {
665 Py_BEGIN_ALLOW_THREADS
666 result = funcW(PyUnicode_AsUnicode(uni));
667 Py_END_ALLOW_THREADS
668 if (!result)
669 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
670 Py_INCREF(Py_None);
671 return Py_None;
672 }
673 }
674 if (!PyArg_ParseTuple(args, format, &ansi))
675 return NULL;
676 Py_BEGIN_ALLOW_THREADS
677 result = funcA(ansi);
678 Py_END_ALLOW_THREADS
679 if (!result)
680 return win32_error(func, ansi);
681 Py_INCREF(Py_None);
682 return Py_None;
683
684}
685
686/* This is a reimplementation of the C library's chdir function,
687 but one that produces Win32 errors instead of DOS error codes.
688 chdir is essentially a wrapper around SetCurrentDirectory; however,
689 it also needs to set "magic" environment variables indicating
690 the per-drive current directory, which are of the form =<drive>: */
691BOOL __stdcall
692win32_chdir(LPCSTR path)
693{
694 char new_path[MAX_PATH+1];
695 int result;
696 char env[4] = "=x:";
697
698 if(!SetCurrentDirectoryA(path))
699 return FALSE;
700 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
701 if (!result)
702 return FALSE;
703 /* In the ANSI API, there should not be any paths longer
704 than MAX_PATH. */
705 assert(result <= MAX_PATH+1);
706 if (strncmp(new_path, "\\\\", 2) == 0 ||
707 strncmp(new_path, "//", 2) == 0)
708 /* UNC path, nothing to do. */
709 return TRUE;
710 env[1] = new_path[0];
711 return SetEnvironmentVariableA(env, new_path);
712}
713
714/* The Unicode version differs from the ANSI version
715 since the current directory might exceed MAX_PATH characters */
716BOOL __stdcall
717win32_wchdir(LPCWSTR path)
718{
719 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
720 int result;
721 wchar_t env[4] = L"=x:";
722
723 if(!SetCurrentDirectoryW(path))
724 return FALSE;
725 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
726 if (!result)
727 return FALSE;
728 if (result > MAX_PATH+1) {
Hirokazu Yamamoto2c66b7c2008-10-09 18:06:58 +0000729 new_path = malloc(result * sizeof(wchar_t));
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000730 if (!new_path) {
731 SetLastError(ERROR_OUTOFMEMORY);
732 return FALSE;
733 }
Hirokazu Yamamoto2c66b7c2008-10-09 18:06:58 +0000734 result = GetCurrentDirectoryW(result, new_path);
735 if (!result) {
736 free(new_path);
737 return FALSE;
738 }
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000739 }
740 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
741 wcsncmp(new_path, L"//", 2) == 0)
742 /* UNC path, nothing to do. */
743 return TRUE;
744 env[1] = new_path[0];
745 result = SetEnvironmentVariableW(env, new_path);
746 if (new_path != _new_path)
747 free(new_path);
748 return result;
749}
750#endif
751
Martin v. Löwis14694662006-02-03 12:54:16 +0000752#ifdef MS_WINDOWS
753/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
754 - time stamps are restricted to second resolution
755 - file modification times suffer from forth-and-back conversions between
756 UTC and local time
757 Therefore, we implement our own stat, based on the Win32 API directly.
758*/
759#define HAVE_STAT_NSEC 1
760
761struct win32_stat{
762 int st_dev;
763 __int64 st_ino;
764 unsigned short st_mode;
765 int st_nlink;
766 int st_uid;
767 int st_gid;
768 int st_rdev;
769 __int64 st_size;
770 int st_atime;
771 int st_atime_nsec;
772 int st_mtime;
773 int st_mtime_nsec;
774 int st_ctime;
775 int st_ctime_nsec;
776};
777
778static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
779
780static void
781FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
782{
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000783 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
784 /* Cannot simply cast and dereference in_ptr,
785 since it might not be aligned properly */
786 __int64 in;
787 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000788 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
789 /* XXX Win32 supports time stamps past 2038; we currently don't */
790 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
791}
792
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000793static void
794time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
795{
796 /* XXX endianness */
797 __int64 out;
798 out = time_in + secs_between_epochs;
Martin v. Löwisf43893a2006-10-09 20:44:25 +0000799 out = out * 10000000 + nsec_in / 100;
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000800 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000801}
802
Martin v. Löwis14694662006-02-03 12:54:16 +0000803/* Below, we *know* that ugo+r is 0444 */
804#if _S_IREAD != 0400
805#error Unsupported C library
806#endif
807static int
808attributes_to_mode(DWORD attr)
809{
810 int m = 0;
811 if (attr & FILE_ATTRIBUTE_DIRECTORY)
812 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
813 else
814 m |= _S_IFREG;
815 if (attr & FILE_ATTRIBUTE_READONLY)
816 m |= 0444;
817 else
818 m |= 0666;
819 return m;
820}
821
822static int
823attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
824{
825 memset(result, 0, sizeof(*result));
826 result->st_mode = attributes_to_mode(info->dwFileAttributes);
827 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
828 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
829 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
830 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
831
832 return 0;
833}
834
Martin v. Löwis012bc722006-10-15 09:43:39 +0000835/* Emulate GetFileAttributesEx[AW] on Windows 95 */
836static int checked = 0;
837static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
838static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
839static void
840check_gfax()
841{
842 HINSTANCE hKernel32;
843 if (checked)
844 return;
845 checked = 1;
846 hKernel32 = GetModuleHandle("KERNEL32");
847 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
848 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
849}
850
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000851static BOOL
852attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
853{
854 HANDLE hFindFile;
855 WIN32_FIND_DATAA FileData;
856 hFindFile = FindFirstFileA(pszFile, &FileData);
857 if (hFindFile == INVALID_HANDLE_VALUE)
858 return FALSE;
859 FindClose(hFindFile);
860 pfad->dwFileAttributes = FileData.dwFileAttributes;
861 pfad->ftCreationTime = FileData.ftCreationTime;
862 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
863 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
864 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
865 pfad->nFileSizeLow = FileData.nFileSizeLow;
866 return TRUE;
867}
868
869static BOOL
870attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
871{
872 HANDLE hFindFile;
873 WIN32_FIND_DATAW FileData;
874 hFindFile = FindFirstFileW(pszFile, &FileData);
875 if (hFindFile == INVALID_HANDLE_VALUE)
876 return FALSE;
877 FindClose(hFindFile);
878 pfad->dwFileAttributes = FileData.dwFileAttributes;
879 pfad->ftCreationTime = FileData.ftCreationTime;
880 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
881 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
882 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
883 pfad->nFileSizeLow = FileData.nFileSizeLow;
884 return TRUE;
885}
886
Martin v. Löwis012bc722006-10-15 09:43:39 +0000887static BOOL WINAPI
888Py_GetFileAttributesExA(LPCSTR pszFile,
889 GET_FILEEX_INFO_LEVELS level,
890 LPVOID pv)
891{
892 BOOL result;
Martin v. Löwis012bc722006-10-15 09:43:39 +0000893 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
894 /* First try to use the system's implementation, if that is
895 available and either succeeds to gives an error other than
896 that it isn't implemented. */
897 check_gfax();
898 if (gfaxa) {
899 result = gfaxa(pszFile, level, pv);
900 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
901 return result;
902 }
903 /* It's either not present, or not implemented.
904 Emulate using FindFirstFile. */
905 if (level != GetFileExInfoStandard) {
906 SetLastError(ERROR_INVALID_PARAMETER);
907 return FALSE;
908 }
909 /* Use GetFileAttributes to validate that the file name
910 does not contain wildcards (which FindFirstFile would
911 accept). */
912 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
913 return FALSE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000914 return attributes_from_dir(pszFile, pfad);
Martin v. Löwis012bc722006-10-15 09:43:39 +0000915}
916
917static BOOL WINAPI
918Py_GetFileAttributesExW(LPCWSTR pszFile,
919 GET_FILEEX_INFO_LEVELS level,
920 LPVOID pv)
921{
922 BOOL result;
Martin v. Löwis012bc722006-10-15 09:43:39 +0000923 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
924 /* First try to use the system's implementation, if that is
925 available and either succeeds to gives an error other than
926 that it isn't implemented. */
927 check_gfax();
928 if (gfaxa) {
929 result = gfaxw(pszFile, level, pv);
930 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
931 return result;
932 }
933 /* It's either not present, or not implemented.
934 Emulate using FindFirstFile. */
935 if (level != GetFileExInfoStandard) {
936 SetLastError(ERROR_INVALID_PARAMETER);
937 return FALSE;
938 }
939 /* Use GetFileAttributes to validate that the file name
940 does not contain wildcards (which FindFirstFile would
941 accept). */
942 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
943 return FALSE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000944 return attributes_from_dir_w(pszFile, pfad);
Martin v. Löwis012bc722006-10-15 09:43:39 +0000945}
946
Martin v. Löwis14694662006-02-03 12:54:16 +0000947static int
948win32_stat(const char* path, struct win32_stat *result)
949{
950 WIN32_FILE_ATTRIBUTE_DATA info;
951 int code;
952 char *dot;
953 /* XXX not supported on Win95 and NT 3.x */
Martin v. Löwis012bc722006-10-15 09:43:39 +0000954 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000955 if (GetLastError() != ERROR_SHARING_VIOLATION) {
956 /* Protocol violation: we explicitly clear errno, instead of
957 setting it to a POSIX error. Callers should use GetLastError. */
958 errno = 0;
959 return -1;
960 } else {
961 /* Could not get attributes on open file. Fall back to
962 reading the directory. */
963 if (!attributes_from_dir(path, &info)) {
964 /* Very strange. This should not fail now */
965 errno = 0;
966 return -1;
967 }
968 }
Martin v. Löwis14694662006-02-03 12:54:16 +0000969 }
970 code = attribute_data_to_stat(&info, result);
971 if (code != 0)
972 return code;
973 /* Set S_IFEXEC if it is an .exe, .bat, ... */
974 dot = strrchr(path, '.');
975 if (dot) {
976 if (stricmp(dot, ".bat") == 0 ||
977 stricmp(dot, ".cmd") == 0 ||
978 stricmp(dot, ".exe") == 0 ||
979 stricmp(dot, ".com") == 0)
980 result->st_mode |= 0111;
981 }
982 return code;
983}
984
985static int
986win32_wstat(const wchar_t* path, struct win32_stat *result)
987{
988 int code;
989 const wchar_t *dot;
990 WIN32_FILE_ATTRIBUTE_DATA info;
991 /* XXX not supported on Win95 and NT 3.x */
Martin v. Löwis012bc722006-10-15 09:43:39 +0000992 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000993 if (GetLastError() != ERROR_SHARING_VIOLATION) {
994 /* Protocol violation: we explicitly clear errno, instead of
995 setting it to a POSIX error. Callers should use GetLastError. */
996 errno = 0;
997 return -1;
998 } else {
999 /* Could not get attributes on open file. Fall back to
1000 reading the directory. */
1001 if (!attributes_from_dir_w(path, &info)) {
1002 /* Very strange. This should not fail now */
1003 errno = 0;
1004 return -1;
1005 }
1006 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001007 }
1008 code = attribute_data_to_stat(&info, result);
1009 if (code < 0)
1010 return code;
1011 /* Set IFEXEC if it is an .exe, .bat, ... */
1012 dot = wcsrchr(path, '.');
1013 if (dot) {
1014 if (_wcsicmp(dot, L".bat") == 0 ||
1015 _wcsicmp(dot, L".cmd") == 0 ||
1016 _wcsicmp(dot, L".exe") == 0 ||
1017 _wcsicmp(dot, L".com") == 0)
1018 result->st_mode |= 0111;
1019 }
1020 return code;
1021}
1022
1023static int
1024win32_fstat(int file_number, struct win32_stat *result)
1025{
1026 BY_HANDLE_FILE_INFORMATION info;
1027 HANDLE h;
1028 int type;
1029
1030 h = (HANDLE)_get_osfhandle(file_number);
1031
1032 /* Protocol violation: we explicitly clear errno, instead of
1033 setting it to a POSIX error. Callers should use GetLastError. */
1034 errno = 0;
1035
1036 if (h == INVALID_HANDLE_VALUE) {
1037 /* This is really a C library error (invalid file handle).
1038 We set the Win32 error to the closes one matching. */
1039 SetLastError(ERROR_INVALID_HANDLE);
1040 return -1;
1041 }
1042 memset(result, 0, sizeof(*result));
1043
1044 type = GetFileType(h);
1045 if (type == FILE_TYPE_UNKNOWN) {
1046 DWORD error = GetLastError();
1047 if (error != 0) {
1048 return -1;
1049 }
1050 /* else: valid but unknown file */
1051 }
1052
1053 if (type != FILE_TYPE_DISK) {
1054 if (type == FILE_TYPE_CHAR)
1055 result->st_mode = _S_IFCHR;
1056 else if (type == FILE_TYPE_PIPE)
1057 result->st_mode = _S_IFIFO;
1058 return 0;
1059 }
1060
1061 if (!GetFileInformationByHandle(h, &info)) {
1062 return -1;
1063 }
1064
1065 /* similar to stat() */
1066 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1067 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1068 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1069 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1070 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1071 /* specific to fstat() */
1072 result->st_nlink = info.nNumberOfLinks;
1073 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1074 return 0;
1075}
1076
1077#endif /* MS_WINDOWS */
1078
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001079PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001080"stat_result: Result from stat or lstat.\n\n\
1081This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001082 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001083or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1084\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001085Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1086or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001087\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001088See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001089
1090static PyStructSequence_Field stat_result_fields[] = {
1091 {"st_mode", "protection bits"},
1092 {"st_ino", "inode"},
1093 {"st_dev", "device"},
1094 {"st_nlink", "number of hard links"},
1095 {"st_uid", "user ID of owner"},
1096 {"st_gid", "group ID of owner"},
1097 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001098 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1099 {NULL, "integer time of last access"},
1100 {NULL, "integer time of last modification"},
1101 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001102 {"st_atime", "time of last access"},
1103 {"st_mtime", "time of last modification"},
1104 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001105#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001106 {"st_blksize", "blocksize for filesystem I/O"},
1107#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001108#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001109 {"st_blocks", "number of blocks allocated"},
1110#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001111#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001112 {"st_rdev", "device type (if inode device)"},
1113#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001114#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1115 {"st_flags", "user defined flags for file"},
1116#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001117#ifdef HAVE_STRUCT_STAT_ST_GEN
1118 {"st_gen", "generation number"},
1119#endif
1120#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1121 {"st_birthtime", "time of creation"},
1122#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001123 {0}
1124};
1125
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001126#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001127#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001128#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001129#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001130#endif
1131
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001132#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001133#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1134#else
1135#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1136#endif
1137
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001138#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001139#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1140#else
1141#define ST_RDEV_IDX ST_BLOCKS_IDX
1142#endif
1143
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001144#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1145#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1146#else
1147#define ST_FLAGS_IDX ST_RDEV_IDX
1148#endif
1149
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001150#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001151#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001152#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001153#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001154#endif
1155
1156#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1157#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1158#else
1159#define ST_BIRTHTIME_IDX ST_GEN_IDX
1160#endif
1161
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001162static PyStructSequence_Desc stat_result_desc = {
1163 "stat_result", /* name */
1164 stat_result__doc__, /* doc */
1165 stat_result_fields,
1166 10
1167};
1168
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001169PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001170"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1171This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001172 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001173or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001174\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001175See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001176
1177static PyStructSequence_Field statvfs_result_fields[] = {
1178 {"f_bsize", },
1179 {"f_frsize", },
1180 {"f_blocks", },
1181 {"f_bfree", },
1182 {"f_bavail", },
1183 {"f_files", },
1184 {"f_ffree", },
1185 {"f_favail", },
1186 {"f_flag", },
1187 {"f_namemax",},
1188 {0}
1189};
1190
1191static PyStructSequence_Desc statvfs_result_desc = {
1192 "statvfs_result", /* name */
1193 statvfs_result__doc__, /* doc */
1194 statvfs_result_fields,
1195 10
1196};
1197
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001198static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001199static PyTypeObject StatResultType;
1200static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001201static newfunc structseq_new;
1202
1203static PyObject *
1204statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1205{
1206 PyStructSequence *result;
1207 int i;
1208
1209 result = (PyStructSequence*)structseq_new(type, args, kwds);
1210 if (!result)
1211 return NULL;
1212 /* If we have been initialized from a tuple,
1213 st_?time might be set to None. Initialize it
1214 from the int slots. */
1215 for (i = 7; i <= 9; i++) {
1216 if (result->ob_item[i+3] == Py_None) {
1217 Py_DECREF(Py_None);
1218 Py_INCREF(result->ob_item[i]);
1219 result->ob_item[i+3] = result->ob_item[i];
1220 }
1221 }
1222 return (PyObject*)result;
1223}
1224
1225
1226
1227/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001228static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001229
1230PyDoc_STRVAR(stat_float_times__doc__,
1231"stat_float_times([newval]) -> oldval\n\n\
1232Determine whether os.[lf]stat represents time stamps as float objects.\n\
1233If newval is True, future calls to stat() return floats, if it is False,\n\
1234future calls return ints. \n\
1235If newval is omitted, return the current setting.\n");
1236
1237static PyObject*
1238stat_float_times(PyObject* self, PyObject *args)
1239{
1240 int newval = -1;
1241 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1242 return NULL;
1243 if (newval == -1)
1244 /* Return old value */
1245 return PyBool_FromLong(_stat_float_times);
1246 _stat_float_times = newval;
1247 Py_INCREF(Py_None);
1248 return Py_None;
1249}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001250
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001251static void
1252fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1253{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001254 PyObject *fval,*ival;
1255#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001256 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001257#else
1258 ival = PyInt_FromLong((long)sec);
1259#endif
Neal Norwitze0a81af2006-08-12 01:50:38 +00001260 if (!ival)
1261 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001262 if (_stat_float_times) {
1263 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1264 } else {
1265 fval = ival;
1266 Py_INCREF(fval);
1267 }
1268 PyStructSequence_SET_ITEM(v, index, ival);
1269 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001270}
1271
Tim Peters5aa91602002-01-30 05:46:57 +00001272/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001273 (used by posix_stat() and posix_fstat()) */
1274static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001275_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001276{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001277 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001278 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001279 if (v == NULL)
1280 return NULL;
1281
Martin v. Löwis14694662006-02-03 12:54:16 +00001282 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001283#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001284 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001285 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001286#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001287 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001288#endif
1289#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001290 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001291 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001292#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001293 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001294#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001295 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1296 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1297 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001298#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001299 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001300 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001301#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001302 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001303#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001304
Martin v. Löwis14694662006-02-03 12:54:16 +00001305#if defined(HAVE_STAT_TV_NSEC)
1306 ansec = st->st_atim.tv_nsec;
1307 mnsec = st->st_mtim.tv_nsec;
1308 cnsec = st->st_ctim.tv_nsec;
1309#elif defined(HAVE_STAT_TV_NSEC2)
1310 ansec = st->st_atimespec.tv_nsec;
1311 mnsec = st->st_mtimespec.tv_nsec;
1312 cnsec = st->st_ctimespec.tv_nsec;
1313#elif defined(HAVE_STAT_NSEC)
1314 ansec = st->st_atime_nsec;
1315 mnsec = st->st_mtime_nsec;
1316 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001317#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001318 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001319#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001320 fill_time(v, 7, st->st_atime, ansec);
1321 fill_time(v, 8, st->st_mtime, mnsec);
1322 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001323
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001324#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001325 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001326 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001327#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001328#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001329 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001330 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001331#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001332#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001333 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001334 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001335#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001336#ifdef HAVE_STRUCT_STAT_ST_GEN
1337 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001338 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001339#endif
1340#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1341 {
1342 PyObject *val;
1343 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001344 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001345#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001346 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001347#else
1348 bnsec = 0;
1349#endif
1350 if (_stat_float_times) {
1351 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1352 } else {
1353 val = PyInt_FromLong((long)bsec);
1354 }
1355 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1356 val);
1357 }
1358#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001359#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1360 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001361 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001362#endif
Fred Drake699f3522000-06-29 21:12:41 +00001363
1364 if (PyErr_Occurred()) {
1365 Py_DECREF(v);
1366 return NULL;
1367 }
1368
1369 return v;
1370}
1371
Martin v. Löwisd8948722004-06-02 09:57:56 +00001372#ifdef MS_WINDOWS
1373
1374/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1375 where / can be used in place of \ and the trailing slash is optional.
1376 Both SERVER and SHARE must have at least one character.
1377*/
1378
1379#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1380#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001381#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001382#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001383#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001384
Tim Peters4ad82172004-08-30 17:02:04 +00001385static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001386IsUNCRootA(char *path, int pathlen)
1387{
1388 #define ISSLASH ISSLASHA
1389
1390 int i, share;
1391
1392 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1393 /* minimum UNCRoot is \\x\y */
1394 return FALSE;
1395 for (i = 2; i < pathlen ; i++)
1396 if (ISSLASH(path[i])) break;
1397 if (i == 2 || i == pathlen)
1398 /* do not allow \\\SHARE or \\SERVER */
1399 return FALSE;
1400 share = i+1;
1401 for (i = share; i < pathlen; i++)
1402 if (ISSLASH(path[i])) break;
1403 return (i != share && (i == pathlen || i == pathlen-1));
1404
1405 #undef ISSLASH
1406}
1407
1408#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001409static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001410IsUNCRootW(Py_UNICODE *path, int pathlen)
1411{
1412 #define ISSLASH ISSLASHW
1413
1414 int i, share;
1415
1416 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1417 /* minimum UNCRoot is \\x\y */
1418 return FALSE;
1419 for (i = 2; i < pathlen ; i++)
1420 if (ISSLASH(path[i])) break;
1421 if (i == 2 || i == pathlen)
1422 /* do not allow \\\SHARE or \\SERVER */
1423 return FALSE;
1424 share = i+1;
1425 for (i = share; i < pathlen; i++)
1426 if (ISSLASH(path[i])) break;
1427 return (i != share && (i == pathlen || i == pathlen-1));
1428
1429 #undef ISSLASH
1430}
1431#endif /* Py_WIN_WIDE_FILENAMES */
1432#endif /* MS_WINDOWS */
1433
Barry Warsaw53699e91996-12-10 23:23:01 +00001434static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001435posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001436 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001437#ifdef __VMS
1438 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1439#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001440 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001441#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001442 char *wformat,
1443 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001444{
Fred Drake699f3522000-06-29 21:12:41 +00001445 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001446 char *path = NULL; /* pass this to stat; do not free() it */
1447 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001448 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001449 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001450
1451#ifdef Py_WIN_WIDE_FILENAMES
1452 /* If on wide-character-capable OS see if argument
1453 is Unicode and if so use wide API. */
1454 if (unicode_file_names()) {
1455 PyUnicodeObject *po;
1456 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001457 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1458
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001459 Py_BEGIN_ALLOW_THREADS
1460 /* PyUnicode_AS_UNICODE result OK without
1461 thread lock as it is a simple dereference. */
1462 res = wstatfunc(wpath, &st);
1463 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001464
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001465 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001466 return win32_error_unicode("stat", wpath);
1467 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001468 }
1469 /* Drop the argument parsing error as narrow strings
1470 are also valid. */
1471 PyErr_Clear();
1472 }
1473#endif
1474
Tim Peters5aa91602002-01-30 05:46:57 +00001475 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001476 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001477 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001478 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001479
Barry Warsaw53699e91996-12-10 23:23:01 +00001480 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001481 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001482 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001483
1484 if (res != 0) {
1485#ifdef MS_WINDOWS
1486 result = win32_error("stat", pathfree);
1487#else
1488 result = posix_error_with_filename(pathfree);
1489#endif
1490 }
1491 else
1492 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001493
Tim Peters500bd032001-12-19 19:05:01 +00001494 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001495 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001496}
1497
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001498/* POSIX methods */
1499
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001500PyDoc_STRVAR(posix_access__doc__,
Georg Brandl7a284472007-01-27 19:38:50 +00001501"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001502Use the real uid/gid to test for access to a path. Note that most\n\
1503operations will use the effective uid/gid, therefore this routine can\n\
1504be used in a suid/sgid environment to test if the invoking user has the\n\
1505specified access to the path. The mode argument can be F_OK to test\n\
1506existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001507
1508static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001509posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001510{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001511 char *path;
1512 int mode;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001513
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001514#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001515 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001516 if (unicode_file_names()) {
1517 PyUnicodeObject *po;
1518 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1519 Py_BEGIN_ALLOW_THREADS
1520 /* PyUnicode_AS_UNICODE OK without thread lock as
1521 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001522 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001523 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001524 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001525 }
1526 /* Drop the argument parsing error as narrow strings
1527 are also valid. */
1528 PyErr_Clear();
1529 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001530 if (!PyArg_ParseTuple(args, "eti:access",
1531 Py_FileSystemDefaultEncoding, &path, &mode))
1532 return 0;
1533 Py_BEGIN_ALLOW_THREADS
1534 attr = GetFileAttributesA(path);
1535 Py_END_ALLOW_THREADS
1536 PyMem_Free(path);
1537finish:
1538 if (attr == 0xFFFFFFFF)
1539 /* File does not exist, or cannot read attributes */
1540 return PyBool_FromLong(0);
1541 /* Access is possible if either write access wasn't requested, or
Martin v. Löwis7b3cc062007-12-03 23:09:04 +00001542 the file isn't read-only, or if it's a directory, as there are
1543 no read-only directories on Windows. */
1544 return PyBool_FromLong(!(mode & 2)
1545 || !(attr & FILE_ATTRIBUTE_READONLY)
1546 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001547#else
1548 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001549 if (!PyArg_ParseTuple(args, "eti:access",
1550 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001551 return NULL;
1552 Py_BEGIN_ALLOW_THREADS
1553 res = access(path, mode);
1554 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001555 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001556 return PyBool_FromLong(res == 0);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001557#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001558}
1559
Guido van Rossumd371ff11999-01-25 16:12:23 +00001560#ifndef F_OK
1561#define F_OK 0
1562#endif
1563#ifndef R_OK
1564#define R_OK 4
1565#endif
1566#ifndef W_OK
1567#define W_OK 2
1568#endif
1569#ifndef X_OK
1570#define X_OK 1
1571#endif
1572
1573#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001574PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001575"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001576Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001577
1578static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001579posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001580{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001581 int id;
1582 char *ret;
1583
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001584 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001585 return NULL;
1586
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001587#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001588 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001589 if (id == 0) {
1590 ret = ttyname();
1591 }
1592 else {
1593 ret = NULL;
1594 }
1595#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001596 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001597#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001598 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001599 return posix_error();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001600 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001601}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001602#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001603
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001604#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001605PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001606"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001607Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001608
1609static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001610posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001611{
1612 char *ret;
1613 char buffer[L_ctermid];
1614
Greg Wardb48bc172000-03-01 21:51:56 +00001615#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001616 ret = ctermid_r(buffer);
1617#else
1618 ret = ctermid(buffer);
1619#endif
1620 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001621 return posix_error();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001622 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001623}
1624#endif
1625
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001626PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001627"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001628Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001629
Barry Warsaw53699e91996-12-10 23:23:01 +00001630static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001631posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001632{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001633#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001634 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001635#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001636 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001637#elif defined(__VMS)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001638 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001639#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001640 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001641#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001642}
1643
Fred Drake4d1e64b2002-04-15 19:40:07 +00001644#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001645PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001646"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001647Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001648opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001649
1650static PyObject *
1651posix_fchdir(PyObject *self, PyObject *fdobj)
1652{
1653 return posix_fildes(fdobj, fchdir);
1654}
1655#endif /* HAVE_FCHDIR */
1656
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001657
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001658PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001659"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001660Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001661
Barry Warsaw53699e91996-12-10 23:23:01 +00001662static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001663posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001664{
Mark Hammondef8b6542001-05-13 08:04:26 +00001665 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001666 int i;
1667 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001668#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001669 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001670 if (unicode_file_names()) {
1671 PyUnicodeObject *po;
1672 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1673 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001674 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1675 if (attr != 0xFFFFFFFF) {
1676 if (i & _S_IWRITE)
1677 attr &= ~FILE_ATTRIBUTE_READONLY;
1678 else
1679 attr |= FILE_ATTRIBUTE_READONLY;
1680 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1681 }
1682 else
1683 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001684 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001685 if (!res)
1686 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001687 PyUnicode_AS_UNICODE(po));
1688 Py_INCREF(Py_None);
1689 return Py_None;
1690 }
1691 /* Drop the argument parsing error as narrow strings
1692 are also valid. */
1693 PyErr_Clear();
1694 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001695 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1696 &path, &i))
1697 return NULL;
1698 Py_BEGIN_ALLOW_THREADS
1699 attr = GetFileAttributesA(path);
1700 if (attr != 0xFFFFFFFF) {
1701 if (i & _S_IWRITE)
1702 attr &= ~FILE_ATTRIBUTE_READONLY;
1703 else
1704 attr |= FILE_ATTRIBUTE_READONLY;
1705 res = SetFileAttributesA(path, attr);
1706 }
1707 else
1708 res = 0;
1709 Py_END_ALLOW_THREADS
1710 if (!res) {
1711 win32_error("chmod", path);
1712 PyMem_Free(path);
1713 return NULL;
1714 }
Martin v. Löwis9f485bc2006-05-08 05:25:56 +00001715 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001716 Py_INCREF(Py_None);
1717 return Py_None;
1718#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001719 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001720 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001721 return NULL;
1722 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001723 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001724 Py_END_ALLOW_THREADS
1725 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001726 return posix_error_with_allocated_filename(path);
1727 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001728 Py_INCREF(Py_None);
1729 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001730#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001731}
1732
Christian Heimes36281872007-11-30 21:11:28 +00001733#ifdef HAVE_FCHMOD
1734PyDoc_STRVAR(posix_fchmod__doc__,
1735"fchmod(fd, mode)\n\n\
1736Change the access permissions of the file given by file\n\
1737descriptor fd.");
1738
1739static PyObject *
1740posix_fchmod(PyObject *self, PyObject *args)
1741{
1742 int fd, mode, res;
1743 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1744 return NULL;
1745 Py_BEGIN_ALLOW_THREADS
1746 res = fchmod(fd, mode);
1747 Py_END_ALLOW_THREADS
1748 if (res < 0)
1749 return posix_error();
1750 Py_RETURN_NONE;
1751}
1752#endif /* HAVE_FCHMOD */
1753
1754#ifdef HAVE_LCHMOD
1755PyDoc_STRVAR(posix_lchmod__doc__,
1756"lchmod(path, mode)\n\n\
1757Change the access permissions of a file. If path is a symlink, this\n\
1758affects the link itself rather than the target.");
1759
1760static PyObject *
1761posix_lchmod(PyObject *self, PyObject *args)
1762{
1763 char *path = NULL;
1764 int i;
1765 int res;
1766 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1767 &path, &i))
1768 return NULL;
1769 Py_BEGIN_ALLOW_THREADS
1770 res = lchmod(path, i);
1771 Py_END_ALLOW_THREADS
1772 if (res < 0)
1773 return posix_error_with_allocated_filename(path);
1774 PyMem_Free(path);
1775 Py_RETURN_NONE;
1776}
1777#endif /* HAVE_LCHMOD */
1778
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001779
Martin v. Löwis382abef2007-02-19 10:55:19 +00001780#ifdef HAVE_CHFLAGS
1781PyDoc_STRVAR(posix_chflags__doc__,
1782"chflags(path, flags)\n\n\
1783Set file flags.");
1784
1785static PyObject *
1786posix_chflags(PyObject *self, PyObject *args)
1787{
1788 char *path;
1789 unsigned long flags;
1790 int res;
1791 if (!PyArg_ParseTuple(args, "etk:chflags",
1792 Py_FileSystemDefaultEncoding, &path, &flags))
1793 return NULL;
1794 Py_BEGIN_ALLOW_THREADS
1795 res = chflags(path, flags);
1796 Py_END_ALLOW_THREADS
1797 if (res < 0)
1798 return posix_error_with_allocated_filename(path);
1799 PyMem_Free(path);
1800 Py_INCREF(Py_None);
1801 return Py_None;
1802}
1803#endif /* HAVE_CHFLAGS */
1804
1805#ifdef HAVE_LCHFLAGS
1806PyDoc_STRVAR(posix_lchflags__doc__,
1807"lchflags(path, flags)\n\n\
1808Set file flags.\n\
1809This function will not follow symbolic links.");
1810
1811static PyObject *
1812posix_lchflags(PyObject *self, PyObject *args)
1813{
1814 char *path;
1815 unsigned long flags;
1816 int res;
1817 if (!PyArg_ParseTuple(args, "etk:lchflags",
1818 Py_FileSystemDefaultEncoding, &path, &flags))
1819 return NULL;
1820 Py_BEGIN_ALLOW_THREADS
1821 res = lchflags(path, flags);
1822 Py_END_ALLOW_THREADS
1823 if (res < 0)
1824 return posix_error_with_allocated_filename(path);
1825 PyMem_Free(path);
1826 Py_INCREF(Py_None);
1827 return Py_None;
1828}
1829#endif /* HAVE_LCHFLAGS */
1830
Martin v. Löwis244edc82001-10-04 22:44:26 +00001831#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001832PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001833"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001834Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001835
1836static PyObject *
1837posix_chroot(PyObject *self, PyObject *args)
1838{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001839 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001840}
1841#endif
1842
Guido van Rossum21142a01999-01-08 21:05:37 +00001843#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001844PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001845"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001846force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001847
1848static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001849posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001850{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001851 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001852}
1853#endif /* HAVE_FSYNC */
1854
1855#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001856
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001857#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001858extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1859#endif
1860
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001861PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001862"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001863force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001864 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001865
1866static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001867posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001868{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001869 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001870}
1871#endif /* HAVE_FDATASYNC */
1872
1873
Fredrik Lundh10723342000-07-10 16:38:09 +00001874#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001875PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001876"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001877Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001878
Barry Warsaw53699e91996-12-10 23:23:01 +00001879static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001880posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001881{
Mark Hammondef8b6542001-05-13 08:04:26 +00001882 char *path = NULL;
Gregory P. Smithf48da8f2008-03-18 19:05:32 +00001883 long uid, gid;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001884 int res;
Gregory P. Smithf48da8f2008-03-18 19:05:32 +00001885 if (!PyArg_ParseTuple(args, "etll:chown",
Tim Peters5aa91602002-01-30 05:46:57 +00001886 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001887 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001888 return NULL;
1889 Py_BEGIN_ALLOW_THREADS
1890 res = chown(path, (uid_t) uid, (gid_t) gid);
1891 Py_END_ALLOW_THREADS
1892 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001893 return posix_error_with_allocated_filename(path);
1894 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001895 Py_INCREF(Py_None);
1896 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001897}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001898#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001899
Christian Heimes36281872007-11-30 21:11:28 +00001900#ifdef HAVE_FCHOWN
1901PyDoc_STRVAR(posix_fchown__doc__,
1902"fchown(fd, uid, gid)\n\n\
1903Change the owner and group id of the file given by file descriptor\n\
1904fd to the numeric uid and gid.");
1905
1906static PyObject *
1907posix_fchown(PyObject *self, PyObject *args)
1908{
1909 int fd, uid, gid;
1910 int res;
1911 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
1912 return NULL;
1913 Py_BEGIN_ALLOW_THREADS
1914 res = fchown(fd, (uid_t) uid, (gid_t) gid);
1915 Py_END_ALLOW_THREADS
1916 if (res < 0)
1917 return posix_error();
1918 Py_RETURN_NONE;
1919}
1920#endif /* HAVE_FCHOWN */
1921
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001922#ifdef HAVE_LCHOWN
1923PyDoc_STRVAR(posix_lchown__doc__,
1924"lchown(path, uid, gid)\n\n\
1925Change the owner and group id of path to the numeric uid and gid.\n\
1926This function will not follow symbolic links.");
1927
1928static PyObject *
1929posix_lchown(PyObject *self, PyObject *args)
1930{
1931 char *path = NULL;
1932 int uid, gid;
1933 int res;
1934 if (!PyArg_ParseTuple(args, "etii:lchown",
1935 Py_FileSystemDefaultEncoding, &path,
1936 &uid, &gid))
1937 return NULL;
1938 Py_BEGIN_ALLOW_THREADS
1939 res = lchown(path, (uid_t) uid, (gid_t) gid);
1940 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001941 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001942 return posix_error_with_allocated_filename(path);
1943 PyMem_Free(path);
1944 Py_INCREF(Py_None);
1945 return Py_None;
1946}
1947#endif /* HAVE_LCHOWN */
1948
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001949
Guido van Rossum36bc6801995-06-14 22:54:23 +00001950#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001951PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001952"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001953Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001954
Barry Warsaw53699e91996-12-10 23:23:01 +00001955static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001956posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001957{
Facundo Batista5596b0c2008-06-22 13:36:20 +00001958 int bufsize_incr = 1024;
1959 int bufsize = 0;
1960 char *tmpbuf = NULL;
1961 char *res = NULL;
1962 PyObject *dynamic_return;
Neal Norwitze241ce82003-02-17 18:17:05 +00001963
Barry Warsaw53699e91996-12-10 23:23:01 +00001964 Py_BEGIN_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00001965 do {
1966 bufsize = bufsize + bufsize_incr;
1967 tmpbuf = malloc(bufsize);
1968 if (tmpbuf == NULL) {
1969 break;
1970 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001971#if defined(PYOS_OS2) && defined(PYCC_GCC)
Facundo Batista5596b0c2008-06-22 13:36:20 +00001972 res = _getcwd2(tmpbuf, bufsize);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001973#else
Facundo Batista5596b0c2008-06-22 13:36:20 +00001974 res = getcwd(tmpbuf, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001975#endif
Facundo Batista5596b0c2008-06-22 13:36:20 +00001976
1977 if (res == NULL) {
1978 free(tmpbuf);
1979 }
1980 } while ((res == NULL) && (errno == ERANGE));
Barry Warsaw53699e91996-12-10 23:23:01 +00001981 Py_END_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00001982
Guido van Rossumff4949e1992-08-05 19:58:53 +00001983 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001984 return posix_error();
Facundo Batista5596b0c2008-06-22 13:36:20 +00001985
1986 dynamic_return = PyString_FromString(tmpbuf);
1987 free(tmpbuf);
1988
1989 return dynamic_return;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001990}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001991
Walter Dörwald3b918c32002-11-21 20:18:46 +00001992#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001993PyDoc_STRVAR(posix_getcwdu__doc__,
1994"getcwdu() -> path\n\n\
1995Return a unicode string representing the current working directory.");
1996
1997static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001998posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001999{
2000 char buf[1026];
2001 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002002
2003#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002004 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002005 if (unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002006 wchar_t wbuf[1026];
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002007 wchar_t *wbuf2 = wbuf;
2008 PyObject *resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002009 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002010 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2011 /* If the buffer is large enough, len does not include the
2012 terminating \0. If the buffer is too small, len includes
2013 the space needed for the terminator. */
2014 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2015 wbuf2 = malloc(len * sizeof(wchar_t));
2016 if (wbuf2)
2017 len = GetCurrentDirectoryW(len, wbuf2);
2018 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002019 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002020 if (!wbuf2) {
2021 PyErr_NoMemory();
2022 return NULL;
2023 }
2024 if (!len) {
2025 if (wbuf2 != wbuf) free(wbuf2);
2026 return win32_error("getcwdu", NULL);
2027 }
2028 resobj = PyUnicode_FromWideChar(wbuf2, len);
2029 if (wbuf2 != wbuf) free(wbuf2);
2030 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002031 }
2032#endif
2033
2034 Py_BEGIN_ALLOW_THREADS
2035#if defined(PYOS_OS2) && defined(PYCC_GCC)
2036 res = _getcwd2(buf, sizeof buf);
2037#else
2038 res = getcwd(buf, sizeof buf);
2039#endif
2040 Py_END_ALLOW_THREADS
2041 if (res == NULL)
2042 return posix_error();
2043 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
2044}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002045#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00002046#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002047
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002048
Guido van Rossumb6775db1994-08-01 11:34:53 +00002049#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002050PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002051"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002052Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002053
Barry Warsaw53699e91996-12-10 23:23:01 +00002054static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002055posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002056{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002057 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002058}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002059#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002060
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002061
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002062PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002063"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002064Return a list containing the names of the entries in the directory.\n\
2065\n\
2066 path: path of directory to list\n\
2067\n\
2068The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002069entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002070
Barry Warsaw53699e91996-12-10 23:23:01 +00002071static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002072posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002073{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002074 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002075 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002076#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002077
Barry Warsaw53699e91996-12-10 23:23:01 +00002078 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002079 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002080 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002081 WIN32_FIND_DATA FileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002082 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00002083 char *bufptr = namebuf;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002084 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002085
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002086#ifdef Py_WIN_WIDE_FILENAMES
2087 /* If on wide-character-capable OS see if argument
2088 is Unicode and if so use wide API. */
2089 if (unicode_file_names()) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002090 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002091 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2092 WIN32_FIND_DATAW wFileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002093 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002094 Py_UNICODE wch;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002095 /* Overallocate for \\*.*\0 */
2096 len = PyUnicode_GET_SIZE(po);
2097 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2098 if (!wnamebuf) {
2099 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002100 return NULL;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002101 }
2102 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2103 wch = len > 0 ? wnamebuf[len-1] : '\0';
2104 if (wch != L'/' && wch != L'\\' && wch != L':')
2105 wnamebuf[len++] = L'\\';
2106 wcscpy(wnamebuf + len, L"*.*");
2107 if ((d = PyList_New(0)) == NULL) {
2108 free(wnamebuf);
2109 return NULL;
2110 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002111 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2112 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002113 int error = GetLastError();
2114 if (error == ERROR_FILE_NOT_FOUND) {
2115 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002116 return d;
2117 }
2118 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002119 win32_error_unicode("FindFirstFileW", wnamebuf);
2120 free(wnamebuf);
2121 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002122 }
2123 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002124 /* Skip over . and .. */
2125 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2126 wcscmp(wFileData.cFileName, L"..") != 0) {
2127 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2128 if (v == NULL) {
2129 Py_DECREF(d);
2130 d = NULL;
2131 break;
2132 }
2133 if (PyList_Append(d, v) != 0) {
2134 Py_DECREF(v);
2135 Py_DECREF(d);
2136 d = NULL;
2137 break;
2138 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002139 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002140 }
Georg Brandl622927b2006-03-07 12:48:03 +00002141 Py_BEGIN_ALLOW_THREADS
2142 result = FindNextFileW(hFindFile, &wFileData);
2143 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00002144 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2145 it got to the end of the directory. */
2146 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2147 Py_DECREF(d);
2148 win32_error_unicode("FindNextFileW", wnamebuf);
2149 FindClose(hFindFile);
2150 free(wnamebuf);
2151 return NULL;
2152 }
Georg Brandl622927b2006-03-07 12:48:03 +00002153 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002154
2155 if (FindClose(hFindFile) == FALSE) {
2156 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002157 win32_error_unicode("FindClose", wnamebuf);
2158 free(wnamebuf);
2159 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002160 }
Martin v. Löwise3edaea2006-05-15 05:51:36 +00002161 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002162 return d;
2163 }
2164 /* Drop the argument parsing error as narrow strings
2165 are also valid. */
2166 PyErr_Clear();
2167 }
2168#endif
2169
Tim Peters5aa91602002-01-30 05:46:57 +00002170 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002171 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002172 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002173 if (len > 0) {
2174 char ch = namebuf[len-1];
2175 if (ch != SEP && ch != ALTSEP && ch != ':')
2176 namebuf[len++] = '/';
2177 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002178 strcpy(namebuf + len, "*.*");
2179
Barry Warsaw53699e91996-12-10 23:23:01 +00002180 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002181 return NULL;
2182
2183 hFindFile = FindFirstFile(namebuf, &FileData);
2184 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002185 int error = GetLastError();
2186 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002187 return d;
2188 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002189 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002190 }
2191 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002192 /* Skip over . and .. */
2193 if (strcmp(FileData.cFileName, ".") != 0 &&
2194 strcmp(FileData.cFileName, "..") != 0) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002195 v = PyString_FromString(FileData.cFileName);
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002196 if (v == NULL) {
2197 Py_DECREF(d);
2198 d = NULL;
2199 break;
2200 }
2201 if (PyList_Append(d, v) != 0) {
2202 Py_DECREF(v);
2203 Py_DECREF(d);
2204 d = NULL;
2205 break;
2206 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002207 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002208 }
Georg Brandl622927b2006-03-07 12:48:03 +00002209 Py_BEGIN_ALLOW_THREADS
2210 result = FindNextFile(hFindFile, &FileData);
2211 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00002212 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2213 it got to the end of the directory. */
2214 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2215 Py_DECREF(d);
2216 win32_error("FindNextFile", namebuf);
2217 FindClose(hFindFile);
2218 return NULL;
2219 }
Georg Brandl622927b2006-03-07 12:48:03 +00002220 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002221
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002222 if (FindClose(hFindFile) == FALSE) {
2223 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002224 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002225 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002226
2227 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002228
Tim Peters0bb44a42000-09-15 07:44:49 +00002229#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002230
2231#ifndef MAX_PATH
2232#define MAX_PATH CCHMAXPATH
2233#endif
2234 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002235 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002236 PyObject *d, *v;
2237 char namebuf[MAX_PATH+5];
2238 HDIR hdir = 1;
2239 ULONG srchcnt = 1;
2240 FILEFINDBUF3 ep;
2241 APIRET rc;
2242
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002243 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002244 return NULL;
2245 if (len >= MAX_PATH) {
2246 PyErr_SetString(PyExc_ValueError, "path too long");
2247 return NULL;
2248 }
2249 strcpy(namebuf, name);
2250 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002251 if (*pt == ALTSEP)
2252 *pt = SEP;
2253 if (namebuf[len-1] != SEP)
2254 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002255 strcpy(namebuf + len, "*.*");
2256
2257 if ((d = PyList_New(0)) == NULL)
2258 return NULL;
2259
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002260 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2261 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002262 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002263 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2264 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2265 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002266
2267 if (rc != NO_ERROR) {
2268 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002269 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002270 }
2271
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002272 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002273 do {
2274 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002275 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002276 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002277
2278 strcpy(namebuf, ep.achName);
2279
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002280 /* Leave Case of Name Alone -- In Native Form */
2281 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002282
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002283 v = PyString_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002284 if (v == NULL) {
2285 Py_DECREF(d);
2286 d = NULL;
2287 break;
2288 }
2289 if (PyList_Append(d, v) != 0) {
2290 Py_DECREF(v);
2291 Py_DECREF(d);
2292 d = NULL;
2293 break;
2294 }
2295 Py_DECREF(v);
2296 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2297 }
2298
2299 return d;
2300#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002301
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002302 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002303 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002304 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002305 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002306 int arg_is_unicode = 1;
2307
Georg Brandl05e89b82006-04-11 07:04:06 +00002308 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002309 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2310 arg_is_unicode = 0;
2311 PyErr_Clear();
2312 }
2313 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002314 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002315 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002316 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002317 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002318 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002319 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002320 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002321 return NULL;
2322 }
Georg Brandl622927b2006-03-07 12:48:03 +00002323 for (;;) {
Georg Brandl86cbf812008-07-16 21:31:41 +00002324 errno = 0;
Georg Brandl622927b2006-03-07 12:48:03 +00002325 Py_BEGIN_ALLOW_THREADS
2326 ep = readdir(dirp);
2327 Py_END_ALLOW_THREADS
Georg Brandl86cbf812008-07-16 21:31:41 +00002328 if (ep == NULL) {
2329 if (errno == 0) {
2330 break;
2331 } else {
2332 closedir(dirp);
2333 Py_DECREF(d);
2334 return posix_error_with_allocated_filename(name);
2335 }
2336 }
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002337 if (ep->d_name[0] == '.' &&
2338 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002339 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002340 continue;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002341 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002342 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002343 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002344 d = NULL;
2345 break;
2346 }
Just van Rossum46c97842003-02-25 21:42:15 +00002347#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00002348 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002349 PyObject *w;
2350
2351 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002352 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002353 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002354 if (w != NULL) {
2355 Py_DECREF(v);
2356 v = w;
2357 }
2358 else {
2359 /* fall back to the original byte string, as
2360 discussed in patch #683592 */
2361 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002362 }
Just van Rossum46c97842003-02-25 21:42:15 +00002363 }
2364#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002365 if (PyList_Append(d, v) != 0) {
2366 Py_DECREF(v);
2367 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002368 d = NULL;
2369 break;
2370 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002371 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002372 }
2373 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002374 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002375
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002376 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002377
Tim Peters0bb44a42000-09-15 07:44:49 +00002378#endif /* which OS */
2379} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002380
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002381#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002382/* A helper function for abspath on win32 */
2383static PyObject *
2384posix__getfullpathname(PyObject *self, PyObject *args)
2385{
2386 /* assume encoded strings wont more than double no of chars */
2387 char inbuf[MAX_PATH*2];
2388 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002389 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002390 char outbuf[MAX_PATH*2];
2391 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002392#ifdef Py_WIN_WIDE_FILENAMES
2393 if (unicode_file_names()) {
2394 PyUnicodeObject *po;
2395 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
Georg Brandlbb608a82008-12-05 08:35:09 +00002396 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2397 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002398 Py_UNICODE *wtemp;
Georg Brandlbb608a82008-12-05 08:35:09 +00002399 DWORD result;
2400 PyObject *v;
2401 result = GetFullPathNameW(wpath,
2402 sizeof(woutbuf)/sizeof(woutbuf[0]),
2403 woutbuf, &wtemp);
2404 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2405 woutbufp = malloc(result * sizeof(Py_UNICODE));
2406 if (!woutbufp)
2407 return PyErr_NoMemory();
2408 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2409 }
2410 if (result)
2411 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2412 else
2413 v = win32_error_unicode("GetFullPathNameW", wpath);
2414 if (woutbufp != woutbuf)
2415 free(woutbufp);
2416 return v;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002417 }
2418 /* Drop the argument parsing error as narrow strings
2419 are also valid. */
2420 PyErr_Clear();
2421 }
2422#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002423 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2424 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002425 &insize))
2426 return NULL;
2427 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2428 outbuf, &temp))
2429 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002430 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2431 return PyUnicode_Decode(outbuf, strlen(outbuf),
2432 Py_FileSystemDefaultEncoding, NULL);
2433 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002434 return PyString_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002435} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002436#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002437
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002438PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002439"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002440Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002441
Barry Warsaw53699e91996-12-10 23:23:01 +00002442static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002443posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002444{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002445 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002446 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002447 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002448
2449#ifdef Py_WIN_WIDE_FILENAMES
2450 if (unicode_file_names()) {
2451 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002452 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002453 Py_BEGIN_ALLOW_THREADS
2454 /* PyUnicode_AS_UNICODE OK without thread lock as
2455 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002456 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002457 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002458 if (!res)
2459 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002460 Py_INCREF(Py_None);
2461 return Py_None;
2462 }
2463 /* Drop the argument parsing error as narrow strings
2464 are also valid. */
2465 PyErr_Clear();
2466 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002467 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2468 Py_FileSystemDefaultEncoding, &path, &mode))
2469 return NULL;
2470 Py_BEGIN_ALLOW_THREADS
2471 /* PyUnicode_AS_UNICODE OK without thread lock as
2472 it is a simple dereference. */
2473 res = CreateDirectoryA(path, NULL);
2474 Py_END_ALLOW_THREADS
2475 if (!res) {
2476 win32_error("mkdir", path);
2477 PyMem_Free(path);
2478 return NULL;
2479 }
2480 PyMem_Free(path);
2481 Py_INCREF(Py_None);
2482 return Py_None;
2483#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002484
Tim Peters5aa91602002-01-30 05:46:57 +00002485 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002486 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002487 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002488 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002489#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002490 res = mkdir(path);
2491#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002492 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002493#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002494 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002495 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002496 return posix_error_with_allocated_filename(path);
2497 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002498 Py_INCREF(Py_None);
2499 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002500#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002501}
2502
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002503
Neal Norwitz1818ed72006-03-26 00:29:48 +00002504/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2505#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002506#include <sys/resource.h>
2507#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002508
Neal Norwitz1818ed72006-03-26 00:29:48 +00002509
2510#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002511PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002512"nice(inc) -> new_priority\n\n\
2513Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002514
Barry Warsaw53699e91996-12-10 23:23:01 +00002515static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002516posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002517{
2518 int increment, value;
2519
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002520 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002521 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002522
2523 /* There are two flavours of 'nice': one that returns the new
2524 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002525 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2526 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002527
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002528 If we are of the nice family that returns the new priority, we
2529 need to clear errno before the call, and check if errno is filled
2530 before calling posix_error() on a returnvalue of -1, because the
2531 -1 may be the actual new priority! */
2532
2533 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002534 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002535#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002536 if (value == 0)
2537 value = getpriority(PRIO_PROCESS, 0);
2538#endif
2539 if (value == -1 && errno != 0)
2540 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002541 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002542 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002543}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002544#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002545
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002546PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002547"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002548Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002549
Barry Warsaw53699e91996-12-10 23:23:01 +00002550static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002551posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002552{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002553#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002554 PyObject *o1, *o2;
2555 char *p1, *p2;
2556 BOOL result;
2557 if (unicode_file_names()) {
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002558 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2559 goto error;
2560 if (!convert_to_unicode(&o1))
2561 goto error;
2562 if (!convert_to_unicode(&o2)) {
2563 Py_DECREF(o1);
2564 goto error;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002565 }
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002566 Py_BEGIN_ALLOW_THREADS
2567 result = MoveFileW(PyUnicode_AsUnicode(o1),
2568 PyUnicode_AsUnicode(o2));
2569 Py_END_ALLOW_THREADS
2570 Py_DECREF(o1);
2571 Py_DECREF(o2);
2572 if (!result)
2573 return win32_error("rename", NULL);
2574 Py_INCREF(Py_None);
2575 return Py_None;
2576error:
2577 PyErr_Clear();
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002578 }
2579 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2580 return NULL;
2581 Py_BEGIN_ALLOW_THREADS
2582 result = MoveFileA(p1, p2);
2583 Py_END_ALLOW_THREADS
2584 if (!result)
2585 return win32_error("rename", NULL);
2586 Py_INCREF(Py_None);
2587 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002588#else
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002589 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002590#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002591}
2592
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002593
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002594PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002595"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002596Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002597
Barry Warsaw53699e91996-12-10 23:23:01 +00002598static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002599posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002600{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002601#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002602 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002603#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002604 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002605#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002606}
2607
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002608
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002609PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002610"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002611Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002612
Barry Warsaw53699e91996-12-10 23:23:01 +00002613static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002614posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002615{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002616#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002617 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002618#else
2619 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2620#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002621}
2622
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002623
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002624#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002625PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002626"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002627Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002628
Barry Warsaw53699e91996-12-10 23:23:01 +00002629static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002630posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002631{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002632 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002633 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002634 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002635 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002636 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002637 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002638 Py_END_ALLOW_THREADS
2639 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002640}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002641#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002642
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002643
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002644PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002645"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002646Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002647
Barry Warsaw53699e91996-12-10 23:23:01 +00002648static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002649posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002650{
2651 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002652 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002653 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002654 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002655 if (i < 0)
2656 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002657 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002658}
2659
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002660
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002661PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002662"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002663Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002664
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002665PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002666"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002667Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002668
Barry Warsaw53699e91996-12-10 23:23:01 +00002669static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002670posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002671{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002672#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002673 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002674#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002675 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002676#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002677}
2678
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002679
Guido van Rossumb6775db1994-08-01 11:34:53 +00002680#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002681PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002682"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002683Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002684
Barry Warsaw53699e91996-12-10 23:23:01 +00002685static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002686posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002687{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002688 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002689 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002690
Barry Warsaw53699e91996-12-10 23:23:01 +00002691 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002692 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002693 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002694 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002695 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002696 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002697 u.sysname,
2698 u.nodename,
2699 u.release,
2700 u.version,
2701 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002702}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002703#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002704
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002705static int
2706extract_time(PyObject *t, long* sec, long* usec)
2707{
2708 long intval;
2709 if (PyFloat_Check(t)) {
2710 double tval = PyFloat_AsDouble(t);
Christian Heimese93237d2007-12-19 02:37:44 +00002711 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002712 if (!intobj)
2713 return -1;
2714 intval = PyInt_AsLong(intobj);
2715 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002716 if (intval == -1 && PyErr_Occurred())
2717 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002718 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002719 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002720 if (*usec < 0)
2721 /* If rounding gave us a negative number,
2722 truncate. */
2723 *usec = 0;
2724 return 0;
2725 }
2726 intval = PyInt_AsLong(t);
2727 if (intval == -1 && PyErr_Occurred())
2728 return -1;
2729 *sec = intval;
2730 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002731 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002732}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002733
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002734PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002735"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002736utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002737Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002738second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002739
Barry Warsaw53699e91996-12-10 23:23:01 +00002740static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002741posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002742{
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002743#ifdef Py_WIN_WIDE_FILENAMES
2744 PyObject *arg;
2745 PyUnicodeObject *obwpath;
2746 wchar_t *wpath = NULL;
2747 char *apath = NULL;
2748 HANDLE hFile;
2749 long atimesec, mtimesec, ausec, musec;
2750 FILETIME atime, mtime;
2751 PyObject *result = NULL;
2752
2753 if (unicode_file_names()) {
2754 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2755 wpath = PyUnicode_AS_UNICODE(obwpath);
2756 Py_BEGIN_ALLOW_THREADS
2757 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002758 NULL, OPEN_EXISTING,
2759 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002760 Py_END_ALLOW_THREADS
2761 if (hFile == INVALID_HANDLE_VALUE)
2762 return win32_error_unicode("utime", wpath);
2763 } else
2764 /* Drop the argument parsing error as narrow strings
2765 are also valid. */
2766 PyErr_Clear();
2767 }
2768 if (!wpath) {
2769 if (!PyArg_ParseTuple(args, "etO:utime",
2770 Py_FileSystemDefaultEncoding, &apath, &arg))
2771 return NULL;
2772 Py_BEGIN_ALLOW_THREADS
2773 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002774 NULL, OPEN_EXISTING,
2775 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002776 Py_END_ALLOW_THREADS
2777 if (hFile == INVALID_HANDLE_VALUE) {
2778 win32_error("utime", apath);
2779 PyMem_Free(apath);
2780 return NULL;
2781 }
2782 PyMem_Free(apath);
2783 }
2784
2785 if (arg == Py_None) {
2786 SYSTEMTIME now;
2787 GetSystemTime(&now);
2788 if (!SystemTimeToFileTime(&now, &mtime) ||
2789 !SystemTimeToFileTime(&now, &atime)) {
2790 win32_error("utime", NULL);
2791 goto done;
2792 }
2793 }
2794 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2795 PyErr_SetString(PyExc_TypeError,
2796 "utime() arg 2 must be a tuple (atime, mtime)");
2797 goto done;
2798 }
2799 else {
2800 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2801 &atimesec, &ausec) == -1)
2802 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002803 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002804 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2805 &mtimesec, &musec) == -1)
2806 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002807 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002808 }
2809 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2810 /* Avoid putting the file name into the error here,
2811 as that may confuse the user into believing that
2812 something is wrong with the file, when it also
2813 could be the time stamp that gives a problem. */
2814 win32_error("utime", NULL);
2815 }
2816 Py_INCREF(Py_None);
2817 result = Py_None;
2818done:
2819 CloseHandle(hFile);
2820 return result;
2821#else /* Py_WIN_WIDE_FILENAMES */
2822
Neal Norwitz2adf2102004-06-09 01:46:02 +00002823 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002824 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002825 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002826 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002827
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002828#if defined(HAVE_UTIMES)
2829 struct timeval buf[2];
2830#define ATIME buf[0].tv_sec
2831#define MTIME buf[1].tv_sec
2832#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002833/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002834 struct utimbuf buf;
2835#define ATIME buf.actime
2836#define MTIME buf.modtime
2837#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002838#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002839 time_t buf[2];
2840#define ATIME buf[0]
2841#define MTIME buf[1]
2842#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002843#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002844
Mark Hammond817c9292003-12-03 01:22:38 +00002845
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002846 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002847 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002848 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002849 if (arg == Py_None) {
2850 /* optional time values not given */
2851 Py_BEGIN_ALLOW_THREADS
2852 res = utime(path, NULL);
2853 Py_END_ALLOW_THREADS
2854 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002855 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002856 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002857 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002858 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002859 return NULL;
2860 }
2861 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002862 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002863 &atime, &ausec) == -1) {
2864 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002865 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002866 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002867 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002868 &mtime, &musec) == -1) {
2869 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002870 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002871 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002872 ATIME = atime;
2873 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002874#ifdef HAVE_UTIMES
2875 buf[0].tv_usec = ausec;
2876 buf[1].tv_usec = musec;
2877 Py_BEGIN_ALLOW_THREADS
2878 res = utimes(path, buf);
2879 Py_END_ALLOW_THREADS
2880#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002881 Py_BEGIN_ALLOW_THREADS
2882 res = utime(path, UTIME_ARG);
2883 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002884#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002885 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002886 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002887 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002888 }
Neal Norwitz96652712004-06-06 20:40:27 +00002889 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002890 Py_INCREF(Py_None);
2891 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002892#undef UTIME_ARG
2893#undef ATIME
2894#undef MTIME
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002895#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002896}
2897
Guido van Rossum85e3b011991-06-03 12:42:10 +00002898
Guido van Rossum3b066191991-06-04 19:40:25 +00002899/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002900
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002901PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002902"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002903Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002904
Barry Warsaw53699e91996-12-10 23:23:01 +00002905static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002906posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002907{
2908 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002909 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002910 return NULL;
2911 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002912 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002913}
2914
Martin v. Löwis114619e2002-10-07 06:44:21 +00002915#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2916static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002917free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002918{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002919 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002920 for (i = 0; i < count; i++)
2921 PyMem_Free(array[i]);
2922 PyMem_DEL(array);
2923}
2924#endif
2925
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002926
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002927#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002928PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002929"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002930Execute an executable path with arguments, replacing current process.\n\
2931\n\
2932 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002933 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002934
Barry Warsaw53699e91996-12-10 23:23:01 +00002935static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002936posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002937{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002938 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002939 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002940 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002941 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002942 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002943
Guido van Rossum89b33251993-10-22 14:26:06 +00002944 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002945 argv is a list or tuple of strings. */
2946
Martin v. Löwis114619e2002-10-07 06:44:21 +00002947 if (!PyArg_ParseTuple(args, "etO:execv",
2948 Py_FileSystemDefaultEncoding,
2949 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002950 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002951 if (PyList_Check(argv)) {
2952 argc = PyList_Size(argv);
2953 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002954 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002955 else if (PyTuple_Check(argv)) {
2956 argc = PyTuple_Size(argv);
2957 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002958 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002959 else {
Fred Drake661ea262000-10-24 19:57:45 +00002960 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002961 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002962 return NULL;
2963 }
2964
Barry Warsaw53699e91996-12-10 23:23:01 +00002965 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002966 if (argvlist == NULL) {
2967 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002968 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002969 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002970 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002971 if (!PyArg_Parse((*getitem)(argv, i), "et",
2972 Py_FileSystemDefaultEncoding,
2973 &argvlist[i])) {
2974 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002975 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002976 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002977 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002978 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002979
Guido van Rossum85e3b011991-06-03 12:42:10 +00002980 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002981 }
2982 argvlist[argc] = NULL;
2983
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002984 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002985
Guido van Rossum85e3b011991-06-03 12:42:10 +00002986 /* If we get here it's definitely an error */
2987
Martin v. Löwis114619e2002-10-07 06:44:21 +00002988 free_string_array(argvlist, argc);
2989 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002990 return posix_error();
2991}
2992
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002993
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002994PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002995"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002996Execute a path with arguments and environment, replacing current process.\n\
2997\n\
2998 path: path of executable file\n\
2999 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003000 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003001
Barry Warsaw53699e91996-12-10 23:23:01 +00003002static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003003posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003004{
3005 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003006 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003007 char **argvlist;
3008 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003009 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003010 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003011 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003012 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003013
3014 /* execve has three arguments: (path, argv, env), where
3015 argv is a list or tuple of strings and env is a dictionary
3016 like posix.environ. */
3017
Martin v. Löwis114619e2002-10-07 06:44:21 +00003018 if (!PyArg_ParseTuple(args, "etOO:execve",
3019 Py_FileSystemDefaultEncoding,
3020 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003021 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003022 if (PyList_Check(argv)) {
3023 argc = PyList_Size(argv);
3024 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003025 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003026 else if (PyTuple_Check(argv)) {
3027 argc = PyTuple_Size(argv);
3028 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003029 }
3030 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003031 PyErr_SetString(PyExc_TypeError,
3032 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003033 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003034 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003035 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003036 PyErr_SetString(PyExc_TypeError,
3037 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003038 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003039 }
3040
Barry Warsaw53699e91996-12-10 23:23:01 +00003041 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003042 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003043 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003044 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003045 }
3046 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003047 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00003048 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00003049 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00003050 &argvlist[i]))
3051 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003052 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003053 goto fail_1;
3054 }
3055 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003056 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003057 argvlist[argc] = NULL;
3058
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003059 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003060 if (i < 0)
3061 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00003062 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003063 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003064 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003065 goto fail_1;
3066 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003067 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003068 keys = PyMapping_Keys(env);
3069 vals = PyMapping_Values(env);
3070 if (!keys || !vals)
3071 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003072 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3073 PyErr_SetString(PyExc_TypeError,
3074 "execve(): env.keys() or env.values() is not a list");
3075 goto fail_2;
3076 }
Tim Peters5aa91602002-01-30 05:46:57 +00003077
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003078 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003079 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003080 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003081
3082 key = PyList_GetItem(keys, pos);
3083 val = PyList_GetItem(vals, pos);
3084 if (!key || !val)
3085 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003086
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003087 if (!PyArg_Parse(
3088 key,
3089 "s;execve() arg 3 contains a non-string key",
3090 &k) ||
3091 !PyArg_Parse(
3092 val,
3093 "s;execve() arg 3 contains a non-string value",
3094 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003095 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003096 goto fail_2;
3097 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003098
3099#if defined(PYOS_OS2)
3100 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3101 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3102#endif
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003103 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003104 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003105 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003106 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003107 goto fail_2;
3108 }
Tim Petersc8996f52001-12-03 20:41:00 +00003109 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003110 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003111#if defined(PYOS_OS2)
3112 }
3113#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003114 }
3115 envlist[envc] = 0;
3116
3117 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003118
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003119 /* If we get here it's definitely an error */
3120
3121 (void) posix_error();
3122
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003123 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003124 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003125 PyMem_DEL(envlist[envc]);
3126 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003127 fail_1:
3128 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003129 Py_XDECREF(vals);
3130 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003131 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003132 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003133 return NULL;
3134}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003135#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003136
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003137
Guido van Rossuma1065681999-01-25 23:20:23 +00003138#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003139PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003140"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003141Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003142\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003143 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003144 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003145 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003146
3147static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003148posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003149{
3150 char *path;
3151 PyObject *argv;
3152 char **argvlist;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003153 int mode, i;
3154 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003155 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003156 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003157
3158 /* spawnv has three arguments: (mode, path, argv), where
3159 argv is a list or tuple of strings. */
3160
Martin v. Löwis114619e2002-10-07 06:44:21 +00003161 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3162 Py_FileSystemDefaultEncoding,
3163 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003164 return NULL;
3165 if (PyList_Check(argv)) {
3166 argc = PyList_Size(argv);
3167 getitem = PyList_GetItem;
3168 }
3169 else if (PyTuple_Check(argv)) {
3170 argc = PyTuple_Size(argv);
3171 getitem = PyTuple_GetItem;
3172 }
3173 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003174 PyErr_SetString(PyExc_TypeError,
3175 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003176 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003177 return NULL;
3178 }
3179
3180 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003181 if (argvlist == NULL) {
3182 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003183 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003184 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003185 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003186 if (!PyArg_Parse((*getitem)(argv, i), "et",
3187 Py_FileSystemDefaultEncoding,
3188 &argvlist[i])) {
3189 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003190 PyErr_SetString(
3191 PyExc_TypeError,
3192 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003193 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00003194 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003195 }
3196 }
3197 argvlist[argc] = NULL;
3198
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003199#if defined(PYOS_OS2) && defined(PYCC_GCC)
3200 Py_BEGIN_ALLOW_THREADS
3201 spawnval = spawnv(mode, path, argvlist);
3202 Py_END_ALLOW_THREADS
3203#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003204 if (mode == _OLD_P_OVERLAY)
3205 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003206
Tim Peters25059d32001-12-07 20:35:43 +00003207 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003208 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003209 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003210#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003211
Martin v. Löwis114619e2002-10-07 06:44:21 +00003212 free_string_array(argvlist, argc);
3213 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003214
Fred Drake699f3522000-06-29 21:12:41 +00003215 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003216 return posix_error();
3217 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003218#if SIZEOF_LONG == SIZEOF_VOID_P
3219 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003220#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003221 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003222#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003223}
3224
3225
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003226PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003227"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003228Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003229\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003230 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003231 path: path of executable file\n\
3232 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003233 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003234
3235static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003236posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003237{
3238 char *path;
3239 PyObject *argv, *env;
3240 char **argvlist;
3241 char **envlist;
3242 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003243 int mode, pos, envc;
3244 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003245 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003246 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003247 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003248
3249 /* spawnve has four arguments: (mode, path, argv, env), where
3250 argv is a list or tuple of strings and env is a dictionary
3251 like posix.environ. */
3252
Martin v. Löwis114619e2002-10-07 06:44:21 +00003253 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3254 Py_FileSystemDefaultEncoding,
3255 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003256 return NULL;
3257 if (PyList_Check(argv)) {
3258 argc = PyList_Size(argv);
3259 getitem = PyList_GetItem;
3260 }
3261 else if (PyTuple_Check(argv)) {
3262 argc = PyTuple_Size(argv);
3263 getitem = PyTuple_GetItem;
3264 }
3265 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003266 PyErr_SetString(PyExc_TypeError,
3267 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003268 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003269 }
3270 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003271 PyErr_SetString(PyExc_TypeError,
3272 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003273 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003274 }
3275
3276 argvlist = PyMem_NEW(char *, argc+1);
3277 if (argvlist == NULL) {
3278 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003279 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003280 }
3281 for (i = 0; i < argc; i++) {
3282 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003283 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00003284 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00003285 &argvlist[i]))
3286 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003287 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003288 goto fail_1;
3289 }
3290 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003291 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003292 argvlist[argc] = NULL;
3293
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003294 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003295 if (i < 0)
3296 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003297 envlist = PyMem_NEW(char *, i + 1);
3298 if (envlist == NULL) {
3299 PyErr_NoMemory();
3300 goto fail_1;
3301 }
3302 envc = 0;
3303 keys = PyMapping_Keys(env);
3304 vals = PyMapping_Values(env);
3305 if (!keys || !vals)
3306 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003307 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3308 PyErr_SetString(PyExc_TypeError,
3309 "spawnve(): env.keys() or env.values() is not a list");
3310 goto fail_2;
3311 }
Tim Peters5aa91602002-01-30 05:46:57 +00003312
Guido van Rossuma1065681999-01-25 23:20:23 +00003313 for (pos = 0; pos < i; pos++) {
3314 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003315 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003316
3317 key = PyList_GetItem(keys, pos);
3318 val = PyList_GetItem(vals, pos);
3319 if (!key || !val)
3320 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003321
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003322 if (!PyArg_Parse(
3323 key,
3324 "s;spawnve() arg 3 contains a non-string key",
3325 &k) ||
3326 !PyArg_Parse(
3327 val,
3328 "s;spawnve() arg 3 contains a non-string value",
3329 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003330 {
3331 goto fail_2;
3332 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003333 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003334 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003335 if (p == NULL) {
3336 PyErr_NoMemory();
3337 goto fail_2;
3338 }
Tim Petersc8996f52001-12-03 20:41:00 +00003339 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003340 envlist[envc++] = p;
3341 }
3342 envlist[envc] = 0;
3343
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003344#if defined(PYOS_OS2) && defined(PYCC_GCC)
3345 Py_BEGIN_ALLOW_THREADS
3346 spawnval = spawnve(mode, path, argvlist, envlist);
3347 Py_END_ALLOW_THREADS
3348#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003349 if (mode == _OLD_P_OVERLAY)
3350 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003351
3352 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003353 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003354 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003355#endif
Tim Peters25059d32001-12-07 20:35:43 +00003356
Fred Drake699f3522000-06-29 21:12:41 +00003357 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003358 (void) posix_error();
3359 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003360#if SIZEOF_LONG == SIZEOF_VOID_P
3361 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003362#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003363 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003364#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003365
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003366 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003367 while (--envc >= 0)
3368 PyMem_DEL(envlist[envc]);
3369 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003370 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003371 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003372 Py_XDECREF(vals);
3373 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003374 fail_0:
3375 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003376 return res;
3377}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003378
3379/* OS/2 supports spawnvp & spawnvpe natively */
3380#if defined(PYOS_OS2)
3381PyDoc_STRVAR(posix_spawnvp__doc__,
3382"spawnvp(mode, file, args)\n\n\
3383Execute the program 'file' in a new process, using the environment\n\
3384search path to find the file.\n\
3385\n\
3386 mode: mode of process creation\n\
3387 file: executable file name\n\
3388 args: tuple or list of strings");
3389
3390static PyObject *
3391posix_spawnvp(PyObject *self, PyObject *args)
3392{
3393 char *path;
3394 PyObject *argv;
3395 char **argvlist;
3396 int mode, i, argc;
3397 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003398 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003399
3400 /* spawnvp has three arguments: (mode, path, argv), where
3401 argv is a list or tuple of strings. */
3402
3403 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3404 Py_FileSystemDefaultEncoding,
3405 &path, &argv))
3406 return NULL;
3407 if (PyList_Check(argv)) {
3408 argc = PyList_Size(argv);
3409 getitem = PyList_GetItem;
3410 }
3411 else if (PyTuple_Check(argv)) {
3412 argc = PyTuple_Size(argv);
3413 getitem = PyTuple_GetItem;
3414 }
3415 else {
3416 PyErr_SetString(PyExc_TypeError,
3417 "spawnvp() arg 2 must be a tuple or list");
3418 PyMem_Free(path);
3419 return NULL;
3420 }
3421
3422 argvlist = PyMem_NEW(char *, argc+1);
3423 if (argvlist == NULL) {
3424 PyMem_Free(path);
3425 return PyErr_NoMemory();
3426 }
3427 for (i = 0; i < argc; i++) {
3428 if (!PyArg_Parse((*getitem)(argv, i), "et",
3429 Py_FileSystemDefaultEncoding,
3430 &argvlist[i])) {
3431 free_string_array(argvlist, i);
3432 PyErr_SetString(
3433 PyExc_TypeError,
3434 "spawnvp() arg 2 must contain only strings");
3435 PyMem_Free(path);
3436 return NULL;
3437 }
3438 }
3439 argvlist[argc] = NULL;
3440
3441 Py_BEGIN_ALLOW_THREADS
3442#if defined(PYCC_GCC)
3443 spawnval = spawnvp(mode, path, argvlist);
3444#else
3445 spawnval = _spawnvp(mode, path, argvlist);
3446#endif
3447 Py_END_ALLOW_THREADS
3448
3449 free_string_array(argvlist, argc);
3450 PyMem_Free(path);
3451
3452 if (spawnval == -1)
3453 return posix_error();
3454 else
3455 return Py_BuildValue("l", (long) spawnval);
3456}
3457
3458
3459PyDoc_STRVAR(posix_spawnvpe__doc__,
3460"spawnvpe(mode, file, args, env)\n\n\
3461Execute the program 'file' in a new process, using the environment\n\
3462search path to find the file.\n\
3463\n\
3464 mode: mode of process creation\n\
3465 file: executable file name\n\
3466 args: tuple or list of arguments\n\
3467 env: dictionary of strings mapping to strings");
3468
3469static PyObject *
3470posix_spawnvpe(PyObject *self, PyObject *args)
3471{
3472 char *path;
3473 PyObject *argv, *env;
3474 char **argvlist;
3475 char **envlist;
3476 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3477 int mode, i, pos, argc, envc;
3478 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003479 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003480 int lastarg = 0;
3481
3482 /* spawnvpe has four arguments: (mode, path, argv, env), where
3483 argv is a list or tuple of strings and env is a dictionary
3484 like posix.environ. */
3485
3486 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3487 Py_FileSystemDefaultEncoding,
3488 &path, &argv, &env))
3489 return NULL;
3490 if (PyList_Check(argv)) {
3491 argc = PyList_Size(argv);
3492 getitem = PyList_GetItem;
3493 }
3494 else if (PyTuple_Check(argv)) {
3495 argc = PyTuple_Size(argv);
3496 getitem = PyTuple_GetItem;
3497 }
3498 else {
3499 PyErr_SetString(PyExc_TypeError,
3500 "spawnvpe() arg 2 must be a tuple or list");
3501 goto fail_0;
3502 }
3503 if (!PyMapping_Check(env)) {
3504 PyErr_SetString(PyExc_TypeError,
3505 "spawnvpe() arg 3 must be a mapping object");
3506 goto fail_0;
3507 }
3508
3509 argvlist = PyMem_NEW(char *, argc+1);
3510 if (argvlist == NULL) {
3511 PyErr_NoMemory();
3512 goto fail_0;
3513 }
3514 for (i = 0; i < argc; i++) {
3515 if (!PyArg_Parse((*getitem)(argv, i),
3516 "et;spawnvpe() arg 2 must contain only strings",
3517 Py_FileSystemDefaultEncoding,
3518 &argvlist[i]))
3519 {
3520 lastarg = i;
3521 goto fail_1;
3522 }
3523 }
3524 lastarg = argc;
3525 argvlist[argc] = NULL;
3526
3527 i = PyMapping_Size(env);
3528 if (i < 0)
3529 goto fail_1;
3530 envlist = PyMem_NEW(char *, i + 1);
3531 if (envlist == NULL) {
3532 PyErr_NoMemory();
3533 goto fail_1;
3534 }
3535 envc = 0;
3536 keys = PyMapping_Keys(env);
3537 vals = PyMapping_Values(env);
3538 if (!keys || !vals)
3539 goto fail_2;
3540 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3541 PyErr_SetString(PyExc_TypeError,
3542 "spawnvpe(): env.keys() or env.values() is not a list");
3543 goto fail_2;
3544 }
3545
3546 for (pos = 0; pos < i; pos++) {
3547 char *p, *k, *v;
3548 size_t len;
3549
3550 key = PyList_GetItem(keys, pos);
3551 val = PyList_GetItem(vals, pos);
3552 if (!key || !val)
3553 goto fail_2;
3554
3555 if (!PyArg_Parse(
3556 key,
3557 "s;spawnvpe() arg 3 contains a non-string key",
3558 &k) ||
3559 !PyArg_Parse(
3560 val,
3561 "s;spawnvpe() arg 3 contains a non-string value",
3562 &v))
3563 {
3564 goto fail_2;
3565 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003566 len = PyString_Size(key) + PyString_Size(val) + 2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003567 p = PyMem_NEW(char, len);
3568 if (p == NULL) {
3569 PyErr_NoMemory();
3570 goto fail_2;
3571 }
3572 PyOS_snprintf(p, len, "%s=%s", k, v);
3573 envlist[envc++] = p;
3574 }
3575 envlist[envc] = 0;
3576
3577 Py_BEGIN_ALLOW_THREADS
3578#if defined(PYCC_GCC)
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003579 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003580#else
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003581 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003582#endif
3583 Py_END_ALLOW_THREADS
3584
3585 if (spawnval == -1)
3586 (void) posix_error();
3587 else
3588 res = Py_BuildValue("l", (long) spawnval);
3589
3590 fail_2:
3591 while (--envc >= 0)
3592 PyMem_DEL(envlist[envc]);
3593 PyMem_DEL(envlist);
3594 fail_1:
3595 free_string_array(argvlist, lastarg);
3596 Py_XDECREF(vals);
3597 Py_XDECREF(keys);
3598 fail_0:
3599 PyMem_Free(path);
3600 return res;
3601}
3602#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003603#endif /* HAVE_SPAWNV */
3604
3605
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003606#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003607PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003608"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003609Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3610\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003611Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003612
3613static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003614posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003615{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003616 pid_t pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003617 if (pid == -1)
3618 return posix_error();
Gregory P. Smithfb7a50f2008-07-14 06:06:48 +00003619 if (pid == 0)
3620 PyOS_AfterFork();
Christian Heimes951cc0f2008-01-31 23:08:23 +00003621 return PyInt_FromLong(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003622}
3623#endif
3624
3625
Guido van Rossumad0ee831995-03-01 10:34:45 +00003626#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003627PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003628"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003629Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003630Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003631
Barry Warsaw53699e91996-12-10 23:23:01 +00003632static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003633posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003634{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003635 pid_t pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003636 if (pid == -1)
3637 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003638 if (pid == 0)
3639 PyOS_AfterFork();
Christian Heimes951cc0f2008-01-31 23:08:23 +00003640 return PyInt_FromLong(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003641}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003642#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003643
Neal Norwitzb59798b2003-03-21 01:43:31 +00003644/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003645/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3646#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003647#define DEV_PTY_FILE "/dev/ptc"
3648#define HAVE_DEV_PTMX
3649#else
3650#define DEV_PTY_FILE "/dev/ptmx"
3651#endif
3652
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003653#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003654#ifdef HAVE_PTY_H
3655#include <pty.h>
3656#else
3657#ifdef HAVE_LIBUTIL_H
3658#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003659#endif /* HAVE_LIBUTIL_H */
3660#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003661#ifdef HAVE_STROPTS_H
3662#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003663#endif
3664#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003665
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003666#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003667PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003668"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003669Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003670
3671static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003672posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003673{
3674 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003675#ifndef HAVE_OPENPTY
3676 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003677#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003678#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003679 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003680#ifdef sun
Neal Norwitz84a98e02006-04-10 07:44:23 +00003681 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003682#endif
3683#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003684
Thomas Wouters70c21a12000-07-14 14:28:33 +00003685#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003686 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3687 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003688#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003689 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3690 if (slave_name == NULL)
3691 return posix_error();
3692
3693 slave_fd = open(slave_name, O_RDWR);
3694 if (slave_fd < 0)
3695 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003696#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003697 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003698 if (master_fd < 0)
3699 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003700 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003701 /* change permission of slave */
3702 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003703 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003704 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003705 }
3706 /* unlock slave */
3707 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003708 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003709 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003710 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003711 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003712 slave_name = ptsname(master_fd); /* get name of slave */
3713 if (slave_name == NULL)
3714 return posix_error();
3715 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3716 if (slave_fd < 0)
3717 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003718#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003719 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3720 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003721#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003722 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003723#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003724#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003725#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003726
Fred Drake8cef4cf2000-06-28 16:40:38 +00003727 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003728
Fred Drake8cef4cf2000-06-28 16:40:38 +00003729}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003730#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003731
3732#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003733PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003734"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003735Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3736Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003737To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003738
3739static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003740posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003741{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003742 int master_fd = -1;
3743 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003744
Fred Drake8cef4cf2000-06-28 16:40:38 +00003745 pid = forkpty(&master_fd, NULL, NULL, NULL);
3746 if (pid == -1)
3747 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003748 if (pid == 0)
3749 PyOS_AfterFork();
Christian Heimes951cc0f2008-01-31 23:08:23 +00003750 return Py_BuildValue("(li)", pid, master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003751}
3752#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003753
Guido van Rossumad0ee831995-03-01 10:34:45 +00003754#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003755PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003756"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003757Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003758
Barry Warsaw53699e91996-12-10 23:23:01 +00003759static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003760posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003761{
Barry Warsaw53699e91996-12-10 23:23:01 +00003762 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003763}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003764#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003765
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003766
Guido van Rossumad0ee831995-03-01 10:34:45 +00003767#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003768PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003769"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003770Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003771
Barry Warsaw53699e91996-12-10 23:23:01 +00003772static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003773posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003774{
Barry Warsaw53699e91996-12-10 23:23:01 +00003775 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003776}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003777#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003778
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003779
Guido van Rossumad0ee831995-03-01 10:34:45 +00003780#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003781PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003782"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003783Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003784
Barry Warsaw53699e91996-12-10 23:23:01 +00003785static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003786posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003787{
Barry Warsaw53699e91996-12-10 23:23:01 +00003788 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003789}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003790#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003791
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003792
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003793PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003794"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003795Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003796
Barry Warsaw53699e91996-12-10 23:23:01 +00003797static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003798posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003799{
Barry Warsaw53699e91996-12-10 23:23:01 +00003800 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003801}
3802
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003803
Fred Drakec9680921999-12-13 16:37:25 +00003804#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003805PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003806"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003807Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003808
3809static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003810posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003811{
3812 PyObject *result = NULL;
3813
Fred Drakec9680921999-12-13 16:37:25 +00003814#ifdef NGROUPS_MAX
3815#define MAX_GROUPS NGROUPS_MAX
3816#else
3817 /* defined to be 16 on Solaris7, so this should be a small number */
3818#define MAX_GROUPS 64
3819#endif
3820 gid_t grouplist[MAX_GROUPS];
3821 int n;
3822
3823 n = getgroups(MAX_GROUPS, grouplist);
3824 if (n < 0)
3825 posix_error();
3826 else {
3827 result = PyList_New(n);
3828 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003829 int i;
3830 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003831 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003832 if (o == NULL) {
3833 Py_DECREF(result);
3834 result = NULL;
3835 break;
3836 }
3837 PyList_SET_ITEM(result, i, o);
3838 }
3839 }
3840 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003841
Fred Drakec9680921999-12-13 16:37:25 +00003842 return result;
3843}
3844#endif
3845
Martin v. Löwis606edc12002-06-13 21:09:11 +00003846#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003847PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003848"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003849Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003850
3851static PyObject *
3852posix_getpgid(PyObject *self, PyObject *args)
3853{
3854 int pid, pgid;
3855 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3856 return NULL;
3857 pgid = getpgid(pid);
3858 if (pgid < 0)
3859 return posix_error();
3860 return PyInt_FromLong((long)pgid);
3861}
3862#endif /* HAVE_GETPGID */
3863
3864
Guido van Rossumb6775db1994-08-01 11:34:53 +00003865#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003866PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003867"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003868Return the current process group id.");
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_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003872{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003873#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003874 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003875#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003876 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003877#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003878}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003879#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003880
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003881
Guido van Rossumb6775db1994-08-01 11:34:53 +00003882#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003883PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003884"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003885Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003886
Barry Warsaw53699e91996-12-10 23:23:01 +00003887static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003888posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003889{
Guido van Rossum64933891994-10-20 21:56:42 +00003890#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003891 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003892#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003893 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003894#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003895 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003896 Py_INCREF(Py_None);
3897 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003898}
3899
Guido van Rossumb6775db1994-08-01 11:34:53 +00003900#endif /* HAVE_SETPGRP */
3901
Guido van Rossumad0ee831995-03-01 10:34:45 +00003902#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003903PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003904"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003905Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003906
Barry Warsaw53699e91996-12-10 23:23:01 +00003907static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003908posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003909{
Christian Heimesd491d712008-02-01 18:49:26 +00003910 return PyInt_FromLong(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003911}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003912#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003913
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003914
Fred Drake12c6e2d1999-12-14 21:25:03 +00003915#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003916PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003917"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003918Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003919
3920static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003921posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003922{
Neal Norwitze241ce82003-02-17 18:17:05 +00003923 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003924 char *name;
3925 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003926
Fred Drakea30680b2000-12-06 21:24:28 +00003927 errno = 0;
3928 name = getlogin();
3929 if (name == NULL) {
3930 if (errno)
3931 posix_error();
3932 else
3933 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003934 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003935 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003936 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003937 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003938 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003939
Fred Drake12c6e2d1999-12-14 21:25:03 +00003940 return result;
3941}
3942#endif
3943
Guido van Rossumad0ee831995-03-01 10:34:45 +00003944#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003945PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003946"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003947Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003948
Barry Warsaw53699e91996-12-10 23:23:01 +00003949static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003950posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003951{
Barry Warsaw53699e91996-12-10 23:23:01 +00003952 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003953}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003954#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003955
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003956
Guido van Rossumad0ee831995-03-01 10:34:45 +00003957#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003958PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003959"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003960Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003961
Barry Warsaw53699e91996-12-10 23:23:01 +00003962static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003963posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003964{
Christian Heimesd491d712008-02-01 18:49:26 +00003965 pid_t pid;
3966 int sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003967 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003968 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003969#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003970 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3971 APIRET rc;
3972 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003973 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003974
3975 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3976 APIRET rc;
3977 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003978 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003979
3980 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003981 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003982#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003983 if (kill(pid, sig) == -1)
3984 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003985#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003986 Py_INCREF(Py_None);
3987 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003988}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003989#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003990
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003991#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003992PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003993"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003994Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003995
3996static PyObject *
3997posix_killpg(PyObject *self, PyObject *args)
3998{
3999 int pgid, sig;
4000 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
4001 return NULL;
4002 if (killpg(pgid, sig) == -1)
4003 return posix_error();
4004 Py_INCREF(Py_None);
4005 return Py_None;
4006}
4007#endif
4008
Guido van Rossumc0125471996-06-28 18:55:32 +00004009#ifdef HAVE_PLOCK
4010
4011#ifdef HAVE_SYS_LOCK_H
4012#include <sys/lock.h>
4013#endif
4014
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004015PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004016"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004017Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004018
Barry Warsaw53699e91996-12-10 23:23:01 +00004019static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004020posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004021{
4022 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004023 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00004024 return NULL;
4025 if (plock(op) == -1)
4026 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004027 Py_INCREF(Py_None);
4028 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004029}
4030#endif
4031
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004032
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004033#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004034PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004035"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004036Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004037
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004038#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004039#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004040static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004041async_system(const char *command)
4042{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004043 char errormsg[256], args[1024];
4044 RESULTCODES rcodes;
4045 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004046
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004047 char *shell = getenv("COMSPEC");
4048 if (!shell)
4049 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004050
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004051 /* avoid overflowing the argument buffer */
4052 if (strlen(shell) + 3 + strlen(command) >= 1024)
4053 return ERROR_NOT_ENOUGH_MEMORY
4054
4055 args[0] = '\0';
4056 strcat(args, shell);
4057 strcat(args, "/c ");
4058 strcat(args, command);
4059
4060 /* execute asynchronously, inheriting the environment */
4061 rc = DosExecPgm(errormsg,
4062 sizeof(errormsg),
4063 EXEC_ASYNC,
4064 args,
4065 NULL,
4066 &rcodes,
4067 shell);
4068 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004069}
4070
Guido van Rossumd48f2521997-12-05 22:19:34 +00004071static FILE *
4072popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004073{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004074 int oldfd, tgtfd;
4075 HFILE pipeh[2];
4076 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004077
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004078 /* mode determines which of stdin or stdout is reconnected to
4079 * the pipe to the child
4080 */
4081 if (strchr(mode, 'r') != NULL) {
4082 tgt_fd = 1; /* stdout */
4083 } else if (strchr(mode, 'w')) {
4084 tgt_fd = 0; /* stdin */
4085 } else {
4086 *err = ERROR_INVALID_ACCESS;
4087 return NULL;
4088 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004089
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00004090 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004091 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4092 *err = rc;
4093 return NULL;
4094 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004095
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004096 /* prevent other threads accessing stdio */
4097 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004098
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004099 /* reconnect stdio and execute child */
4100 oldfd = dup(tgtfd);
4101 close(tgtfd);
4102 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4103 DosClose(pipeh[tgtfd]);
4104 rc = async_system(command);
4105 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004106
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004107 /* restore stdio */
4108 dup2(oldfd, tgtfd);
4109 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004110
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004111 /* allow other threads access to stdio */
4112 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004113
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004114 /* if execution of child was successful return file stream */
4115 if (rc == NO_ERROR)
4116 return fdopen(pipeh[1 - tgtfd], mode);
4117 else {
4118 DosClose(pipeh[1 - tgtfd]);
4119 *err = rc;
4120 return NULL;
4121 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004122}
4123
4124static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004125posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004126{
4127 char *name;
4128 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00004129 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004130 FILE *fp;
4131 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004132 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004133 return NULL;
4134 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00004135 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004136 Py_END_ALLOW_THREADS
4137 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004138 return os2_error(err);
4139
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004140 f = PyFile_FromFile(fp, name, mode, fclose);
4141 if (f != NULL)
4142 PyFile_SetBufSize(f, bufsize);
4143 return f;
4144}
4145
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004146#elif defined(PYCC_GCC)
4147
4148/* standard posix version of popen() support */
4149static PyObject *
4150posix_popen(PyObject *self, PyObject *args)
4151{
4152 char *name;
4153 char *mode = "r";
4154 int bufsize = -1;
4155 FILE *fp;
4156 PyObject *f;
4157 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4158 return NULL;
4159 Py_BEGIN_ALLOW_THREADS
4160 fp = popen(name, mode);
4161 Py_END_ALLOW_THREADS
4162 if (fp == NULL)
4163 return posix_error();
4164 f = PyFile_FromFile(fp, name, mode, pclose);
4165 if (f != NULL)
4166 PyFile_SetBufSize(f, bufsize);
4167 return f;
4168}
4169
4170/* fork() under OS/2 has lots'o'warts
4171 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4172 * most of this code is a ripoff of the win32 code, but using the
4173 * capabilities of EMX's C library routines
4174 */
4175
4176/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4177#define POPEN_1 1
4178#define POPEN_2 2
4179#define POPEN_3 3
4180#define POPEN_4 4
4181
4182static PyObject *_PyPopen(char *, int, int, int);
4183static int _PyPclose(FILE *file);
4184
4185/*
4186 * Internal dictionary mapping popen* file pointers to process handles,
4187 * for use when retrieving the process exit code. See _PyPclose() below
4188 * for more information on this dictionary's use.
4189 */
4190static PyObject *_PyPopenProcs = NULL;
4191
4192/* os2emx version of popen2()
4193 *
4194 * The result of this function is a pipe (file) connected to the
4195 * process's stdin, and a pipe connected to the process's stdout.
4196 */
4197
4198static PyObject *
4199os2emx_popen2(PyObject *self, PyObject *args)
4200{
4201 PyObject *f;
4202 int tm=0;
4203
4204 char *cmdstring;
4205 char *mode = "t";
4206 int bufsize = -1;
4207 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4208 return NULL;
4209
4210 if (*mode == 't')
4211 tm = O_TEXT;
4212 else if (*mode != 'b') {
4213 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4214 return NULL;
4215 } else
4216 tm = O_BINARY;
4217
4218 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
4219
4220 return f;
4221}
4222
4223/*
4224 * Variation on os2emx.popen2
4225 *
4226 * The result of this function is 3 pipes - the process's stdin,
4227 * stdout and stderr
4228 */
4229
4230static PyObject *
4231os2emx_popen3(PyObject *self, PyObject *args)
4232{
4233 PyObject *f;
4234 int tm = 0;
4235
4236 char *cmdstring;
4237 char *mode = "t";
4238 int bufsize = -1;
4239 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4240 return NULL;
4241
4242 if (*mode == 't')
4243 tm = O_TEXT;
4244 else if (*mode != 'b') {
4245 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4246 return NULL;
4247 } else
4248 tm = O_BINARY;
4249
4250 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
4251
4252 return f;
4253}
4254
4255/*
4256 * Variation on os2emx.popen2
4257 *
Tim Peters11b23062003-04-23 02:39:17 +00004258 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004259 * and stdout+stderr combined as a single pipe.
4260 */
4261
4262static PyObject *
4263os2emx_popen4(PyObject *self, PyObject *args)
4264{
4265 PyObject *f;
4266 int tm = 0;
4267
4268 char *cmdstring;
4269 char *mode = "t";
4270 int bufsize = -1;
4271 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4272 return NULL;
4273
4274 if (*mode == 't')
4275 tm = O_TEXT;
4276 else if (*mode != 'b') {
4277 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4278 return NULL;
4279 } else
4280 tm = O_BINARY;
4281
4282 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
4283
4284 return f;
4285}
4286
4287/* a couple of structures for convenient handling of multiple
4288 * file handles and pipes
4289 */
4290struct file_ref
4291{
4292 int handle;
4293 int flags;
4294};
4295
4296struct pipe_ref
4297{
4298 int rd;
4299 int wr;
4300};
4301
4302/* The following code is derived from the win32 code */
4303
4304static PyObject *
4305_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4306{
4307 struct file_ref stdio[3];
4308 struct pipe_ref p_fd[3];
4309 FILE *p_s[3];
Christian Heimesd491d712008-02-01 18:49:26 +00004310 int file_count, i, pipe_err;
4311 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004312 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4313 PyObject *f, *p_f[3];
4314
4315 /* file modes for subsequent fdopen's on pipe handles */
4316 if (mode == O_TEXT)
4317 {
4318 rd_mode = "rt";
4319 wr_mode = "wt";
4320 }
4321 else
4322 {
4323 rd_mode = "rb";
4324 wr_mode = "wb";
4325 }
4326
4327 /* prepare shell references */
4328 if ((shell = getenv("EMXSHELL")) == NULL)
4329 if ((shell = getenv("COMSPEC")) == NULL)
4330 {
4331 errno = ENOENT;
4332 return posix_error();
4333 }
4334
4335 sh_name = _getname(shell);
4336 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4337 opt = "/c";
4338 else
4339 opt = "-c";
4340
4341 /* save current stdio fds + their flags, and set not inheritable */
4342 i = pipe_err = 0;
4343 while (pipe_err >= 0 && i < 3)
4344 {
4345 pipe_err = stdio[i].handle = dup(i);
4346 stdio[i].flags = fcntl(i, F_GETFD, 0);
4347 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4348 i++;
4349 }
4350 if (pipe_err < 0)
4351 {
4352 /* didn't get them all saved - clean up and bail out */
4353 int saved_err = errno;
4354 while (i-- > 0)
4355 {
4356 close(stdio[i].handle);
4357 }
4358 errno = saved_err;
4359 return posix_error();
4360 }
4361
4362 /* create pipe ends */
4363 file_count = 2;
4364 if (n == POPEN_3)
4365 file_count = 3;
4366 i = pipe_err = 0;
4367 while ((pipe_err == 0) && (i < file_count))
4368 pipe_err = pipe((int *)&p_fd[i++]);
4369 if (pipe_err < 0)
4370 {
4371 /* didn't get them all made - clean up and bail out */
4372 while (i-- > 0)
4373 {
4374 close(p_fd[i].wr);
4375 close(p_fd[i].rd);
4376 }
4377 errno = EPIPE;
4378 return posix_error();
4379 }
4380
4381 /* change the actual standard IO streams over temporarily,
4382 * making the retained pipe ends non-inheritable
4383 */
4384 pipe_err = 0;
4385
4386 /* - stdin */
4387 if (dup2(p_fd[0].rd, 0) == 0)
4388 {
4389 close(p_fd[0].rd);
4390 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4391 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4392 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4393 {
4394 close(p_fd[0].wr);
4395 pipe_err = -1;
4396 }
4397 }
4398 else
4399 {
4400 pipe_err = -1;
4401 }
4402
4403 /* - stdout */
4404 if (pipe_err == 0)
4405 {
4406 if (dup2(p_fd[1].wr, 1) == 1)
4407 {
4408 close(p_fd[1].wr);
4409 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4410 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4411 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4412 {
4413 close(p_fd[1].rd);
4414 pipe_err = -1;
4415 }
4416 }
4417 else
4418 {
4419 pipe_err = -1;
4420 }
4421 }
4422
4423 /* - stderr, as required */
4424 if (pipe_err == 0)
4425 switch (n)
4426 {
4427 case POPEN_3:
4428 {
4429 if (dup2(p_fd[2].wr, 2) == 2)
4430 {
4431 close(p_fd[2].wr);
4432 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4433 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4434 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4435 {
4436 close(p_fd[2].rd);
4437 pipe_err = -1;
4438 }
4439 }
4440 else
4441 {
4442 pipe_err = -1;
4443 }
4444 break;
4445 }
4446
4447 case POPEN_4:
4448 {
4449 if (dup2(1, 2) != 2)
4450 {
4451 pipe_err = -1;
4452 }
4453 break;
4454 }
4455 }
4456
4457 /* spawn the child process */
4458 if (pipe_err == 0)
4459 {
4460 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4461 if (pipe_pid == -1)
4462 {
4463 pipe_err = -1;
4464 }
4465 else
4466 {
4467 /* save the PID into the FILE structure
4468 * NOTE: this implementation doesn't actually
4469 * take advantage of this, but do it for
4470 * completeness - AIM Apr01
4471 */
4472 for (i = 0; i < file_count; i++)
4473 p_s[i]->_pid = pipe_pid;
4474 }
4475 }
4476
4477 /* reset standard IO to normal */
4478 for (i = 0; i < 3; i++)
4479 {
4480 dup2(stdio[i].handle, i);
4481 fcntl(i, F_SETFD, stdio[i].flags);
4482 close(stdio[i].handle);
4483 }
4484
4485 /* if any remnant problems, clean up and bail out */
4486 if (pipe_err < 0)
4487 {
4488 for (i = 0; i < 3; i++)
4489 {
4490 close(p_fd[i].rd);
4491 close(p_fd[i].wr);
4492 }
4493 errno = EPIPE;
4494 return posix_error_with_filename(cmdstring);
4495 }
4496
4497 /* build tuple of file objects to return */
4498 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4499 PyFile_SetBufSize(p_f[0], bufsize);
4500 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4501 PyFile_SetBufSize(p_f[1], bufsize);
4502 if (n == POPEN_3)
4503 {
4504 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4505 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004506 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004507 }
4508 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004509 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004510
4511 /*
4512 * Insert the files we've created into the process dictionary
4513 * all referencing the list with the process handle and the
4514 * initial number of files (see description below in _PyPclose).
4515 * Since if _PyPclose later tried to wait on a process when all
4516 * handles weren't closed, it could create a deadlock with the
4517 * child, we spend some energy here to try to ensure that we
4518 * either insert all file handles into the dictionary or none
4519 * at all. It's a little clumsy with the various popen modes
4520 * and variable number of files involved.
4521 */
4522 if (!_PyPopenProcs)
4523 {
4524 _PyPopenProcs = PyDict_New();
4525 }
4526
4527 if (_PyPopenProcs)
4528 {
4529 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4530 int ins_rc[3];
4531
4532 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4533 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4534
4535 procObj = PyList_New(2);
4536 pidObj = PyInt_FromLong((long) pipe_pid);
4537 intObj = PyInt_FromLong((long) file_count);
4538
4539 if (procObj && pidObj && intObj)
4540 {
4541 PyList_SetItem(procObj, 0, pidObj);
4542 PyList_SetItem(procObj, 1, intObj);
4543
4544 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4545 if (fileObj[0])
4546 {
4547 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4548 fileObj[0],
4549 procObj);
4550 }
4551 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4552 if (fileObj[1])
4553 {
4554 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4555 fileObj[1],
4556 procObj);
4557 }
4558 if (file_count >= 3)
4559 {
4560 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4561 if (fileObj[2])
4562 {
4563 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4564 fileObj[2],
4565 procObj);
4566 }
4567 }
4568
4569 if (ins_rc[0] < 0 || !fileObj[0] ||
4570 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4571 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4572 {
4573 /* Something failed - remove any dictionary
4574 * entries that did make it.
4575 */
4576 if (!ins_rc[0] && fileObj[0])
4577 {
4578 PyDict_DelItem(_PyPopenProcs,
4579 fileObj[0]);
4580 }
4581 if (!ins_rc[1] && fileObj[1])
4582 {
4583 PyDict_DelItem(_PyPopenProcs,
4584 fileObj[1]);
4585 }
4586 if (!ins_rc[2] && fileObj[2])
4587 {
4588 PyDict_DelItem(_PyPopenProcs,
4589 fileObj[2]);
4590 }
4591 }
4592 }
Tim Peters11b23062003-04-23 02:39:17 +00004593
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004594 /*
4595 * Clean up our localized references for the dictionary keys
4596 * and value since PyDict_SetItem will Py_INCREF any copies
4597 * that got placed in the dictionary.
4598 */
4599 Py_XDECREF(procObj);
4600 Py_XDECREF(fileObj[0]);
4601 Py_XDECREF(fileObj[1]);
4602 Py_XDECREF(fileObj[2]);
4603 }
4604
4605 /* Child is launched. */
4606 return f;
4607}
4608
4609/*
4610 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4611 * exit code for the child process and return as a result of the close.
4612 *
4613 * This function uses the _PyPopenProcs dictionary in order to map the
4614 * input file pointer to information about the process that was
4615 * originally created by the popen* call that created the file pointer.
4616 * The dictionary uses the file pointer as a key (with one entry
4617 * inserted for each file returned by the original popen* call) and a
4618 * single list object as the value for all files from a single call.
4619 * The list object contains the Win32 process handle at [0], and a file
4620 * count at [1], which is initialized to the total number of file
4621 * handles using that list.
4622 *
4623 * This function closes whichever handle it is passed, and decrements
4624 * the file count in the dictionary for the process handle pointed to
4625 * by this file. On the last close (when the file count reaches zero),
4626 * this function will wait for the child process and then return its
4627 * exit code as the result of the close() operation. This permits the
4628 * files to be closed in any order - it is always the close() of the
4629 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004630 *
4631 * NOTE: This function is currently called with the GIL released.
4632 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004633 */
4634
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004635static int _PyPclose(FILE *file)
4636{
4637 int result;
4638 int exit_code;
Christian Heimesd491d712008-02-01 18:49:26 +00004639 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004640 PyObject *procObj, *pidObj, *intObj, *fileObj;
4641 int file_count;
4642#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004643 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004644#endif
4645
4646 /* Close the file handle first, to ensure it can't block the
4647 * child from exiting if it's the last handle.
4648 */
4649 result = fclose(file);
4650
4651#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004652 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004653#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004654 if (_PyPopenProcs)
4655 {
4656 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4657 (procObj = PyDict_GetItem(_PyPopenProcs,
4658 fileObj)) != NULL &&
4659 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4660 (intObj = PyList_GetItem(procObj,1)) != NULL)
4661 {
4662 pipe_pid = (int) PyInt_AsLong(pidObj);
4663 file_count = (int) PyInt_AsLong(intObj);
4664
4665 if (file_count > 1)
4666 {
4667 /* Still other files referencing process */
4668 file_count--;
4669 PyList_SetItem(procObj,1,
4670 PyInt_FromLong((long) file_count));
4671 }
4672 else
4673 {
4674 /* Last file for this process */
4675 if (result != EOF &&
4676 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4677 {
4678 /* extract exit status */
4679 if (WIFEXITED(exit_code))
4680 {
4681 result = WEXITSTATUS(exit_code);
4682 }
4683 else
4684 {
4685 errno = EPIPE;
4686 result = -1;
4687 }
4688 }
4689 else
4690 {
4691 /* Indicate failure - this will cause the file object
4692 * to raise an I/O error and translate the last
4693 * error code from errno. We do have a problem with
4694 * last errors that overlap the normal errno table,
4695 * but that's a consistent problem with the file object.
4696 */
4697 result = -1;
4698 }
4699 }
4700
4701 /* Remove this file pointer from dictionary */
4702 PyDict_DelItem(_PyPopenProcs, fileObj);
4703
4704 if (PyDict_Size(_PyPopenProcs) == 0)
4705 {
4706 Py_DECREF(_PyPopenProcs);
4707 _PyPopenProcs = NULL;
4708 }
4709
4710 } /* if object retrieval ok */
4711
4712 Py_XDECREF(fileObj);
4713 } /* if _PyPopenProcs */
4714
4715#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004716 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004717#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004718 return result;
4719}
4720
4721#endif /* PYCC_??? */
4722
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004723#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004724
4725/*
4726 * Portable 'popen' replacement for Win32.
4727 *
4728 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4729 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004730 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004731 */
4732
4733#include <malloc.h>
4734#include <io.h>
4735#include <fcntl.h>
4736
4737/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4738#define POPEN_1 1
4739#define POPEN_2 2
4740#define POPEN_3 3
4741#define POPEN_4 4
4742
4743static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004744static int _PyPclose(FILE *file);
4745
4746/*
4747 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004748 * for use when retrieving the process exit code. See _PyPclose() below
4749 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004750 */
4751static PyObject *_PyPopenProcs = NULL;
4752
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004753
4754/* popen that works from a GUI.
4755 *
4756 * The result of this function is a pipe (file) connected to the
4757 * processes stdin or stdout, depending on the requested mode.
4758 */
4759
4760static PyObject *
4761posix_popen(PyObject *self, PyObject *args)
4762{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004763 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004764 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004765
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004766 char *cmdstring;
4767 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004768 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004769 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004770 return NULL;
4771
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004772 if (*mode == 'r')
4773 tm = _O_RDONLY;
4774 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004775 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004776 return NULL;
4777 } else
4778 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004779
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004780 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004781 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004782 return NULL;
4783 }
4784
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004785 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004786 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004787 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004788 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004789 else
4790 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4791
4792 return f;
4793}
4794
4795/* Variation on win32pipe.popen
4796 *
4797 * The result of this function is a pipe (file) connected to the
4798 * process's stdin, and a pipe connected to the process's stdout.
4799 */
4800
4801static PyObject *
4802win32_popen2(PyObject *self, PyObject *args)
4803{
4804 PyObject *f;
4805 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004806
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004807 char *cmdstring;
4808 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004809 int bufsize = -1;
4810 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004811 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004812
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004813 if (*mode == 't')
4814 tm = _O_TEXT;
4815 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004816 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004817 return NULL;
4818 } else
4819 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004820
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004821 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004822 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004823 return NULL;
4824 }
4825
4826 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004827
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004828 return f;
4829}
4830
4831/*
4832 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004833 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004834 * The result of this function is 3 pipes - the process's stdin,
4835 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004836 */
4837
4838static PyObject *
4839win32_popen3(PyObject *self, PyObject *args)
4840{
4841 PyObject *f;
4842 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004843
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004844 char *cmdstring;
4845 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004846 int bufsize = -1;
4847 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004848 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004849
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004850 if (*mode == 't')
4851 tm = _O_TEXT;
4852 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004853 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004854 return NULL;
4855 } else
4856 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004857
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004858 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004859 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004860 return NULL;
4861 }
4862
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004863 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004864
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004865 return f;
4866}
4867
4868/*
4869 * Variation on win32pipe.popen
4870 *
Tim Peters5aa91602002-01-30 05:46:57 +00004871 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004872 * and stdout+stderr combined as a single pipe.
4873 */
4874
4875static PyObject *
4876win32_popen4(PyObject *self, PyObject *args)
4877{
4878 PyObject *f;
4879 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004880
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004881 char *cmdstring;
4882 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004883 int bufsize = -1;
4884 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004885 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004886
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004887 if (*mode == 't')
4888 tm = _O_TEXT;
4889 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004890 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004891 return NULL;
4892 } else
4893 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004894
4895 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004896 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004897 return NULL;
4898 }
4899
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004900 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004901
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004902 return f;
4903}
4904
Mark Hammond08501372001-01-31 07:30:29 +00004905static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004906_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004907 HANDLE hStdin,
4908 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004909 HANDLE hStderr,
4910 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004911{
4912 PROCESS_INFORMATION piProcInfo;
4913 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004914 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004915 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004916 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004917 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004918 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004919
4920 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004921 char *comshell;
4922
Tim Peters92e4dd82002-10-05 01:47:34 +00004923 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004924 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004925 /* x < i, so x fits into an integer */
4926 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004927
4928 /* Explicitly check if we are using COMMAND.COM. If we are
4929 * then use the w9xpopen hack.
4930 */
4931 comshell = s1 + x;
4932 while (comshell >= s1 && *comshell != '\\')
4933 --comshell;
4934 ++comshell;
4935
4936 if (GetVersion() < 0x80000000 &&
4937 _stricmp(comshell, "command.com") != 0) {
4938 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004939 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004940 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004941 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004942 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004943 }
4944 else {
4945 /*
Tim Peters402d5982001-08-27 06:37:48 +00004946 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4947 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004948 */
Mark Hammond08501372001-01-31 07:30:29 +00004949 char modulepath[_MAX_PATH];
4950 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004951 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Martin v. Löwis26fd9602006-04-22 11:15:41 +00004952 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004953 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004954 x = i+1;
4955 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004956 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004957 strncat(modulepath,
4958 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004959 (sizeof(modulepath)/sizeof(modulepath[0]))
4960 -strlen(modulepath));
4961 if (stat(modulepath, &statinfo) != 0) {
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00004962 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
Tim Peters5aa91602002-01-30 05:46:57 +00004963 /* Eeek - file-not-found - possibly an embedding
4964 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004965 */
Tim Peters5aa91602002-01-30 05:46:57 +00004966 strncpy(modulepath,
4967 Py_GetExecPrefix(),
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00004968 mplen);
4969 modulepath[mplen-1] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004970 if (modulepath[strlen(modulepath)-1] != '\\')
4971 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004972 strncat(modulepath,
4973 szConsoleSpawn,
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00004974 mplen-strlen(modulepath));
Mark Hammond08501372001-01-31 07:30:29 +00004975 /* No where else to look - raise an easily identifiable
4976 error, rather than leaving Windows to report
4977 "file not found" - as the user is probably blissfully
4978 unaware this shim EXE is used, and it will confuse them.
4979 (well, it confused me for a while ;-)
4980 */
4981 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004982 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004983 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004984 "for popen to work with your shell "
4985 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004986 szConsoleSpawn);
4987 return FALSE;
4988 }
4989 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004990 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004991 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004992 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004993
Tim Peters92e4dd82002-10-05 01:47:34 +00004994 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004995 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004996 /* To maintain correct argument passing semantics,
4997 we pass the command-line as it stands, and allow
4998 quoting to be applied. w9xpopen.exe will then
4999 use its argv vector, and re-quote the necessary
5000 args for the ultimate child process.
5001 */
Tim Peters75cdad52001-11-28 22:07:30 +00005002 PyOS_snprintf(
5003 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00005004 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005005 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005006 s1,
5007 s3,
5008 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005009 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00005010 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005011 dialog:
5012 "Your program accessed mem currently in use at xxx"
5013 and a hopeful warning about the stability of your
5014 system.
5015 Cost is Ctrl+C wont kill children, but anyone
5016 who cares can have a go!
5017 */
5018 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005019 }
5020 }
5021
5022 /* Could be an else here to try cmd.exe / command.com in the path
5023 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00005024 else {
Tim Peters402d5982001-08-27 06:37:48 +00005025 PyErr_SetString(PyExc_RuntimeError,
5026 "Cannot locate a COMSPEC environment variable to "
5027 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00005028 return FALSE;
5029 }
Tim Peters5aa91602002-01-30 05:46:57 +00005030
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005031 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5032 siStartInfo.cb = sizeof(STARTUPINFO);
5033 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5034 siStartInfo.hStdInput = hStdin;
5035 siStartInfo.hStdOutput = hStdout;
5036 siStartInfo.hStdError = hStderr;
5037 siStartInfo.wShowWindow = SW_HIDE;
5038
5039 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005040 s2,
5041 NULL,
5042 NULL,
5043 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005044 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005045 NULL,
5046 NULL,
5047 &siStartInfo,
5048 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005049 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005050 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005051
Mark Hammondb37a3732000-08-14 04:47:33 +00005052 /* Return process handle */
5053 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005054 return TRUE;
5055 }
Tim Peters402d5982001-08-27 06:37:48 +00005056 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005057 return FALSE;
5058}
5059
5060/* The following code is based off of KB: Q190351 */
5061
5062static PyObject *
5063_PyPopen(char *cmdstring, int mode, int n)
5064{
5065 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5066 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00005067 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005068
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005069 SECURITY_ATTRIBUTES saAttr;
5070 BOOL fSuccess;
5071 int fd1, fd2, fd3;
5072 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00005073 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005074 PyObject *f;
5075
5076 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5077 saAttr.bInheritHandle = TRUE;
5078 saAttr.lpSecurityDescriptor = NULL;
5079
5080 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5081 return win32_error("CreatePipe", NULL);
5082
5083 /* Create new output read handle and the input write handle. Set
5084 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005085 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005086 * being created. */
5087 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005088 GetCurrentProcess(), &hChildStdinWrDup, 0,
5089 FALSE,
5090 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005091 if (!fSuccess)
5092 return win32_error("DuplicateHandle", NULL);
5093
5094 /* Close the inheritable version of ChildStdin
5095 that we're using. */
5096 CloseHandle(hChildStdinWr);
5097
5098 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5099 return win32_error("CreatePipe", NULL);
5100
5101 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005102 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5103 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005104 if (!fSuccess)
5105 return win32_error("DuplicateHandle", NULL);
5106
5107 /* Close the inheritable version of ChildStdout
5108 that we're using. */
5109 CloseHandle(hChildStdoutRd);
5110
5111 if (n != POPEN_4) {
5112 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5113 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005114 fSuccess = DuplicateHandle(GetCurrentProcess(),
5115 hChildStderrRd,
5116 GetCurrentProcess(),
5117 &hChildStderrRdDup, 0,
5118 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005119 if (!fSuccess)
5120 return win32_error("DuplicateHandle", NULL);
5121 /* Close the inheritable version of ChildStdErr that we're using. */
5122 CloseHandle(hChildStderrRd);
5123 }
Tim Peters5aa91602002-01-30 05:46:57 +00005124
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005125 switch (n) {
5126 case POPEN_1:
5127 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5128 case _O_WRONLY | _O_TEXT:
5129 /* Case for writing to child Stdin in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005130 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005131 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005132 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005133 PyFile_SetBufSize(f, 0);
5134 /* We don't care about these pipes anymore, so close them. */
5135 CloseHandle(hChildStdoutRdDup);
5136 CloseHandle(hChildStderrRdDup);
5137 break;
5138
5139 case _O_RDONLY | _O_TEXT:
5140 /* Case for reading from child Stdout in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005141 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005142 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005143 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005144 PyFile_SetBufSize(f, 0);
5145 /* We don't care about these pipes anymore, so close them. */
5146 CloseHandle(hChildStdinWrDup);
5147 CloseHandle(hChildStderrRdDup);
5148 break;
5149
5150 case _O_RDONLY | _O_BINARY:
5151 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005152 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005153 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005154 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005155 PyFile_SetBufSize(f, 0);
5156 /* We don't care about these pipes anymore, so close them. */
5157 CloseHandle(hChildStdinWrDup);
5158 CloseHandle(hChildStderrRdDup);
5159 break;
5160
5161 case _O_WRONLY | _O_BINARY:
5162 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005163 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005164 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005165 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005166 PyFile_SetBufSize(f, 0);
5167 /* We don't care about these pipes anymore, so close them. */
5168 CloseHandle(hChildStdoutRdDup);
5169 CloseHandle(hChildStderrRdDup);
5170 break;
5171 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005172 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005173 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005174
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005175 case POPEN_2:
5176 case POPEN_4:
5177 {
5178 char *m1, *m2;
5179 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005180
Tim Peters7dca21e2002-08-19 00:42:29 +00005181 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005182 m1 = "r";
5183 m2 = "w";
5184 } else {
5185 m1 = "rb";
5186 m2 = "wb";
5187 }
5188
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005189 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005190 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005191 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005192 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005193 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005194 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00005195 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005196 PyFile_SetBufSize(p2, 0);
5197
5198 if (n != 4)
5199 CloseHandle(hChildStderrRdDup);
5200
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005201 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00005202 Py_XDECREF(p1);
5203 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00005204 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005205 break;
5206 }
Tim Peters5aa91602002-01-30 05:46:57 +00005207
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005208 case POPEN_3:
5209 {
5210 char *m1, *m2;
5211 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005212
Tim Peters7dca21e2002-08-19 00:42:29 +00005213 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005214 m1 = "r";
5215 m2 = "w";
5216 } else {
5217 m1 = "rb";
5218 m2 = "wb";
5219 }
5220
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005221 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005222 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005223 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005224 f2 = _fdopen(fd2, m1);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005225 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005226 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005227 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00005228 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5229 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005230 PyFile_SetBufSize(p1, 0);
5231 PyFile_SetBufSize(p2, 0);
5232 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005233 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00005234 Py_XDECREF(p1);
5235 Py_XDECREF(p2);
5236 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00005237 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005238 break;
5239 }
5240 }
5241
5242 if (n == POPEN_4) {
5243 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005244 hChildStdinRd,
5245 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005246 hChildStdoutWr,
5247 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005248 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005249 }
5250 else {
5251 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005252 hChildStdinRd,
5253 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005254 hChildStderrWr,
5255 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005256 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005257 }
5258
Mark Hammondb37a3732000-08-14 04:47:33 +00005259 /*
5260 * Insert the files we've created into the process dictionary
5261 * all referencing the list with the process handle and the
5262 * initial number of files (see description below in _PyPclose).
5263 * Since if _PyPclose later tried to wait on a process when all
5264 * handles weren't closed, it could create a deadlock with the
5265 * child, we spend some energy here to try to ensure that we
5266 * either insert all file handles into the dictionary or none
5267 * at all. It's a little clumsy with the various popen modes
5268 * and variable number of files involved.
5269 */
5270 if (!_PyPopenProcs) {
5271 _PyPopenProcs = PyDict_New();
5272 }
5273
5274 if (_PyPopenProcs) {
5275 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5276 int ins_rc[3];
5277
5278 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5279 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
5280
5281 procObj = PyList_New(2);
5282 hProcessObj = PyLong_FromVoidPtr(hProcess);
5283 intObj = PyInt_FromLong(file_count);
5284
5285 if (procObj && hProcessObj && intObj) {
5286 PyList_SetItem(procObj,0,hProcessObj);
5287 PyList_SetItem(procObj,1,intObj);
5288
5289 fileObj[0] = PyLong_FromVoidPtr(f1);
5290 if (fileObj[0]) {
5291 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5292 fileObj[0],
5293 procObj);
5294 }
5295 if (file_count >= 2) {
5296 fileObj[1] = PyLong_FromVoidPtr(f2);
5297 if (fileObj[1]) {
5298 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5299 fileObj[1],
5300 procObj);
5301 }
5302 }
5303 if (file_count >= 3) {
5304 fileObj[2] = PyLong_FromVoidPtr(f3);
5305 if (fileObj[2]) {
5306 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5307 fileObj[2],
5308 procObj);
5309 }
5310 }
5311
5312 if (ins_rc[0] < 0 || !fileObj[0] ||
5313 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5314 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5315 /* Something failed - remove any dictionary
5316 * entries that did make it.
5317 */
5318 if (!ins_rc[0] && fileObj[0]) {
5319 PyDict_DelItem(_PyPopenProcs,
5320 fileObj[0]);
5321 }
5322 if (!ins_rc[1] && fileObj[1]) {
5323 PyDict_DelItem(_PyPopenProcs,
5324 fileObj[1]);
5325 }
5326 if (!ins_rc[2] && fileObj[2]) {
5327 PyDict_DelItem(_PyPopenProcs,
5328 fileObj[2]);
5329 }
5330 }
5331 }
Tim Peters5aa91602002-01-30 05:46:57 +00005332
Mark Hammondb37a3732000-08-14 04:47:33 +00005333 /*
5334 * Clean up our localized references for the dictionary keys
5335 * and value since PyDict_SetItem will Py_INCREF any copies
5336 * that got placed in the dictionary.
5337 */
5338 Py_XDECREF(procObj);
5339 Py_XDECREF(fileObj[0]);
5340 Py_XDECREF(fileObj[1]);
5341 Py_XDECREF(fileObj[2]);
5342 }
5343
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005344 /* Child is launched. Close the parents copy of those pipe
5345 * handles that only the child should have open. You need to
5346 * make sure that no handles to the write end of the output pipe
5347 * are maintained in this process or else the pipe will not close
5348 * when the child process exits and the ReadFile will hang. */
5349
5350 if (!CloseHandle(hChildStdinRd))
5351 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005352
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005353 if (!CloseHandle(hChildStdoutWr))
5354 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005355
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005356 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5357 return win32_error("CloseHandle", NULL);
5358
5359 return f;
5360}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005361
5362/*
5363 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5364 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005365 *
5366 * This function uses the _PyPopenProcs dictionary in order to map the
5367 * input file pointer to information about the process that was
5368 * originally created by the popen* call that created the file pointer.
5369 * The dictionary uses the file pointer as a key (with one entry
5370 * inserted for each file returned by the original popen* call) and a
5371 * single list object as the value for all files from a single call.
5372 * The list object contains the Win32 process handle at [0], and a file
5373 * count at [1], which is initialized to the total number of file
5374 * handles using that list.
5375 *
5376 * This function closes whichever handle it is passed, and decrements
5377 * the file count in the dictionary for the process handle pointed to
5378 * by this file. On the last close (when the file count reaches zero),
5379 * this function will wait for the child process and then return its
5380 * exit code as the result of the close() operation. This permits the
5381 * files to be closed in any order - it is always the close() of the
5382 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005383 *
5384 * NOTE: This function is currently called with the GIL released.
5385 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005386 */
Tim Peters736aa322000-09-01 06:51:24 +00005387
Fredrik Lundh56055a42000-07-23 19:47:12 +00005388static int _PyPclose(FILE *file)
5389{
Fredrik Lundh20318932000-07-26 17:29:12 +00005390 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005391 DWORD exit_code;
5392 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00005393 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5394 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005395#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005396 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005397#endif
5398
Fredrik Lundh20318932000-07-26 17:29:12 +00005399 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00005400 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00005401 */
5402 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005403#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005404 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005405#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005406 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005407 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5408 (procObj = PyDict_GetItem(_PyPopenProcs,
5409 fileObj)) != NULL &&
5410 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5411 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5412
5413 hProcess = PyLong_AsVoidPtr(hProcessObj);
5414 file_count = PyInt_AsLong(intObj);
5415
5416 if (file_count > 1) {
5417 /* Still other files referencing process */
5418 file_count--;
5419 PyList_SetItem(procObj,1,
5420 PyInt_FromLong(file_count));
5421 } else {
5422 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00005423 if (result != EOF &&
5424 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5425 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00005426 /* Possible truncation here in 16-bit environments, but
5427 * real exit codes are just the lower byte in any event.
5428 */
5429 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005430 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00005431 /* Indicate failure - this will cause the file object
5432 * to raise an I/O error and translate the last Win32
5433 * error code from errno. We do have a problem with
5434 * last errors that overlap the normal errno table,
5435 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005436 */
Fredrik Lundh20318932000-07-26 17:29:12 +00005437 if (result != EOF) {
5438 /* If the error wasn't from the fclose(), then
5439 * set errno for the file object error handling.
5440 */
5441 errno = GetLastError();
5442 }
5443 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005444 }
5445
5446 /* Free up the native handle at this point */
5447 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00005448 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005449
Mark Hammondb37a3732000-08-14 04:47:33 +00005450 /* Remove this file pointer from dictionary */
5451 PyDict_DelItem(_PyPopenProcs, fileObj);
5452
5453 if (PyDict_Size(_PyPopenProcs) == 0) {
5454 Py_DECREF(_PyPopenProcs);
5455 _PyPopenProcs = NULL;
5456 }
5457
5458 } /* if object retrieval ok */
5459
5460 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005461 } /* if _PyPopenProcs */
5462
Tim Peters736aa322000-09-01 06:51:24 +00005463#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005464 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005465#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005466 return result;
5467}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005468
5469#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005470static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005471posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005472{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005473 char *name;
5474 char *mode = "r";
5475 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00005476 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005477 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005478 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00005479 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00005480 /* Strip mode of binary or text modifiers */
5481 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5482 mode = "r";
5483 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5484 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00005485 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005486 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005487 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00005488 if (fp == NULL)
5489 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005490 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005491 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005492 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005493 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005494}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005495
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005496#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005497#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005498
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005499
Guido van Rossumb6775db1994-08-01 11:34:53 +00005500#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005501PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005502"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005503Set the current process's user id.");
5504
Barry Warsaw53699e91996-12-10 23:23:01 +00005505static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005506posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005507{
5508 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005509 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005510 return NULL;
5511 if (setuid(uid) < 0)
5512 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005513 Py_INCREF(Py_None);
5514 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005515}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005516#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005517
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005518
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005519#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005520PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005521"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005522Set the current process's effective user id.");
5523
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005524static PyObject *
5525posix_seteuid (PyObject *self, PyObject *args)
5526{
5527 int euid;
5528 if (!PyArg_ParseTuple(args, "i", &euid)) {
5529 return NULL;
5530 } else if (seteuid(euid) < 0) {
5531 return posix_error();
5532 } else {
5533 Py_INCREF(Py_None);
5534 return Py_None;
5535 }
5536}
5537#endif /* HAVE_SETEUID */
5538
5539#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005540PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005541"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005542Set the current process's effective group id.");
5543
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005544static PyObject *
5545posix_setegid (PyObject *self, PyObject *args)
5546{
5547 int egid;
5548 if (!PyArg_ParseTuple(args, "i", &egid)) {
5549 return NULL;
5550 } else if (setegid(egid) < 0) {
5551 return posix_error();
5552 } else {
5553 Py_INCREF(Py_None);
5554 return Py_None;
5555 }
5556}
5557#endif /* HAVE_SETEGID */
5558
5559#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005560PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005561"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005562Set the current process's real and effective user ids.");
5563
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005564static PyObject *
5565posix_setreuid (PyObject *self, PyObject *args)
5566{
5567 int ruid, euid;
5568 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
5569 return NULL;
5570 } else if (setreuid(ruid, euid) < 0) {
5571 return posix_error();
5572 } else {
5573 Py_INCREF(Py_None);
5574 return Py_None;
5575 }
5576}
5577#endif /* HAVE_SETREUID */
5578
5579#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005580PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005581"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005582Set the current process's real and effective group ids.");
5583
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005584static PyObject *
5585posix_setregid (PyObject *self, PyObject *args)
5586{
5587 int rgid, egid;
5588 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
5589 return NULL;
5590 } else if (setregid(rgid, egid) < 0) {
5591 return posix_error();
5592 } else {
5593 Py_INCREF(Py_None);
5594 return Py_None;
5595 }
5596}
5597#endif /* HAVE_SETREGID */
5598
Guido van Rossumb6775db1994-08-01 11:34:53 +00005599#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005600PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005601"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005602Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005603
Barry Warsaw53699e91996-12-10 23:23:01 +00005604static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005605posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005606{
5607 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005608 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005609 return NULL;
5610 if (setgid(gid) < 0)
5611 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005612 Py_INCREF(Py_None);
5613 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005614}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005615#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005616
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005617#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005618PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005619"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005620Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005621
5622static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005623posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005624{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005625 int i, len;
5626 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005627
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005628 if (!PySequence_Check(groups)) {
5629 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5630 return NULL;
5631 }
5632 len = PySequence_Size(groups);
5633 if (len > MAX_GROUPS) {
5634 PyErr_SetString(PyExc_ValueError, "too many groups");
5635 return NULL;
5636 }
5637 for(i = 0; i < len; i++) {
5638 PyObject *elem;
5639 elem = PySequence_GetItem(groups, i);
5640 if (!elem)
5641 return NULL;
5642 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005643 if (!PyLong_Check(elem)) {
5644 PyErr_SetString(PyExc_TypeError,
5645 "groups must be integers");
5646 Py_DECREF(elem);
5647 return NULL;
5648 } else {
5649 unsigned long x = PyLong_AsUnsignedLong(elem);
5650 if (PyErr_Occurred()) {
5651 PyErr_SetString(PyExc_TypeError,
5652 "group id too big");
5653 Py_DECREF(elem);
5654 return NULL;
5655 }
5656 grouplist[i] = x;
5657 /* read back the value to see if it fitted in gid_t */
5658 if (grouplist[i] != x) {
5659 PyErr_SetString(PyExc_TypeError,
5660 "group id too big");
5661 Py_DECREF(elem);
5662 return NULL;
5663 }
5664 }
5665 } else {
5666 long x = PyInt_AsLong(elem);
5667 grouplist[i] = x;
5668 if (grouplist[i] != x) {
5669 PyErr_SetString(PyExc_TypeError,
5670 "group id too big");
5671 Py_DECREF(elem);
5672 return NULL;
5673 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005674 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005675 Py_DECREF(elem);
5676 }
5677
5678 if (setgroups(len, grouplist) < 0)
5679 return posix_error();
5680 Py_INCREF(Py_None);
5681 return Py_None;
5682}
5683#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005684
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005685#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005686static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00005687wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00005688{
5689 PyObject *result;
5690 static PyObject *struct_rusage;
5691
5692 if (pid == -1)
5693 return posix_error();
5694
5695 if (struct_rusage == NULL) {
Christian Heimes000a0742008-01-03 22:16:32 +00005696 PyObject *m = PyImport_ImportModuleNoBlock("resource");
Neal Norwitz05a45592006-03-20 06:30:08 +00005697 if (m == NULL)
5698 return NULL;
5699 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5700 Py_DECREF(m);
5701 if (struct_rusage == NULL)
5702 return NULL;
5703 }
5704
5705 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5706 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5707 if (!result)
5708 return NULL;
5709
5710#ifndef doubletime
5711#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5712#endif
5713
5714 PyStructSequence_SET_ITEM(result, 0,
5715 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5716 PyStructSequence_SET_ITEM(result, 1,
5717 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5718#define SET_INT(result, index, value)\
5719 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5720 SET_INT(result, 2, ru->ru_maxrss);
5721 SET_INT(result, 3, ru->ru_ixrss);
5722 SET_INT(result, 4, ru->ru_idrss);
5723 SET_INT(result, 5, ru->ru_isrss);
5724 SET_INT(result, 6, ru->ru_minflt);
5725 SET_INT(result, 7, ru->ru_majflt);
5726 SET_INT(result, 8, ru->ru_nswap);
5727 SET_INT(result, 9, ru->ru_inblock);
5728 SET_INT(result, 10, ru->ru_oublock);
5729 SET_INT(result, 11, ru->ru_msgsnd);
5730 SET_INT(result, 12, ru->ru_msgrcv);
5731 SET_INT(result, 13, ru->ru_nsignals);
5732 SET_INT(result, 14, ru->ru_nvcsw);
5733 SET_INT(result, 15, ru->ru_nivcsw);
5734#undef SET_INT
5735
5736 if (PyErr_Occurred()) {
5737 Py_DECREF(result);
5738 return NULL;
5739 }
5740
Neal Norwitz9b00a562006-03-20 08:47:12 +00005741 return Py_BuildValue("iiN", pid, status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005742}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005743#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005744
5745#ifdef HAVE_WAIT3
5746PyDoc_STRVAR(posix_wait3__doc__,
5747"wait3(options) -> (pid, status, rusage)\n\n\
5748Wait for completion of a child process.");
5749
5750static PyObject *
5751posix_wait3(PyObject *self, PyObject *args)
5752{
Christian Heimesd491d712008-02-01 18:49:26 +00005753 pid_t pid;
5754 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005755 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005756 WAIT_TYPE status;
5757 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005758
5759 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5760 return NULL;
5761
5762 Py_BEGIN_ALLOW_THREADS
5763 pid = wait3(&status, options, &ru);
5764 Py_END_ALLOW_THREADS
5765
Neal Norwitzd5a37542006-03-20 06:48:34 +00005766 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005767}
5768#endif /* HAVE_WAIT3 */
5769
5770#ifdef HAVE_WAIT4
5771PyDoc_STRVAR(posix_wait4__doc__,
5772"wait4(pid, options) -> (pid, status, rusage)\n\n\
5773Wait for completion of a given child process.");
5774
5775static PyObject *
5776posix_wait4(PyObject *self, PyObject *args)
5777{
Christian Heimesd491d712008-02-01 18:49:26 +00005778 pid_t pid;
5779 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005780 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005781 WAIT_TYPE status;
5782 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005783
5784 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5785 return NULL;
5786
5787 Py_BEGIN_ALLOW_THREADS
5788 pid = wait4(pid, &status, options, &ru);
5789 Py_END_ALLOW_THREADS
5790
Neal Norwitzd5a37542006-03-20 06:48:34 +00005791 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005792}
5793#endif /* HAVE_WAIT4 */
5794
Guido van Rossumb6775db1994-08-01 11:34:53 +00005795#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005796PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005797"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005798Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005799
Barry Warsaw53699e91996-12-10 23:23:01 +00005800static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005801posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005802{
Christian Heimesd491d712008-02-01 18:49:26 +00005803 pid_t pid;
5804 int options;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005805 WAIT_TYPE status;
5806 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005807
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005808 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005809 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005810 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005811 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005812 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005813 if (pid == -1)
5814 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005815
5816 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005817}
5818
Tim Petersab034fa2002-02-01 11:27:43 +00005819#elif defined(HAVE_CWAIT)
5820
5821/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005822PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005823"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005824"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005825
5826static PyObject *
5827posix_waitpid(PyObject *self, PyObject *args)
5828{
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005829 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005830 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005831
5832 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5833 return NULL;
5834 Py_BEGIN_ALLOW_THREADS
5835 pid = _cwait(&status, pid, options);
5836 Py_END_ALLOW_THREADS
5837 if (pid == -1)
5838 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005839
5840 /* shift the status left a byte so this is more like the POSIX waitpid */
5841 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005842}
5843#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005844
Guido van Rossumad0ee831995-03-01 10:34:45 +00005845#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005846PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005847"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005848Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005849
Barry Warsaw53699e91996-12-10 23:23:01 +00005850static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005851posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005852{
Christian Heimesd491d712008-02-01 18:49:26 +00005853 pid_t pid;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005854 WAIT_TYPE status;
5855 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005856
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005857 Py_BEGIN_ALLOW_THREADS
5858 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005859 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005860 if (pid == -1)
5861 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005862
5863 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005864}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005865#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005866
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005867
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005868PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005869"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005870Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005871
Barry Warsaw53699e91996-12-10 23:23:01 +00005872static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005873posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005874{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005875#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005876 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005877#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005878#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005879 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005880#else
5881 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5882#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005883#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005884}
5885
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005886
Guido van Rossumb6775db1994-08-01 11:34:53 +00005887#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005888PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005889"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005890Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005891
Barry Warsaw53699e91996-12-10 23:23:01 +00005892static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005893posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005894{
Ronald Oussoren10168f22006-10-22 10:45:18 +00005895 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005896 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005897 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005898 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00005899#ifdef Py_USING_UNICODE
5900 int arg_is_unicode = 0;
5901#endif
5902
5903 if (!PyArg_ParseTuple(args, "et:readlink",
5904 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005905 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00005906#ifdef Py_USING_UNICODE
5907 v = PySequence_GetItem(args, 0);
Neal Norwitz91a57212007-08-12 17:11:13 +00005908 if (v == NULL) {
5909 PyMem_Free(path);
5910 return NULL;
5911 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00005912
5913 if (PyUnicode_Check(v)) {
5914 arg_is_unicode = 1;
5915 }
5916 Py_DECREF(v);
5917#endif
5918
Barry Warsaw53699e91996-12-10 23:23:01 +00005919 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005920 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005921 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005922 if (n < 0)
Neal Norwitz91a57212007-08-12 17:11:13 +00005923 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00005924
Neal Norwitz91a57212007-08-12 17:11:13 +00005925 PyMem_Free(path);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00005926 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00005927#ifdef Py_USING_UNICODE
5928 if (arg_is_unicode) {
5929 PyObject *w;
5930
5931 w = PyUnicode_FromEncodedObject(v,
5932 Py_FileSystemDefaultEncoding,
5933 "strict");
5934 if (w != NULL) {
5935 Py_DECREF(v);
5936 v = w;
5937 }
5938 else {
5939 /* fall back to the original byte string, as
5940 discussed in patch #683592 */
5941 PyErr_Clear();
5942 }
5943 }
5944#endif
5945 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005946}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005947#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005948
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005949
Guido van Rossumb6775db1994-08-01 11:34:53 +00005950#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005951PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005952"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005953Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005954
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005955static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005956posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005957{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00005958 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005959}
5960#endif /* HAVE_SYMLINK */
5961
5962
5963#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00005964#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5965static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005966system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005967{
5968 ULONG value = 0;
5969
5970 Py_BEGIN_ALLOW_THREADS
5971 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5972 Py_END_ALLOW_THREADS
5973
5974 return value;
5975}
5976
5977static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005978posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005979{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005980 /* Currently Only Uptime is Provided -- Others Later */
5981 return Py_BuildValue("ddddd",
5982 (double)0 /* t.tms_utime / HZ */,
5983 (double)0 /* t.tms_stime / HZ */,
5984 (double)0 /* t.tms_cutime / HZ */,
5985 (double)0 /* t.tms_cstime / HZ */,
5986 (double)system_uptime() / 1000);
5987}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005988#else /* not OS2 */
Martin v. Löwis3f15ae32008-12-29 18:20:48 +00005989#define NEED_TICKS_PER_SECOND
5990static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00005991static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005992posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005993{
5994 struct tms t;
5995 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005996 errno = 0;
5997 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005998 if (c == (clock_t) -1)
5999 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006000 return Py_BuildValue("ddddd",
Martin v. Löwis3f15ae32008-12-29 18:20:48 +00006001 (double)t.tms_utime / ticks_per_second,
6002 (double)t.tms_stime / ticks_per_second,
6003 (double)t.tms_cutime / ticks_per_second,
6004 (double)t.tms_cstime / ticks_per_second,
6005 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006006}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006007#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006008#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006009
6010
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006011#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006012#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006013static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006014posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006015{
6016 FILETIME create, exit, kernel, user;
6017 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006018 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006019 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6020 /* The fields of a FILETIME structure are the hi and lo part
6021 of a 64-bit value expressed in 100 nanosecond units.
6022 1e7 is one second in such units; 1e-7 the inverse.
6023 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6024 */
Barry Warsaw53699e91996-12-10 23:23:01 +00006025 return Py_BuildValue(
6026 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006027 (double)(user.dwHighDateTime*429.4967296 +
6028 user.dwLowDateTime*1e-7),
Georg Brandl0a40ffb2008-02-13 07:20:22 +00006029 (double)(kernel.dwHighDateTime*429.4967296 +
6030 kernel.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00006031 (double)0,
6032 (double)0,
6033 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006034}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006035#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006036
6037#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006038PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006039"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006040Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006041#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006042
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006043
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006044#ifdef HAVE_GETSID
6045PyDoc_STRVAR(posix_getsid__doc__,
6046"getsid(pid) -> sid\n\n\
6047Call the system call getsid().");
6048
6049static PyObject *
6050posix_getsid(PyObject *self, PyObject *args)
6051{
Christian Heimesd491d712008-02-01 18:49:26 +00006052 pid_t pid;
6053 int sid;
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006054 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
6055 return NULL;
6056 sid = getsid(pid);
6057 if (sid < 0)
6058 return posix_error();
6059 return PyInt_FromLong((long)sid);
6060}
6061#endif /* HAVE_GETSID */
6062
6063
Guido van Rossumb6775db1994-08-01 11:34:53 +00006064#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006065PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006066"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006067Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006068
Barry Warsaw53699e91996-12-10 23:23:01 +00006069static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006070posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006071{
Guido van Rossum687dd131993-05-17 08:34:16 +00006072 if (setsid() < 0)
6073 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006074 Py_INCREF(Py_None);
6075 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006076}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006077#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006078
Guido van Rossumb6775db1994-08-01 11:34:53 +00006079#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006080PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006081"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006082Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006083
Barry Warsaw53699e91996-12-10 23:23:01 +00006084static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006085posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006086{
Christian Heimesd491d712008-02-01 18:49:26 +00006087 pid_t pid;
6088 int pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006089 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00006090 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006091 if (setpgid(pid, pgrp) < 0)
6092 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006093 Py_INCREF(Py_None);
6094 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006095}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006096#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006097
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006098
Guido van Rossumb6775db1994-08-01 11:34:53 +00006099#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006100PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006101"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006102Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006103
Barry Warsaw53699e91996-12-10 23:23:01 +00006104static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006105posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006106{
Christian Heimese6a80742008-02-03 19:51:13 +00006107 int fd;
6108 pid_t pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006109 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006110 return NULL;
6111 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006112 if (pgid < 0)
6113 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006114 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006115}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006116#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006117
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006118
Guido van Rossumb6775db1994-08-01 11:34:53 +00006119#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006120PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006121"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006122Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006123
Barry Warsaw53699e91996-12-10 23:23:01 +00006124static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006125posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006126{
6127 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006128 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006129 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006130 if (tcsetpgrp(fd, pgid) < 0)
6131 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00006132 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00006133 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006134}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006135#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006136
Guido van Rossum687dd131993-05-17 08:34:16 +00006137/* Functions acting on file descriptors */
6138
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006139PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006140"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006141Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006142
Barry Warsaw53699e91996-12-10 23:23:01 +00006143static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006144posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006145{
Mark Hammondef8b6542001-05-13 08:04:26 +00006146 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006147 int flag;
6148 int mode = 0777;
6149 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006150
6151#ifdef MS_WINDOWS
6152 if (unicode_file_names()) {
6153 PyUnicodeObject *po;
6154 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6155 Py_BEGIN_ALLOW_THREADS
6156 /* PyUnicode_AS_UNICODE OK without thread
6157 lock as it is a simple dereference. */
6158 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6159 Py_END_ALLOW_THREADS
6160 if (fd < 0)
6161 return posix_error();
6162 return PyInt_FromLong((long)fd);
6163 }
6164 /* Drop the argument parsing error as narrow strings
6165 are also valid. */
6166 PyErr_Clear();
6167 }
6168#endif
6169
Tim Peters5aa91602002-01-30 05:46:57 +00006170 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00006171 Py_FileSystemDefaultEncoding, &file,
6172 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00006173 return NULL;
6174
Barry Warsaw53699e91996-12-10 23:23:01 +00006175 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006176 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00006177 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006178 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00006179 return posix_error_with_allocated_filename(file);
6180 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00006181 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006182}
6183
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006184
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006185PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006186"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006187Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006188
Barry Warsaw53699e91996-12-10 23:23:01 +00006189static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006190posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006191{
6192 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006193 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006194 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006195 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006196 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006197 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006198 if (res < 0)
6199 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006200 Py_INCREF(Py_None);
6201 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006202}
6203
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006204
Georg Brandl309501a2008-01-19 20:22:13 +00006205PyDoc_STRVAR(posix_closerange__doc__,
6206"closerange(fd_low, fd_high)\n\n\
6207Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6208
6209static PyObject *
6210posix_closerange(PyObject *self, PyObject *args)
6211{
6212 int fd_from, fd_to, i;
6213 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6214 return NULL;
6215 Py_BEGIN_ALLOW_THREADS
6216 for (i = fd_from; i < fd_to; i++)
6217 close(i);
6218 Py_END_ALLOW_THREADS
6219 Py_RETURN_NONE;
6220}
6221
6222
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006223PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006224"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006225Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006226
Barry Warsaw53699e91996-12-10 23:23:01 +00006227static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006228posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006229{
6230 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006231 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006232 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006233 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006234 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006235 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006236 if (fd < 0)
6237 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006238 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006239}
6240
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006241
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006242PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006243"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006244Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006245
Barry Warsaw53699e91996-12-10 23:23:01 +00006246static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006247posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006248{
6249 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006250 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00006251 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006252 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006253 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00006254 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006255 if (res < 0)
6256 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006257 Py_INCREF(Py_None);
6258 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006259}
6260
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006261
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006262PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006263"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006264Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006265
Barry Warsaw53699e91996-12-10 23:23:01 +00006266static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006267posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006268{
6269 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006270#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006271 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006272#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00006273 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006274#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006275 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006276 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00006277 return NULL;
6278#ifdef SEEK_SET
6279 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6280 switch (how) {
6281 case 0: how = SEEK_SET; break;
6282 case 1: how = SEEK_CUR; break;
6283 case 2: how = SEEK_END; break;
6284 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006285#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006286
6287#if !defined(HAVE_LARGEFILE_SUPPORT)
6288 pos = PyInt_AsLong(posobj);
6289#else
6290 pos = PyLong_Check(posobj) ?
6291 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
6292#endif
6293 if (PyErr_Occurred())
6294 return NULL;
6295
Barry Warsaw53699e91996-12-10 23:23:01 +00006296 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006297#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00006298 res = _lseeki64(fd, pos, how);
6299#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006300 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006301#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006302 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006303 if (res < 0)
6304 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006305
6306#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00006307 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006308#else
6309 return PyLong_FromLongLong(res);
6310#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006311}
6312
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006313
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006314PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006315"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006316Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006317
Barry Warsaw53699e91996-12-10 23:23:01 +00006318static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006319posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006320{
Guido van Rossum8bac5461996-06-11 18:38:48 +00006321 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00006322 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006323 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00006324 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00006325 if (size < 0) {
6326 errno = EINVAL;
6327 return posix_error();
6328 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006329 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006330 if (buffer == NULL)
6331 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006332 Py_BEGIN_ALLOW_THREADS
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006333 n = read(fd, PyString_AsString(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00006334 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00006335 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006336 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00006337 return posix_error();
6338 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00006339 if (n != size)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006340 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00006341 return buffer;
6342}
6343
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006344
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006345PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006346"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006347Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006348
Barry Warsaw53699e91996-12-10 23:23:01 +00006349static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006350posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006351{
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006352 Py_buffer pbuf;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006353 int fd;
6354 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006355
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006356 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
Guido van Rossum687dd131993-05-17 08:34:16 +00006357 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006358 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006359 size = write(fd, pbuf.buf, (size_t)pbuf.len);
Barry Warsaw53699e91996-12-10 23:23:01 +00006360 Py_END_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006361 PyBuffer_Release(&pbuf);
Guido van Rossum687dd131993-05-17 08:34:16 +00006362 if (size < 0)
6363 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006364 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006365}
6366
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006367
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006368PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006369"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006370Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006371
Barry Warsaw53699e91996-12-10 23:23:01 +00006372static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006373posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006374{
6375 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00006376 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00006377 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006378 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006379 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006380#ifdef __VMS
6381 /* on OpenVMS we must ensure that all bytes are written to the file */
6382 fsync(fd);
6383#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006384 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00006385 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00006386 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00006387 if (res != 0) {
6388#ifdef MS_WINDOWS
6389 return win32_error("fstat", NULL);
6390#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006391 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006392#endif
6393 }
Tim Peters5aa91602002-01-30 05:46:57 +00006394
Martin v. Löwis14694662006-02-03 12:54:16 +00006395 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006396}
6397
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006398
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006399PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006400"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006401Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006402
Barry Warsaw53699e91996-12-10 23:23:01 +00006403static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006404posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006405{
Guido van Rossum687dd131993-05-17 08:34:16 +00006406 int fd;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006407 char *orgmode = "r";
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006408 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00006409 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00006410 PyObject *f;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006411 char *mode;
6412 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00006413 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006414
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006415 /* Sanitize mode. See fileobject.c */
6416 mode = PyMem_MALLOC(strlen(orgmode)+3);
6417 if (!mode) {
6418 PyErr_NoMemory();
6419 return NULL;
6420 }
6421 strcpy(mode, orgmode);
6422 if (_PyFile_SanitizeMode(mode)) {
6423 PyMem_FREE(mode);
Thomas Heller1f043e22002-11-07 16:00:59 +00006424 return NULL;
6425 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006426 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006427#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Georg Brandl54a188a2006-03-31 20:00:11 +00006428 if (mode[0] == 'a') {
6429 /* try to make sure the O_APPEND flag is set */
6430 int flags;
6431 flags = fcntl(fd, F_GETFL);
6432 if (flags != -1)
6433 fcntl(fd, F_SETFL, flags | O_APPEND);
6434 fp = fdopen(fd, mode);
Thomas Wouters2a9a6b02006-03-31 22:38:19 +00006435 if (fp == NULL && flags != -1)
Georg Brandl54a188a2006-03-31 20:00:11 +00006436 /* restore old mode if fdopen failed */
6437 fcntl(fd, F_SETFL, flags);
6438 } else {
6439 fp = fdopen(fd, mode);
6440 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006441#else
6442 fp = fdopen(fd, mode);
6443#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006444 Py_END_ALLOW_THREADS
Neal Norwitzd83eb312007-05-02 04:47:55 +00006445 PyMem_FREE(mode);
Guido van Rossum687dd131993-05-17 08:34:16 +00006446 if (fp == NULL)
6447 return posix_error();
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006448 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006449 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00006450 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006451 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006452}
6453
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006454PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006455"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006456Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006457connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006458
6459static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006460posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006461{
6462 int fd;
6463 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6464 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006465 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006466}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006467
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006468#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006469PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006470"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006471Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006472
Barry Warsaw53699e91996-12-10 23:23:01 +00006473static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006474posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006475{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006476#if defined(PYOS_OS2)
6477 HFILE read, write;
6478 APIRET rc;
6479
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006480 Py_BEGIN_ALLOW_THREADS
6481 rc = DosCreatePipe( &read, &write, 4096);
6482 Py_END_ALLOW_THREADS
6483 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006484 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006485
6486 return Py_BuildValue("(ii)", read, write);
6487#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006488#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00006489 int fds[2];
6490 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00006491 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006492 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00006493 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006494 if (res != 0)
6495 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006496 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006497#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00006498 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006499 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00006500 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00006501 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006502 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00006503 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00006504 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006505 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00006506 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6507 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006508 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006509#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006510#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006511}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006512#endif /* HAVE_PIPE */
6513
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006514
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006515#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006516PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006517"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006518Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006519
Barry Warsaw53699e91996-12-10 23:23:01 +00006520static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006521posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006522{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006523 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006524 int mode = 0666;
6525 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006526 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006527 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006528 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006529 res = mkfifo(filename, mode);
6530 Py_END_ALLOW_THREADS
6531 if (res < 0)
6532 return posix_error();
6533 Py_INCREF(Py_None);
6534 return Py_None;
6535}
6536#endif
6537
6538
Neal Norwitz11690112002-07-30 01:08:28 +00006539#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006540PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006541"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006542Create a filesystem node (file, device special file or named pipe)\n\
6543named filename. mode specifies both the permissions to use and the\n\
6544type of node to be created, being combined (bitwise OR) with one of\n\
6545S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006546device defines the newly created device special file (probably using\n\
6547os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006548
6549
6550static PyObject *
6551posix_mknod(PyObject *self, PyObject *args)
6552{
6553 char *filename;
6554 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006555 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006556 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00006557 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006558 return NULL;
6559 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006560 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00006561 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006562 if (res < 0)
6563 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006564 Py_INCREF(Py_None);
6565 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006566}
6567#endif
6568
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006569#ifdef HAVE_DEVICE_MACROS
6570PyDoc_STRVAR(posix_major__doc__,
6571"major(device) -> major number\n\
6572Extracts a device major number from a raw device number.");
6573
6574static PyObject *
6575posix_major(PyObject *self, PyObject *args)
6576{
6577 int device;
6578 if (!PyArg_ParseTuple(args, "i:major", &device))
6579 return NULL;
6580 return PyInt_FromLong((long)major(device));
6581}
6582
6583PyDoc_STRVAR(posix_minor__doc__,
6584"minor(device) -> minor number\n\
6585Extracts a device minor number from a raw device number.");
6586
6587static PyObject *
6588posix_minor(PyObject *self, PyObject *args)
6589{
6590 int device;
6591 if (!PyArg_ParseTuple(args, "i:minor", &device))
6592 return NULL;
6593 return PyInt_FromLong((long)minor(device));
6594}
6595
6596PyDoc_STRVAR(posix_makedev__doc__,
6597"makedev(major, minor) -> device number\n\
6598Composes a raw device number from the major and minor device numbers.");
6599
6600static PyObject *
6601posix_makedev(PyObject *self, PyObject *args)
6602{
6603 int major, minor;
6604 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6605 return NULL;
6606 return PyInt_FromLong((long)makedev(major, minor));
6607}
6608#endif /* device macros */
6609
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006610
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006611#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006612PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006613"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006614Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006615
Barry Warsaw53699e91996-12-10 23:23:01 +00006616static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006617posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006618{
6619 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006620 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006621 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006622 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006623
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006624 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006625 return NULL;
6626
6627#if !defined(HAVE_LARGEFILE_SUPPORT)
6628 length = PyInt_AsLong(lenobj);
6629#else
6630 length = PyLong_Check(lenobj) ?
6631 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6632#endif
6633 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006634 return NULL;
6635
Barry Warsaw53699e91996-12-10 23:23:01 +00006636 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006637 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006638 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006639 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006640 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006641 return NULL;
6642 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006643 Py_INCREF(Py_None);
6644 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006645}
6646#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006647
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006648#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006649PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006650"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006651Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006652
Fred Drake762e2061999-08-26 17:23:54 +00006653/* Save putenv() parameters as values here, so we can collect them when they
6654 * get re-set with another call for the same key. */
6655static PyObject *posix_putenv_garbage;
6656
Tim Peters5aa91602002-01-30 05:46:57 +00006657static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006658posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006659{
6660 char *s1, *s2;
Anthony Baxter64182fe2006-04-11 12:14:09 +00006661 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006662 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006663 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006664
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006665 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006666 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006667
6668#if defined(PYOS_OS2)
6669 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6670 APIRET rc;
6671
Guido van Rossumd48f2521997-12-05 22:19:34 +00006672 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6673 if (rc != NO_ERROR)
6674 return os2_error(rc);
6675
6676 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6677 APIRET rc;
6678
Guido van Rossumd48f2521997-12-05 22:19:34 +00006679 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6680 if (rc != NO_ERROR)
6681 return os2_error(rc);
6682 } else {
6683#endif
6684
Fred Drake762e2061999-08-26 17:23:54 +00006685 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006686 len = strlen(s1) + strlen(s2) + 2;
6687 /* len includes space for a trailing \0; the size arg to
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006688 PyString_FromStringAndSize does not count that */
6689 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006690 if (newstr == NULL)
6691 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006692 newenv = PyString_AS_STRING(newstr);
Anthony Baxter64182fe2006-04-11 12:14:09 +00006693 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6694 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006695 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006696 posix_error();
6697 return NULL;
6698 }
Fred Drake762e2061999-08-26 17:23:54 +00006699 /* Install the first arg and newstr in posix_putenv_garbage;
6700 * this will cause previous value to be collected. This has to
6701 * happen after the real putenv() call because the old value
6702 * was still accessible until then. */
6703 if (PyDict_SetItem(posix_putenv_garbage,
6704 PyTuple_GET_ITEM(args, 0), newstr)) {
6705 /* really not much we can do; just leak */
6706 PyErr_Clear();
6707 }
6708 else {
6709 Py_DECREF(newstr);
6710 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006711
6712#if defined(PYOS_OS2)
6713 }
6714#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006715 Py_INCREF(Py_None);
6716 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006717}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006718#endif /* putenv */
6719
Guido van Rossumc524d952001-10-19 01:31:59 +00006720#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006721PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006722"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006723Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006724
6725static PyObject *
6726posix_unsetenv(PyObject *self, PyObject *args)
6727{
6728 char *s1;
6729
6730 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6731 return NULL;
6732
6733 unsetenv(s1);
6734
6735 /* Remove the key from posix_putenv_garbage;
6736 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006737 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006738 * old value was still accessible until then.
6739 */
6740 if (PyDict_DelItem(posix_putenv_garbage,
6741 PyTuple_GET_ITEM(args, 0))) {
6742 /* really not much we can do; just leak */
6743 PyErr_Clear();
6744 }
6745
6746 Py_INCREF(Py_None);
6747 return Py_None;
6748}
6749#endif /* unsetenv */
6750
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006751PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006752"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006753Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006754
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006755static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006756posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006757{
6758 int code;
6759 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006760 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006761 return NULL;
6762 message = strerror(code);
6763 if (message == NULL) {
6764 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006765 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006766 return NULL;
6767 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006768 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006769}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006770
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006771
Guido van Rossumc9641791998-08-04 15:26:23 +00006772#ifdef HAVE_SYS_WAIT_H
6773
Fred Drake106c1a02002-04-23 15:58:02 +00006774#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006775PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006776"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006777Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006778
6779static PyObject *
6780posix_WCOREDUMP(PyObject *self, PyObject *args)
6781{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006782 WAIT_TYPE status;
6783 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006784
Neal Norwitzd5a37542006-03-20 06:48:34 +00006785 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006786 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006787
6788 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006789}
6790#endif /* WCOREDUMP */
6791
6792#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006793PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006794"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006795Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006796job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006797
6798static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006799posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006800{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006801 WAIT_TYPE status;
6802 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006803
Neal Norwitzd5a37542006-03-20 06:48:34 +00006804 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006805 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006806
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006807 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006808}
6809#endif /* WIFCONTINUED */
6810
Guido van Rossumc9641791998-08-04 15:26:23 +00006811#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006812PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006813"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006814Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006815
6816static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006817posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006818{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006819 WAIT_TYPE status;
6820 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006821
Neal Norwitzd5a37542006-03-20 06:48:34 +00006822 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006823 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006824
Fred Drake106c1a02002-04-23 15:58:02 +00006825 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006826}
6827#endif /* WIFSTOPPED */
6828
6829#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006830PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006831"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006832Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006833
6834static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006835posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006836{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006837 WAIT_TYPE status;
6838 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006839
Neal Norwitzd5a37542006-03-20 06:48:34 +00006840 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006841 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006842
Fred Drake106c1a02002-04-23 15:58:02 +00006843 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006844}
6845#endif /* WIFSIGNALED */
6846
6847#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006848PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006849"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006850Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006851system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006852
6853static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006854posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006855{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006856 WAIT_TYPE status;
6857 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006858
Neal Norwitzd5a37542006-03-20 06:48:34 +00006859 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006860 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006861
Fred Drake106c1a02002-04-23 15:58:02 +00006862 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006863}
6864#endif /* WIFEXITED */
6865
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006866#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006867PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006868"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006869Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006870
6871static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006872posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006873{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006874 WAIT_TYPE status;
6875 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006876
Neal Norwitzd5a37542006-03-20 06:48:34 +00006877 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006878 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006879
Guido van Rossumc9641791998-08-04 15:26:23 +00006880 return Py_BuildValue("i", WEXITSTATUS(status));
6881}
6882#endif /* WEXITSTATUS */
6883
6884#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006885PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006886"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006887Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006888value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006889
6890static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006891posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006892{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006893 WAIT_TYPE status;
6894 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006895
Neal Norwitzd5a37542006-03-20 06:48:34 +00006896 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006897 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006898
Guido van Rossumc9641791998-08-04 15:26:23 +00006899 return Py_BuildValue("i", WTERMSIG(status));
6900}
6901#endif /* WTERMSIG */
6902
6903#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006904PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006905"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006906Return the signal that stopped the process that provided\n\
6907the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006908
6909static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006910posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006911{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006912 WAIT_TYPE status;
6913 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006914
Neal Norwitzd5a37542006-03-20 06:48:34 +00006915 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006916 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006917
Guido van Rossumc9641791998-08-04 15:26:23 +00006918 return Py_BuildValue("i", WSTOPSIG(status));
6919}
6920#endif /* WSTOPSIG */
6921
6922#endif /* HAVE_SYS_WAIT_H */
6923
6924
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006925#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006926#ifdef _SCO_DS
6927/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6928 needed definitions in sys/statvfs.h */
6929#define _SVID3
6930#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006931#include <sys/statvfs.h>
6932
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006933static PyObject*
6934_pystatvfs_fromstructstatvfs(struct statvfs st) {
6935 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6936 if (v == NULL)
6937 return NULL;
6938
6939#if !defined(HAVE_LARGEFILE_SUPPORT)
6940 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6941 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6942 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6943 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6944 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6945 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6946 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6947 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6948 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6949 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6950#else
6951 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6952 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006953 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006954 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006955 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006956 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006957 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006958 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006959 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006960 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006961 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006962 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006963 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006964 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006965 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6966 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6967#endif
6968
6969 return v;
6970}
6971
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006972PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006973"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006974Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006975
6976static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006977posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006978{
6979 int fd, res;
6980 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006981
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006982 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006983 return NULL;
6984 Py_BEGIN_ALLOW_THREADS
6985 res = fstatvfs(fd, &st);
6986 Py_END_ALLOW_THREADS
6987 if (res != 0)
6988 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006989
6990 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006991}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006992#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006993
6994
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006995#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006996#include <sys/statvfs.h>
6997
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006998PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006999"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007000Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007001
7002static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007003posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007004{
7005 char *path;
7006 int res;
7007 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007008 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00007009 return NULL;
7010 Py_BEGIN_ALLOW_THREADS
7011 res = statvfs(path, &st);
7012 Py_END_ALLOW_THREADS
7013 if (res != 0)
7014 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007015
7016 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007017}
7018#endif /* HAVE_STATVFS */
7019
7020
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007021#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007022PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007023"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007024Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007025The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007026or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007027
7028static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007029posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007030{
7031 PyObject *result = NULL;
7032 char *dir = NULL;
7033 char *pfx = NULL;
7034 char *name;
7035
7036 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
7037 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007038
7039 if (PyErr_Warn(PyExc_RuntimeWarning,
7040 "tempnam is a potential security risk to your program") < 0)
7041 return NULL;
7042
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007043#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007044 name = _tempnam(dir, pfx);
7045#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007046 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007047#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007048 if (name == NULL)
7049 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007050 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007051 free(name);
7052 return result;
7053}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007054#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007055
7056
7057#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007058PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007059"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007060Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007061
7062static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007063posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007064{
7065 FILE *fp;
7066
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007067 fp = tmpfile();
7068 if (fp == NULL)
7069 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007070 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007071}
7072#endif
7073
7074
7075#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007076PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007077"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007078Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007079
7080static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007081posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007082{
7083 char buffer[L_tmpnam];
7084 char *name;
7085
Skip Montanaro95618b52001-08-18 18:52:10 +00007086 if (PyErr_Warn(PyExc_RuntimeWarning,
7087 "tmpnam is a potential security risk to your program") < 0)
7088 return NULL;
7089
Greg Wardb48bc172000-03-01 21:51:56 +00007090#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007091 name = tmpnam_r(buffer);
7092#else
7093 name = tmpnam(buffer);
7094#endif
7095 if (name == NULL) {
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007096 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007097#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007098 "unexpected NULL from tmpnam_r"
7099#else
7100 "unexpected NULL from tmpnam"
7101#endif
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007102 );
7103 PyErr_SetObject(PyExc_OSError, err);
7104 Py_XDECREF(err);
7105 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007106 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007107 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007108}
7109#endif
7110
7111
Fred Drakec9680921999-12-13 16:37:25 +00007112/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7113 * It maps strings representing configuration variable names to
7114 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007115 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007116 * rarely-used constants. There are three separate tables that use
7117 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007118 *
7119 * This code is always included, even if none of the interfaces that
7120 * need it are included. The #if hackery needed to avoid it would be
7121 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007122 */
7123struct constdef {
7124 char *name;
7125 long value;
7126};
7127
Fred Drake12c6e2d1999-12-14 21:25:03 +00007128static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007129conv_confname(PyObject *arg, int *valuep, struct constdef *table,
7130 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007131{
7132 if (PyInt_Check(arg)) {
7133 *valuep = PyInt_AS_LONG(arg);
7134 return 1;
7135 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007136 if (PyString_Check(arg)) {
Fred Drake12c6e2d1999-12-14 21:25:03 +00007137 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00007138 size_t lo = 0;
7139 size_t mid;
7140 size_t hi = tablesize;
7141 int cmp;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007142 char *confname = PyString_AS_STRING(arg);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007143 while (lo < hi) {
7144 mid = (lo + hi) / 2;
7145 cmp = strcmp(confname, table[mid].name);
7146 if (cmp < 0)
7147 hi = mid;
7148 else if (cmp > 0)
7149 lo = mid + 1;
7150 else {
7151 *valuep = table[mid].value;
7152 return 1;
7153 }
7154 }
7155 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
7156 }
7157 else
7158 PyErr_SetString(PyExc_TypeError,
7159 "configuration names must be strings or integers");
7160 return 0;
7161}
7162
7163
7164#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7165static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007166#ifdef _PC_ABI_AIO_XFER_MAX
7167 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
7168#endif
7169#ifdef _PC_ABI_ASYNC_IO
7170 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
7171#endif
Fred Drakec9680921999-12-13 16:37:25 +00007172#ifdef _PC_ASYNC_IO
7173 {"PC_ASYNC_IO", _PC_ASYNC_IO},
7174#endif
7175#ifdef _PC_CHOWN_RESTRICTED
7176 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
7177#endif
7178#ifdef _PC_FILESIZEBITS
7179 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
7180#endif
7181#ifdef _PC_LAST
7182 {"PC_LAST", _PC_LAST},
7183#endif
7184#ifdef _PC_LINK_MAX
7185 {"PC_LINK_MAX", _PC_LINK_MAX},
7186#endif
7187#ifdef _PC_MAX_CANON
7188 {"PC_MAX_CANON", _PC_MAX_CANON},
7189#endif
7190#ifdef _PC_MAX_INPUT
7191 {"PC_MAX_INPUT", _PC_MAX_INPUT},
7192#endif
7193#ifdef _PC_NAME_MAX
7194 {"PC_NAME_MAX", _PC_NAME_MAX},
7195#endif
7196#ifdef _PC_NO_TRUNC
7197 {"PC_NO_TRUNC", _PC_NO_TRUNC},
7198#endif
7199#ifdef _PC_PATH_MAX
7200 {"PC_PATH_MAX", _PC_PATH_MAX},
7201#endif
7202#ifdef _PC_PIPE_BUF
7203 {"PC_PIPE_BUF", _PC_PIPE_BUF},
7204#endif
7205#ifdef _PC_PRIO_IO
7206 {"PC_PRIO_IO", _PC_PRIO_IO},
7207#endif
7208#ifdef _PC_SOCK_MAXBUF
7209 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
7210#endif
7211#ifdef _PC_SYNC_IO
7212 {"PC_SYNC_IO", _PC_SYNC_IO},
7213#endif
7214#ifdef _PC_VDISABLE
7215 {"PC_VDISABLE", _PC_VDISABLE},
7216#endif
7217};
7218
Fred Drakec9680921999-12-13 16:37:25 +00007219static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007220conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007221{
7222 return conv_confname(arg, valuep, posix_constants_pathconf,
7223 sizeof(posix_constants_pathconf)
7224 / sizeof(struct constdef));
7225}
7226#endif
7227
7228#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007229PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007230"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007231Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007232If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007233
7234static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007235posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007236{
7237 PyObject *result = NULL;
7238 int name, fd;
7239
Fred Drake12c6e2d1999-12-14 21:25:03 +00007240 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7241 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00007242 long limit;
7243
7244 errno = 0;
7245 limit = fpathconf(fd, name);
7246 if (limit == -1 && errno != 0)
7247 posix_error();
7248 else
7249 result = PyInt_FromLong(limit);
7250 }
7251 return result;
7252}
7253#endif
7254
7255
7256#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007257PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007258"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007259Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007260If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007261
7262static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007263posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007264{
7265 PyObject *result = NULL;
7266 int name;
7267 char *path;
7268
7269 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7270 conv_path_confname, &name)) {
7271 long limit;
7272
7273 errno = 0;
7274 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007275 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00007276 if (errno == EINVAL)
7277 /* could be a path or name problem */
7278 posix_error();
7279 else
7280 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007281 }
Fred Drakec9680921999-12-13 16:37:25 +00007282 else
7283 result = PyInt_FromLong(limit);
7284 }
7285 return result;
7286}
7287#endif
7288
7289#ifdef HAVE_CONFSTR
7290static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007291#ifdef _CS_ARCHITECTURE
7292 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
7293#endif
7294#ifdef _CS_HOSTNAME
7295 {"CS_HOSTNAME", _CS_HOSTNAME},
7296#endif
7297#ifdef _CS_HW_PROVIDER
7298 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
7299#endif
7300#ifdef _CS_HW_SERIAL
7301 {"CS_HW_SERIAL", _CS_HW_SERIAL},
7302#endif
7303#ifdef _CS_INITTAB_NAME
7304 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
7305#endif
Fred Drakec9680921999-12-13 16:37:25 +00007306#ifdef _CS_LFS64_CFLAGS
7307 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
7308#endif
7309#ifdef _CS_LFS64_LDFLAGS
7310 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
7311#endif
7312#ifdef _CS_LFS64_LIBS
7313 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
7314#endif
7315#ifdef _CS_LFS64_LINTFLAGS
7316 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
7317#endif
7318#ifdef _CS_LFS_CFLAGS
7319 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
7320#endif
7321#ifdef _CS_LFS_LDFLAGS
7322 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
7323#endif
7324#ifdef _CS_LFS_LIBS
7325 {"CS_LFS_LIBS", _CS_LFS_LIBS},
7326#endif
7327#ifdef _CS_LFS_LINTFLAGS
7328 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
7329#endif
Fred Draked86ed291999-12-15 15:34:33 +00007330#ifdef _CS_MACHINE
7331 {"CS_MACHINE", _CS_MACHINE},
7332#endif
Fred Drakec9680921999-12-13 16:37:25 +00007333#ifdef _CS_PATH
7334 {"CS_PATH", _CS_PATH},
7335#endif
Fred Draked86ed291999-12-15 15:34:33 +00007336#ifdef _CS_RELEASE
7337 {"CS_RELEASE", _CS_RELEASE},
7338#endif
7339#ifdef _CS_SRPC_DOMAIN
7340 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
7341#endif
7342#ifdef _CS_SYSNAME
7343 {"CS_SYSNAME", _CS_SYSNAME},
7344#endif
7345#ifdef _CS_VERSION
7346 {"CS_VERSION", _CS_VERSION},
7347#endif
Fred Drakec9680921999-12-13 16:37:25 +00007348#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
7349 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
7350#endif
7351#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
7352 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
7353#endif
7354#ifdef _CS_XBS5_ILP32_OFF32_LIBS
7355 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
7356#endif
7357#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
7358 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
7359#endif
7360#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
7361 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
7362#endif
7363#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
7364 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
7365#endif
7366#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
7367 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
7368#endif
7369#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
7370 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
7371#endif
7372#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7373 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
7374#endif
7375#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7376 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7377#endif
7378#ifdef _CS_XBS5_LP64_OFF64_LIBS
7379 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7380#endif
7381#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7382 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7383#endif
7384#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7385 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7386#endif
7387#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7388 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7389#endif
7390#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7391 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7392#endif
7393#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7394 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7395#endif
Fred Draked86ed291999-12-15 15:34:33 +00007396#ifdef _MIPS_CS_AVAIL_PROCESSORS
7397 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7398#endif
7399#ifdef _MIPS_CS_BASE
7400 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7401#endif
7402#ifdef _MIPS_CS_HOSTID
7403 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7404#endif
7405#ifdef _MIPS_CS_HW_NAME
7406 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7407#endif
7408#ifdef _MIPS_CS_NUM_PROCESSORS
7409 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7410#endif
7411#ifdef _MIPS_CS_OSREL_MAJ
7412 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7413#endif
7414#ifdef _MIPS_CS_OSREL_MIN
7415 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7416#endif
7417#ifdef _MIPS_CS_OSREL_PATCH
7418 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7419#endif
7420#ifdef _MIPS_CS_OS_NAME
7421 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7422#endif
7423#ifdef _MIPS_CS_OS_PROVIDER
7424 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7425#endif
7426#ifdef _MIPS_CS_PROCESSORS
7427 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7428#endif
7429#ifdef _MIPS_CS_SERIAL
7430 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7431#endif
7432#ifdef _MIPS_CS_VENDOR
7433 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7434#endif
Fred Drakec9680921999-12-13 16:37:25 +00007435};
7436
7437static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007438conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007439{
7440 return conv_confname(arg, valuep, posix_constants_confstr,
7441 sizeof(posix_constants_confstr)
7442 / sizeof(struct constdef));
7443}
7444
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007445PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007446"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007447Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007448
7449static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007450posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007451{
7452 PyObject *result = NULL;
7453 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007454 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007455
7456 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Skip Montanarodd527fc2006-04-18 00:49:49 +00007457 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007458
Fred Drakec9680921999-12-13 16:37:25 +00007459 errno = 0;
Skip Montanarodd527fc2006-04-18 00:49:49 +00007460 len = confstr(name, buffer, sizeof(buffer));
Skip Montanaro94785ef2006-04-20 01:29:48 +00007461 if (len == 0) {
7462 if (errno) {
7463 posix_error();
7464 }
7465 else {
7466 result = Py_None;
7467 Py_INCREF(Py_None);
7468 }
Fred Drakec9680921999-12-13 16:37:25 +00007469 }
7470 else {
Neal Norwitz0d21b1e2006-04-20 06:44:42 +00007471 if ((unsigned int)len >= sizeof(buffer)) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007472 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007473 if (result != NULL)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007474 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00007475 }
7476 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007477 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007478 }
7479 }
7480 return result;
7481}
7482#endif
7483
7484
7485#ifdef HAVE_SYSCONF
7486static struct constdef posix_constants_sysconf[] = {
7487#ifdef _SC_2_CHAR_TERM
7488 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7489#endif
7490#ifdef _SC_2_C_BIND
7491 {"SC_2_C_BIND", _SC_2_C_BIND},
7492#endif
7493#ifdef _SC_2_C_DEV
7494 {"SC_2_C_DEV", _SC_2_C_DEV},
7495#endif
7496#ifdef _SC_2_C_VERSION
7497 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7498#endif
7499#ifdef _SC_2_FORT_DEV
7500 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7501#endif
7502#ifdef _SC_2_FORT_RUN
7503 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7504#endif
7505#ifdef _SC_2_LOCALEDEF
7506 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7507#endif
7508#ifdef _SC_2_SW_DEV
7509 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7510#endif
7511#ifdef _SC_2_UPE
7512 {"SC_2_UPE", _SC_2_UPE},
7513#endif
7514#ifdef _SC_2_VERSION
7515 {"SC_2_VERSION", _SC_2_VERSION},
7516#endif
Fred Draked86ed291999-12-15 15:34:33 +00007517#ifdef _SC_ABI_ASYNCHRONOUS_IO
7518 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7519#endif
7520#ifdef _SC_ACL
7521 {"SC_ACL", _SC_ACL},
7522#endif
Fred Drakec9680921999-12-13 16:37:25 +00007523#ifdef _SC_AIO_LISTIO_MAX
7524 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7525#endif
Fred Drakec9680921999-12-13 16:37:25 +00007526#ifdef _SC_AIO_MAX
7527 {"SC_AIO_MAX", _SC_AIO_MAX},
7528#endif
7529#ifdef _SC_AIO_PRIO_DELTA_MAX
7530 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7531#endif
7532#ifdef _SC_ARG_MAX
7533 {"SC_ARG_MAX", _SC_ARG_MAX},
7534#endif
7535#ifdef _SC_ASYNCHRONOUS_IO
7536 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7537#endif
7538#ifdef _SC_ATEXIT_MAX
7539 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7540#endif
Fred Draked86ed291999-12-15 15:34:33 +00007541#ifdef _SC_AUDIT
7542 {"SC_AUDIT", _SC_AUDIT},
7543#endif
Fred Drakec9680921999-12-13 16:37:25 +00007544#ifdef _SC_AVPHYS_PAGES
7545 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7546#endif
7547#ifdef _SC_BC_BASE_MAX
7548 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7549#endif
7550#ifdef _SC_BC_DIM_MAX
7551 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7552#endif
7553#ifdef _SC_BC_SCALE_MAX
7554 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7555#endif
7556#ifdef _SC_BC_STRING_MAX
7557 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7558#endif
Fred Draked86ed291999-12-15 15:34:33 +00007559#ifdef _SC_CAP
7560 {"SC_CAP", _SC_CAP},
7561#endif
Fred Drakec9680921999-12-13 16:37:25 +00007562#ifdef _SC_CHARCLASS_NAME_MAX
7563 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7564#endif
7565#ifdef _SC_CHAR_BIT
7566 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7567#endif
7568#ifdef _SC_CHAR_MAX
7569 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7570#endif
7571#ifdef _SC_CHAR_MIN
7572 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7573#endif
7574#ifdef _SC_CHILD_MAX
7575 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7576#endif
7577#ifdef _SC_CLK_TCK
7578 {"SC_CLK_TCK", _SC_CLK_TCK},
7579#endif
7580#ifdef _SC_COHER_BLKSZ
7581 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7582#endif
7583#ifdef _SC_COLL_WEIGHTS_MAX
7584 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7585#endif
7586#ifdef _SC_DCACHE_ASSOC
7587 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7588#endif
7589#ifdef _SC_DCACHE_BLKSZ
7590 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7591#endif
7592#ifdef _SC_DCACHE_LINESZ
7593 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7594#endif
7595#ifdef _SC_DCACHE_SZ
7596 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7597#endif
7598#ifdef _SC_DCACHE_TBLKSZ
7599 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7600#endif
7601#ifdef _SC_DELAYTIMER_MAX
7602 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7603#endif
7604#ifdef _SC_EQUIV_CLASS_MAX
7605 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7606#endif
7607#ifdef _SC_EXPR_NEST_MAX
7608 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7609#endif
7610#ifdef _SC_FSYNC
7611 {"SC_FSYNC", _SC_FSYNC},
7612#endif
7613#ifdef _SC_GETGR_R_SIZE_MAX
7614 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7615#endif
7616#ifdef _SC_GETPW_R_SIZE_MAX
7617 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7618#endif
7619#ifdef _SC_ICACHE_ASSOC
7620 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7621#endif
7622#ifdef _SC_ICACHE_BLKSZ
7623 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7624#endif
7625#ifdef _SC_ICACHE_LINESZ
7626 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7627#endif
7628#ifdef _SC_ICACHE_SZ
7629 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7630#endif
Fred Draked86ed291999-12-15 15:34:33 +00007631#ifdef _SC_INF
7632 {"SC_INF", _SC_INF},
7633#endif
Fred Drakec9680921999-12-13 16:37:25 +00007634#ifdef _SC_INT_MAX
7635 {"SC_INT_MAX", _SC_INT_MAX},
7636#endif
7637#ifdef _SC_INT_MIN
7638 {"SC_INT_MIN", _SC_INT_MIN},
7639#endif
7640#ifdef _SC_IOV_MAX
7641 {"SC_IOV_MAX", _SC_IOV_MAX},
7642#endif
Fred Draked86ed291999-12-15 15:34:33 +00007643#ifdef _SC_IP_SECOPTS
7644 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7645#endif
Fred Drakec9680921999-12-13 16:37:25 +00007646#ifdef _SC_JOB_CONTROL
7647 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7648#endif
Fred Draked86ed291999-12-15 15:34:33 +00007649#ifdef _SC_KERN_POINTERS
7650 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7651#endif
7652#ifdef _SC_KERN_SIM
7653 {"SC_KERN_SIM", _SC_KERN_SIM},
7654#endif
Fred Drakec9680921999-12-13 16:37:25 +00007655#ifdef _SC_LINE_MAX
7656 {"SC_LINE_MAX", _SC_LINE_MAX},
7657#endif
7658#ifdef _SC_LOGIN_NAME_MAX
7659 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7660#endif
7661#ifdef _SC_LOGNAME_MAX
7662 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7663#endif
7664#ifdef _SC_LONG_BIT
7665 {"SC_LONG_BIT", _SC_LONG_BIT},
7666#endif
Fred Draked86ed291999-12-15 15:34:33 +00007667#ifdef _SC_MAC
7668 {"SC_MAC", _SC_MAC},
7669#endif
Fred Drakec9680921999-12-13 16:37:25 +00007670#ifdef _SC_MAPPED_FILES
7671 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7672#endif
7673#ifdef _SC_MAXPID
7674 {"SC_MAXPID", _SC_MAXPID},
7675#endif
7676#ifdef _SC_MB_LEN_MAX
7677 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7678#endif
7679#ifdef _SC_MEMLOCK
7680 {"SC_MEMLOCK", _SC_MEMLOCK},
7681#endif
7682#ifdef _SC_MEMLOCK_RANGE
7683 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7684#endif
7685#ifdef _SC_MEMORY_PROTECTION
7686 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7687#endif
7688#ifdef _SC_MESSAGE_PASSING
7689 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7690#endif
Fred Draked86ed291999-12-15 15:34:33 +00007691#ifdef _SC_MMAP_FIXED_ALIGNMENT
7692 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7693#endif
Fred Drakec9680921999-12-13 16:37:25 +00007694#ifdef _SC_MQ_OPEN_MAX
7695 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7696#endif
7697#ifdef _SC_MQ_PRIO_MAX
7698 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7699#endif
Fred Draked86ed291999-12-15 15:34:33 +00007700#ifdef _SC_NACLS_MAX
7701 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7702#endif
Fred Drakec9680921999-12-13 16:37:25 +00007703#ifdef _SC_NGROUPS_MAX
7704 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7705#endif
7706#ifdef _SC_NL_ARGMAX
7707 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7708#endif
7709#ifdef _SC_NL_LANGMAX
7710 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7711#endif
7712#ifdef _SC_NL_MSGMAX
7713 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7714#endif
7715#ifdef _SC_NL_NMAX
7716 {"SC_NL_NMAX", _SC_NL_NMAX},
7717#endif
7718#ifdef _SC_NL_SETMAX
7719 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7720#endif
7721#ifdef _SC_NL_TEXTMAX
7722 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7723#endif
7724#ifdef _SC_NPROCESSORS_CONF
7725 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7726#endif
7727#ifdef _SC_NPROCESSORS_ONLN
7728 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7729#endif
Fred Draked86ed291999-12-15 15:34:33 +00007730#ifdef _SC_NPROC_CONF
7731 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7732#endif
7733#ifdef _SC_NPROC_ONLN
7734 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7735#endif
Fred Drakec9680921999-12-13 16:37:25 +00007736#ifdef _SC_NZERO
7737 {"SC_NZERO", _SC_NZERO},
7738#endif
7739#ifdef _SC_OPEN_MAX
7740 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7741#endif
7742#ifdef _SC_PAGESIZE
7743 {"SC_PAGESIZE", _SC_PAGESIZE},
7744#endif
7745#ifdef _SC_PAGE_SIZE
7746 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7747#endif
7748#ifdef _SC_PASS_MAX
7749 {"SC_PASS_MAX", _SC_PASS_MAX},
7750#endif
7751#ifdef _SC_PHYS_PAGES
7752 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7753#endif
7754#ifdef _SC_PII
7755 {"SC_PII", _SC_PII},
7756#endif
7757#ifdef _SC_PII_INTERNET
7758 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7759#endif
7760#ifdef _SC_PII_INTERNET_DGRAM
7761 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7762#endif
7763#ifdef _SC_PII_INTERNET_STREAM
7764 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7765#endif
7766#ifdef _SC_PII_OSI
7767 {"SC_PII_OSI", _SC_PII_OSI},
7768#endif
7769#ifdef _SC_PII_OSI_CLTS
7770 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7771#endif
7772#ifdef _SC_PII_OSI_COTS
7773 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7774#endif
7775#ifdef _SC_PII_OSI_M
7776 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7777#endif
7778#ifdef _SC_PII_SOCKET
7779 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7780#endif
7781#ifdef _SC_PII_XTI
7782 {"SC_PII_XTI", _SC_PII_XTI},
7783#endif
7784#ifdef _SC_POLL
7785 {"SC_POLL", _SC_POLL},
7786#endif
7787#ifdef _SC_PRIORITIZED_IO
7788 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7789#endif
7790#ifdef _SC_PRIORITY_SCHEDULING
7791 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7792#endif
7793#ifdef _SC_REALTIME_SIGNALS
7794 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7795#endif
7796#ifdef _SC_RE_DUP_MAX
7797 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7798#endif
7799#ifdef _SC_RTSIG_MAX
7800 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7801#endif
7802#ifdef _SC_SAVED_IDS
7803 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7804#endif
7805#ifdef _SC_SCHAR_MAX
7806 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7807#endif
7808#ifdef _SC_SCHAR_MIN
7809 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7810#endif
7811#ifdef _SC_SELECT
7812 {"SC_SELECT", _SC_SELECT},
7813#endif
7814#ifdef _SC_SEMAPHORES
7815 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7816#endif
7817#ifdef _SC_SEM_NSEMS_MAX
7818 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7819#endif
7820#ifdef _SC_SEM_VALUE_MAX
7821 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7822#endif
7823#ifdef _SC_SHARED_MEMORY_OBJECTS
7824 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7825#endif
7826#ifdef _SC_SHRT_MAX
7827 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7828#endif
7829#ifdef _SC_SHRT_MIN
7830 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7831#endif
7832#ifdef _SC_SIGQUEUE_MAX
7833 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7834#endif
7835#ifdef _SC_SIGRT_MAX
7836 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7837#endif
7838#ifdef _SC_SIGRT_MIN
7839 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7840#endif
Fred Draked86ed291999-12-15 15:34:33 +00007841#ifdef _SC_SOFTPOWER
7842 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7843#endif
Fred Drakec9680921999-12-13 16:37:25 +00007844#ifdef _SC_SPLIT_CACHE
7845 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7846#endif
7847#ifdef _SC_SSIZE_MAX
7848 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7849#endif
7850#ifdef _SC_STACK_PROT
7851 {"SC_STACK_PROT", _SC_STACK_PROT},
7852#endif
7853#ifdef _SC_STREAM_MAX
7854 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7855#endif
7856#ifdef _SC_SYNCHRONIZED_IO
7857 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7858#endif
7859#ifdef _SC_THREADS
7860 {"SC_THREADS", _SC_THREADS},
7861#endif
7862#ifdef _SC_THREAD_ATTR_STACKADDR
7863 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7864#endif
7865#ifdef _SC_THREAD_ATTR_STACKSIZE
7866 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7867#endif
7868#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7869 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7870#endif
7871#ifdef _SC_THREAD_KEYS_MAX
7872 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7873#endif
7874#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7875 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7876#endif
7877#ifdef _SC_THREAD_PRIO_INHERIT
7878 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7879#endif
7880#ifdef _SC_THREAD_PRIO_PROTECT
7881 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7882#endif
7883#ifdef _SC_THREAD_PROCESS_SHARED
7884 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7885#endif
7886#ifdef _SC_THREAD_SAFE_FUNCTIONS
7887 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7888#endif
7889#ifdef _SC_THREAD_STACK_MIN
7890 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7891#endif
7892#ifdef _SC_THREAD_THREADS_MAX
7893 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7894#endif
7895#ifdef _SC_TIMERS
7896 {"SC_TIMERS", _SC_TIMERS},
7897#endif
7898#ifdef _SC_TIMER_MAX
7899 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7900#endif
7901#ifdef _SC_TTY_NAME_MAX
7902 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7903#endif
7904#ifdef _SC_TZNAME_MAX
7905 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7906#endif
7907#ifdef _SC_T_IOV_MAX
7908 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7909#endif
7910#ifdef _SC_UCHAR_MAX
7911 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7912#endif
7913#ifdef _SC_UINT_MAX
7914 {"SC_UINT_MAX", _SC_UINT_MAX},
7915#endif
7916#ifdef _SC_UIO_MAXIOV
7917 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7918#endif
7919#ifdef _SC_ULONG_MAX
7920 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7921#endif
7922#ifdef _SC_USHRT_MAX
7923 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7924#endif
7925#ifdef _SC_VERSION
7926 {"SC_VERSION", _SC_VERSION},
7927#endif
7928#ifdef _SC_WORD_BIT
7929 {"SC_WORD_BIT", _SC_WORD_BIT},
7930#endif
7931#ifdef _SC_XBS5_ILP32_OFF32
7932 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7933#endif
7934#ifdef _SC_XBS5_ILP32_OFFBIG
7935 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7936#endif
7937#ifdef _SC_XBS5_LP64_OFF64
7938 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7939#endif
7940#ifdef _SC_XBS5_LPBIG_OFFBIG
7941 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7942#endif
7943#ifdef _SC_XOPEN_CRYPT
7944 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7945#endif
7946#ifdef _SC_XOPEN_ENH_I18N
7947 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7948#endif
7949#ifdef _SC_XOPEN_LEGACY
7950 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7951#endif
7952#ifdef _SC_XOPEN_REALTIME
7953 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7954#endif
7955#ifdef _SC_XOPEN_REALTIME_THREADS
7956 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7957#endif
7958#ifdef _SC_XOPEN_SHM
7959 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7960#endif
7961#ifdef _SC_XOPEN_UNIX
7962 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7963#endif
7964#ifdef _SC_XOPEN_VERSION
7965 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7966#endif
7967#ifdef _SC_XOPEN_XCU_VERSION
7968 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7969#endif
7970#ifdef _SC_XOPEN_XPG2
7971 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7972#endif
7973#ifdef _SC_XOPEN_XPG3
7974 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7975#endif
7976#ifdef _SC_XOPEN_XPG4
7977 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7978#endif
7979};
7980
7981static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007982conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007983{
7984 return conv_confname(arg, valuep, posix_constants_sysconf,
7985 sizeof(posix_constants_sysconf)
7986 / sizeof(struct constdef));
7987}
7988
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007989PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007990"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007991Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007992
7993static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007994posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007995{
7996 PyObject *result = NULL;
7997 int name;
7998
7999 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
8000 int value;
8001
8002 errno = 0;
8003 value = sysconf(name);
8004 if (value == -1 && errno != 0)
8005 posix_error();
8006 else
8007 result = PyInt_FromLong(value);
8008 }
8009 return result;
8010}
8011#endif
8012
8013
Fred Drakebec628d1999-12-15 18:31:10 +00008014/* This code is used to ensure that the tables of configuration value names
8015 * are in sorted order as required by conv_confname(), and also to build the
8016 * the exported dictionaries that are used to publish information about the
8017 * names available on the host platform.
8018 *
8019 * Sorting the table at runtime ensures that the table is properly ordered
8020 * when used, even for platforms we're not able to test on. It also makes
8021 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008022 */
Fred Drakebec628d1999-12-15 18:31:10 +00008023
8024static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008025cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008026{
8027 const struct constdef *c1 =
8028 (const struct constdef *) v1;
8029 const struct constdef *c2 =
8030 (const struct constdef *) v2;
8031
8032 return strcmp(c1->name, c2->name);
8033}
8034
8035static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008036setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008037 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008038{
Fred Drakebec628d1999-12-15 18:31:10 +00008039 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008040 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008041
8042 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8043 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008044 if (d == NULL)
8045 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008046
Barry Warsaw3155db32000-04-13 15:20:40 +00008047 for (i=0; i < tablesize; ++i) {
8048 PyObject *o = PyInt_FromLong(table[i].value);
8049 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8050 Py_XDECREF(o);
8051 Py_DECREF(d);
8052 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008053 }
Barry Warsaw3155db32000-04-13 15:20:40 +00008054 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008055 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008056 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008057}
8058
Fred Drakebec628d1999-12-15 18:31:10 +00008059/* Return -1 on failure, 0 on success. */
8060static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008061setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008062{
8063#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008064 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008065 sizeof(posix_constants_pathconf)
8066 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008067 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008068 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008069#endif
8070#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008071 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008072 sizeof(posix_constants_confstr)
8073 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008074 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008075 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008076#endif
8077#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008078 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008079 sizeof(posix_constants_sysconf)
8080 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008081 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008082 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008083#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008084 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008085}
Fred Draked86ed291999-12-15 15:34:33 +00008086
8087
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008088PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008089"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008090Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008091in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008092
8093static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008094posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008095{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008096 abort();
8097 /*NOTREACHED*/
8098 Py_FatalError("abort() called from Python code didn't abort!");
8099 return NULL;
8100}
Fred Drakebec628d1999-12-15 18:31:10 +00008101
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008102#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008103PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008104"startfile(filepath [, operation]) - Start a file with its associated\n\
8105application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008106\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008107When \"operation\" is not specified or \"open\", this acts like\n\
8108double-clicking the file in Explorer, or giving the file name as an\n\
8109argument to the DOS \"start\" command: the file is opened with whatever\n\
8110application (if any) its extension is associated.\n\
8111When another \"operation\" is given, it specifies what should be done with\n\
8112the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008113\n\
8114startfile returns as soon as the associated application is launched.\n\
8115There is no option to wait for the application to close, and no way\n\
8116to retrieve the application's exit status.\n\
8117\n\
8118The filepath is relative to the current directory. If you want to use\n\
8119an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008120the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008121
8122static PyObject *
8123win32_startfile(PyObject *self, PyObject *args)
8124{
8125 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00008126 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008127 HINSTANCE rc;
Georg Brandlad89dc82006-04-03 12:26:26 +00008128#ifdef Py_WIN_WIDE_FILENAMES
8129 if (unicode_file_names()) {
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008130 PyObject *unipath, *woperation = NULL;
Georg Brandlad89dc82006-04-03 12:26:26 +00008131 if (!PyArg_ParseTuple(args, "U|s:startfile",
8132 &unipath, &operation)) {
8133 PyErr_Clear();
8134 goto normal;
8135 }
8136
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008137
8138 if (operation) {
8139 woperation = PyUnicode_DecodeASCII(operation,
8140 strlen(operation), NULL);
8141 if (!woperation) {
8142 PyErr_Clear();
8143 operation = NULL;
8144 goto normal;
8145 }
Georg Brandlad89dc82006-04-03 12:26:26 +00008146 }
8147
8148 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008149 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Georg Brandlad89dc82006-04-03 12:26:26 +00008150 PyUnicode_AS_UNICODE(unipath),
Georg Brandlad89dc82006-04-03 12:26:26 +00008151 NULL, NULL, SW_SHOWNORMAL);
8152 Py_END_ALLOW_THREADS
8153
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008154 Py_XDECREF(woperation);
Georg Brandlad89dc82006-04-03 12:26:26 +00008155 if (rc <= (HINSTANCE)32) {
8156 PyObject *errval = win32_error_unicode("startfile",
8157 PyUnicode_AS_UNICODE(unipath));
8158 return errval;
8159 }
8160 Py_INCREF(Py_None);
8161 return Py_None;
8162 }
8163#endif
8164
8165normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00008166 if (!PyArg_ParseTuple(args, "et|s:startfile",
8167 Py_FileSystemDefaultEncoding, &filepath,
8168 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00008169 return NULL;
8170 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00008171 rc = ShellExecute((HWND)0, operation, filepath,
8172 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008173 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00008174 if (rc <= (HINSTANCE)32) {
8175 PyObject *errval = win32_error("startfile", filepath);
8176 PyMem_Free(filepath);
8177 return errval;
8178 }
8179 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008180 Py_INCREF(Py_None);
8181 return Py_None;
8182}
8183#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008184
Martin v. Löwis438b5342002-12-27 10:16:42 +00008185#ifdef HAVE_GETLOADAVG
8186PyDoc_STRVAR(posix_getloadavg__doc__,
8187"getloadavg() -> (float, float, float)\n\n\
8188Return the number of processes in the system run queue averaged over\n\
8189the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8190was unobtainable");
8191
8192static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008193posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008194{
8195 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008196 if (getloadavg(loadavg, 3)!=3) {
8197 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8198 return NULL;
8199 } else
8200 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
8201}
8202#endif
8203
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008204#ifdef MS_WINDOWS
8205
8206PyDoc_STRVAR(win32_urandom__doc__,
8207"urandom(n) -> str\n\n\
8208Return a string of n random bytes suitable for cryptographic use.");
8209
8210typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8211 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8212 DWORD dwFlags );
8213typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8214 BYTE *pbBuffer );
8215
8216static CRYPTGENRANDOM pCryptGenRandom = NULL;
Martin v. Löwisaf699dd2007-09-04 09:51:57 +00008217/* This handle is never explicitly released. Instead, the operating
8218 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008219static HCRYPTPROV hCryptProv = 0;
8220
Tim Peters4ad82172004-08-30 17:02:04 +00008221static PyObject*
8222win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008223{
Tim Petersd3115382004-08-30 17:36:46 +00008224 int howMany;
8225 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008226
Tim Peters4ad82172004-08-30 17:02:04 +00008227 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00008228 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00008229 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00008230 if (howMany < 0)
8231 return PyErr_Format(PyExc_ValueError,
8232 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008233
Tim Peters4ad82172004-08-30 17:02:04 +00008234 if (hCryptProv == 0) {
8235 HINSTANCE hAdvAPI32 = NULL;
8236 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008237
Tim Peters4ad82172004-08-30 17:02:04 +00008238 /* Obtain handle to the DLL containing CryptoAPI
8239 This should not fail */
8240 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8241 if(hAdvAPI32 == NULL)
8242 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008243
Tim Peters4ad82172004-08-30 17:02:04 +00008244 /* Obtain pointers to the CryptoAPI functions
8245 This will fail on some early versions of Win95 */
8246 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8247 hAdvAPI32,
8248 "CryptAcquireContextA");
8249 if (pCryptAcquireContext == NULL)
8250 return PyErr_Format(PyExc_NotImplementedError,
8251 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008252
Tim Peters4ad82172004-08-30 17:02:04 +00008253 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8254 hAdvAPI32, "CryptGenRandom");
Georg Brandl74bb7832006-09-06 06:03:59 +00008255 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00008256 return PyErr_Format(PyExc_NotImplementedError,
8257 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008258
Tim Peters4ad82172004-08-30 17:02:04 +00008259 /* Acquire context */
8260 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8261 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8262 return win32_error("CryptAcquireContext", NULL);
8263 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008264
Tim Peters4ad82172004-08-30 17:02:04 +00008265 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008266 result = PyString_FromStringAndSize(NULL, howMany);
Tim Petersd3115382004-08-30 17:36:46 +00008267 if (result != NULL) {
8268 /* Get random data */
Amaury Forgeot d'Arc74bd40d2008-07-21 21:06:46 +00008269 memset(PyString_AS_STRING(result), 0, howMany); /* zero seed */
Tim Petersd3115382004-08-30 17:36:46 +00008270 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008271 PyString_AS_STRING(result))) {
Tim Petersd3115382004-08-30 17:36:46 +00008272 Py_DECREF(result);
8273 return win32_error("CryptGenRandom", NULL);
8274 }
Tim Peters4ad82172004-08-30 17:02:04 +00008275 }
Tim Petersd3115382004-08-30 17:36:46 +00008276 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008277}
8278#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008279
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008280#ifdef __VMS
8281/* Use openssl random routine */
8282#include <openssl/rand.h>
8283PyDoc_STRVAR(vms_urandom__doc__,
8284"urandom(n) -> str\n\n\
8285Return a string of n random bytes suitable for cryptographic use.");
8286
8287static PyObject*
8288vms_urandom(PyObject *self, PyObject *args)
8289{
8290 int howMany;
8291 PyObject* result;
8292
8293 /* Read arguments */
8294 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8295 return NULL;
8296 if (howMany < 0)
8297 return PyErr_Format(PyExc_ValueError,
8298 "negative argument not allowed");
8299
8300 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008301 result = PyString_FromStringAndSize(NULL, howMany);
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008302 if (result != NULL) {
8303 /* Get random data */
8304 if (RAND_pseudo_bytes((unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008305 PyString_AS_STRING(result),
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008306 howMany) < 0) {
8307 Py_DECREF(result);
8308 return PyErr_Format(PyExc_ValueError,
8309 "RAND_pseudo_bytes");
8310 }
8311 }
8312 return result;
8313}
8314#endif
8315
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008316static PyMethodDef posix_methods[] = {
8317 {"access", posix_access, METH_VARARGS, posix_access__doc__},
8318#ifdef HAVE_TTYNAME
8319 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
8320#endif
8321 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008322#ifdef HAVE_CHFLAGS
8323 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
8324#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008325 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008326#ifdef HAVE_FCHMOD
8327 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
8328#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008329#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008330 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008331#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008332#ifdef HAVE_LCHMOD
8333 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
8334#endif /* HAVE_LCHMOD */
8335#ifdef HAVE_FCHOWN
8336 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
8337#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008338#ifdef HAVE_LCHFLAGS
8339 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
8340#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008341#ifdef HAVE_LCHOWN
8342 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
8343#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008344#ifdef HAVE_CHROOT
8345 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
8346#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008347#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00008348 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008349#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008350#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00008351 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008352#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00008353 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008354#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008355#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008356#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008357 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008358#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008359 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8360 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8361 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008362#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008363 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008364#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008365#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008366 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008367#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008368 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8369 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8370 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008371 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008372#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008373 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008374#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008375#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008376 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008377#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008378 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008379#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00008380 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008381#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008382 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8383 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8384 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008385#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00008386 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008387#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008388 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008389#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008390 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8391 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008392#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008393#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008394 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8395 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008396#if defined(PYOS_OS2)
8397 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8398 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8399#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008400#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008401#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00008402 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008403#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008404#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00008405 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008406#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008407#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00008408 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008409#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008410#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00008411 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008412#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008413#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008414 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008415#endif /* HAVE_GETEGID */
8416#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008417 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008418#endif /* HAVE_GETEUID */
8419#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008420 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008421#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008422#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00008423 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008424#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008425 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008426#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008427 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008428#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008429#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00008430 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008431#endif /* HAVE_GETPPID */
8432#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008433 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008434#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008435#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00008436 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008437#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008438#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008439 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008440#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008441#ifdef HAVE_KILLPG
8442 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8443#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008444#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008445 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008446#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008447#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008448 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008449#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008450 {"popen2", win32_popen2, METH_VARARGS},
8451 {"popen3", win32_popen3, METH_VARARGS},
8452 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00008453 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008454#else
8455#if defined(PYOS_OS2) && defined(PYCC_GCC)
8456 {"popen2", os2emx_popen2, METH_VARARGS},
8457 {"popen3", os2emx_popen3, METH_VARARGS},
8458 {"popen4", os2emx_popen4, METH_VARARGS},
8459#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008460#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008461#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008462#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008463 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008464#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008465#ifdef HAVE_SETEUID
8466 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8467#endif /* HAVE_SETEUID */
8468#ifdef HAVE_SETEGID
8469 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8470#endif /* HAVE_SETEGID */
8471#ifdef HAVE_SETREUID
8472 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8473#endif /* HAVE_SETREUID */
8474#ifdef HAVE_SETREGID
8475 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8476#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008477#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008478 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008479#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008480#ifdef HAVE_SETGROUPS
Georg Brandl96a8c392006-05-29 21:04:52 +00008481 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008482#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008483#ifdef HAVE_GETPGID
8484 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8485#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008486#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008487 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008488#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008489#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00008490 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008491#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008492#ifdef HAVE_WAIT3
8493 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8494#endif /* HAVE_WAIT3 */
8495#ifdef HAVE_WAIT4
8496 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8497#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008498#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008499 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008500#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008501#ifdef HAVE_GETSID
8502 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8503#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008504#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00008505 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008506#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008507#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008508 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008509#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008510#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008511 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008512#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008513#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008514 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008515#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008516 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8517 {"close", posix_close, METH_VARARGS, posix_close__doc__},
Georg Brandl309501a2008-01-19 20:22:13 +00008518 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008519 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8520 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8521 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8522 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8523 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8524 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8525 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00008526 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008527#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00008528 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008529#endif
8530#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008531 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008532#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008533#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008534 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8535#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008536#ifdef HAVE_DEVICE_MACROS
8537 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8538 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8539 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8540#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008541#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008542 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008543#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008544#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008545 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008546#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008547#ifdef HAVE_UNSETENV
8548 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8549#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008550 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008551#ifdef HAVE_FCHDIR
8552 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8553#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008554#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008555 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008556#endif
8557#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008558 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008559#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008560#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008561#ifdef WCOREDUMP
8562 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8563#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008564#ifdef WIFCONTINUED
8565 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8566#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008567#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008568 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008569#endif /* WIFSTOPPED */
8570#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008571 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008572#endif /* WIFSIGNALED */
8573#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008574 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008575#endif /* WIFEXITED */
8576#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008577 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008578#endif /* WEXITSTATUS */
8579#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008580 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008581#endif /* WTERMSIG */
8582#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008583 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008584#endif /* WSTOPSIG */
8585#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008586#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008587 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008588#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008589#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008590 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008591#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008592#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00008593 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008594#endif
8595#ifdef HAVE_TEMPNAM
8596 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8597#endif
8598#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00008599 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008600#endif
Fred Drakec9680921999-12-13 16:37:25 +00008601#ifdef HAVE_CONFSTR
8602 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8603#endif
8604#ifdef HAVE_SYSCONF
8605 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8606#endif
8607#ifdef HAVE_FPATHCONF
8608 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8609#endif
8610#ifdef HAVE_PATHCONF
8611 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8612#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008613 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008614#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00008615 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8616#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008617#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00008618 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008619#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008620 #ifdef MS_WINDOWS
8621 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8622 #endif
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008623 #ifdef __VMS
8624 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8625 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008626 {NULL, NULL} /* Sentinel */
8627};
8628
8629
Barry Warsaw4a342091996-12-19 23:50:02 +00008630static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008631ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008632{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008633 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008634}
8635
Guido van Rossumd48f2521997-12-05 22:19:34 +00008636#if defined(PYOS_OS2)
8637/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008638static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008639{
8640 APIRET rc;
8641 ULONG values[QSV_MAX+1];
8642 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008643 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008644
8645 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008646 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008647 Py_END_ALLOW_THREADS
8648
8649 if (rc != NO_ERROR) {
8650 os2_error(rc);
8651 return -1;
8652 }
8653
Fred Drake4d1e64b2002-04-15 19:40:07 +00008654 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8655 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8656 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8657 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8658 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8659 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8660 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008661
8662 switch (values[QSV_VERSION_MINOR]) {
8663 case 0: ver = "2.00"; break;
8664 case 10: ver = "2.10"; break;
8665 case 11: ver = "2.11"; break;
8666 case 30: ver = "3.00"; break;
8667 case 40: ver = "4.00"; break;
8668 case 50: ver = "5.00"; break;
8669 default:
Tim Peters885d4572001-11-28 20:27:42 +00008670 PyOS_snprintf(tmp, sizeof(tmp),
8671 "%d-%d", values[QSV_VERSION_MAJOR],
8672 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008673 ver = &tmp[0];
8674 }
8675
8676 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008677 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008678 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008679
8680 /* Add Indicator of Which Drive was Used to Boot the System */
8681 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8682 tmp[1] = ':';
8683 tmp[2] = '\0';
8684
Fred Drake4d1e64b2002-04-15 19:40:07 +00008685 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008686}
8687#endif
8688
Barry Warsaw4a342091996-12-19 23:50:02 +00008689static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008690all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008691{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008692#ifdef F_OK
8693 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008694#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008695#ifdef R_OK
8696 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008697#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008698#ifdef W_OK
8699 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008700#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008701#ifdef X_OK
8702 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008703#endif
Fred Drakec9680921999-12-13 16:37:25 +00008704#ifdef NGROUPS_MAX
8705 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8706#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008707#ifdef TMP_MAX
8708 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8709#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008710#ifdef WCONTINUED
8711 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8712#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008713#ifdef WNOHANG
8714 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008715#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008716#ifdef WUNTRACED
8717 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8718#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008719#ifdef O_RDONLY
8720 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8721#endif
8722#ifdef O_WRONLY
8723 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8724#endif
8725#ifdef O_RDWR
8726 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8727#endif
8728#ifdef O_NDELAY
8729 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8730#endif
8731#ifdef O_NONBLOCK
8732 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8733#endif
8734#ifdef O_APPEND
8735 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8736#endif
8737#ifdef O_DSYNC
8738 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8739#endif
8740#ifdef O_RSYNC
8741 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8742#endif
8743#ifdef O_SYNC
8744 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8745#endif
8746#ifdef O_NOCTTY
8747 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8748#endif
8749#ifdef O_CREAT
8750 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8751#endif
8752#ifdef O_EXCL
8753 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8754#endif
8755#ifdef O_TRUNC
8756 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8757#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008758#ifdef O_BINARY
8759 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8760#endif
8761#ifdef O_TEXT
8762 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8763#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008764#ifdef O_LARGEFILE
8765 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8766#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008767#ifdef O_SHLOCK
8768 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8769#endif
8770#ifdef O_EXLOCK
8771 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8772#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008773
Tim Peters5aa91602002-01-30 05:46:57 +00008774/* MS Windows */
8775#ifdef O_NOINHERIT
8776 /* Don't inherit in child processes. */
8777 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8778#endif
8779#ifdef _O_SHORT_LIVED
8780 /* Optimize for short life (keep in memory). */
8781 /* MS forgot to define this one with a non-underscore form too. */
8782 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8783#endif
8784#ifdef O_TEMPORARY
8785 /* Automatically delete when last handle is closed. */
8786 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8787#endif
8788#ifdef O_RANDOM
8789 /* Optimize for random access. */
8790 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8791#endif
8792#ifdef O_SEQUENTIAL
8793 /* Optimize for sequential access. */
8794 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8795#endif
8796
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008797/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00008798#ifdef O_ASYNC
8799 /* Send a SIGIO signal whenever input or output
8800 becomes available on file descriptor */
8801 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
8802#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008803#ifdef O_DIRECT
8804 /* Direct disk access. */
8805 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8806#endif
8807#ifdef O_DIRECTORY
8808 /* Must be a directory. */
8809 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8810#endif
8811#ifdef O_NOFOLLOW
8812 /* Do not follow links. */
8813 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8814#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00008815#ifdef O_NOATIME
8816 /* Do not update the access time. */
8817 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
8818#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008819
Barry Warsaw5676bd12003-01-07 20:57:09 +00008820 /* These come from sysexits.h */
8821#ifdef EX_OK
8822 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008823#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008824#ifdef EX_USAGE
8825 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008826#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008827#ifdef EX_DATAERR
8828 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008829#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008830#ifdef EX_NOINPUT
8831 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008832#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008833#ifdef EX_NOUSER
8834 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008835#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008836#ifdef EX_NOHOST
8837 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008838#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008839#ifdef EX_UNAVAILABLE
8840 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008841#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008842#ifdef EX_SOFTWARE
8843 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008844#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008845#ifdef EX_OSERR
8846 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008847#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008848#ifdef EX_OSFILE
8849 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008850#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008851#ifdef EX_CANTCREAT
8852 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008853#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008854#ifdef EX_IOERR
8855 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008856#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008857#ifdef EX_TEMPFAIL
8858 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008859#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008860#ifdef EX_PROTOCOL
8861 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008862#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008863#ifdef EX_NOPERM
8864 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008865#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008866#ifdef EX_CONFIG
8867 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008868#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008869#ifdef EX_NOTFOUND
8870 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008871#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008872
Guido van Rossum246bc171999-02-01 23:54:31 +00008873#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008874#if defined(PYOS_OS2) && defined(PYCC_GCC)
8875 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8876 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8877 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8878 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8879 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8880 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8881 if (ins(d, "P_PM", (long)P_PM)) return -1;
8882 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8883 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8884 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8885 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8886 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8887 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8888 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8889 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8890 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8891 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8892 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8893 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8894 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8895#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008896 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8897 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8898 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8899 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8900 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008901#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008902#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008903
Guido van Rossumd48f2521997-12-05 22:19:34 +00008904#if defined(PYOS_OS2)
8905 if (insertvalues(d)) return -1;
8906#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008907 return 0;
8908}
8909
8910
Tim Peters5aa91602002-01-30 05:46:57 +00008911#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008912#define INITFUNC initnt
8913#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008914
8915#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008916#define INITFUNC initos2
8917#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008918
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008919#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008920#define INITFUNC initposix
8921#define MODNAME "posix"
8922#endif
8923
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008924PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008925INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008926{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008927 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008928
Fred Drake4d1e64b2002-04-15 19:40:07 +00008929 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008930 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008931 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008932 if (m == NULL)
8933 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008934
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008935 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008936 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008937 Py_XINCREF(v);
8938 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008939 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008940 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008941
Fred Drake4d1e64b2002-04-15 19:40:07 +00008942 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008943 return;
8944
Fred Drake4d1e64b2002-04-15 19:40:07 +00008945 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008946 return;
8947
Fred Drake4d1e64b2002-04-15 19:40:07 +00008948 Py_INCREF(PyExc_OSError);
8949 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008950
Guido van Rossumb3d39562000-01-31 18:41:26 +00008951#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008952 if (posix_putenv_garbage == NULL)
8953 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008954#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008955
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00008956 if (!initialized) {
8957 stat_result_desc.name = MODNAME ".stat_result";
8958 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8959 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8960 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8961 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8962 structseq_new = StatResultType.tp_new;
8963 StatResultType.tp_new = statresult_new;
8964
8965 statvfs_result_desc.name = MODNAME ".statvfs_result";
8966 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis3f15ae32008-12-29 18:20:48 +00008967#ifdef NEED_TICKS_PER_SECOND
8968# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
8969 ticks_per_second = sysconf(_SC_CLK_TCK);
8970# elif defined(HZ)
8971 ticks_per_second = HZ;
8972# else
8973 ticks_per_second = 60; /* magic fallback value; may be bogus */
8974# endif
8975#endif
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00008976 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008977 Py_INCREF((PyObject*) &StatResultType);
8978 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008979 Py_INCREF((PyObject*) &StatVFSResultType);
8980 PyModule_AddObject(m, "statvfs_result",
8981 (PyObject*) &StatVFSResultType);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00008982 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00008983
8984#ifdef __APPLE__
8985 /*
8986 * Step 2 of weak-linking support on Mac OS X.
8987 *
8988 * The code below removes functions that are not available on the
8989 * currently active platform.
8990 *
8991 * This block allow one to use a python binary that was build on
8992 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8993 * OSX 10.4.
8994 */
8995#ifdef HAVE_FSTATVFS
8996 if (fstatvfs == NULL) {
8997 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8998 return;
8999 }
9000 }
9001#endif /* HAVE_FSTATVFS */
9002
9003#ifdef HAVE_STATVFS
9004 if (statvfs == NULL) {
9005 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9006 return;
9007 }
9008 }
9009#endif /* HAVE_STATVFS */
9010
9011# ifdef HAVE_LCHOWN
9012 if (lchown == NULL) {
9013 if (PyObject_DelAttrString(m, "lchown") == -1) {
9014 return;
9015 }
9016 }
9017#endif /* HAVE_LCHOWN */
9018
9019
9020#endif /* __APPLE__ */
9021
Guido van Rossumb6775db1994-08-01 11:34:53 +00009022}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009023
9024#ifdef __cplusplus
9025}
9026#endif
9027
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009028