blob: 6dcf1b00c1c29fe09e8ffd72cb1b54a766945c79 [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
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000194extern int chown(const char *, uid_t, gid_t);
195extern char *getcwd(char *, int);
196extern char *strerror(int);
197extern int link(const char *, const char *);
198extern int rename(const char *, const char *);
199extern int stat(const char *, struct stat *);
200extern int unlink(const char *);
201extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000203extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000204#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000206extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000207#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000209
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000210#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211
Guido van Rossumb6775db1994-08-01 11:34:53 +0000212#ifdef HAVE_UTIME_H
213#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000214#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000216#ifdef HAVE_SYS_UTIME_H
217#include <sys/utime.h>
218#define HAVE_UTIME_H /* pretend we do for the rest of this file */
219#endif /* HAVE_SYS_UTIME_H */
220
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221#ifdef HAVE_SYS_TIMES_H
222#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000223#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224
225#ifdef HAVE_SYS_PARAM_H
226#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000227#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228
229#ifdef HAVE_SYS_UTSNAME_H
230#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000231#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000233#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000235#define NAMLEN(dirent) strlen((dirent)->d_name)
236#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000237#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000238#include <direct.h>
239#define NAMLEN(dirent) strlen((dirent)->d_name)
240#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000242#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000243#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000244#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000246#endif
247#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000249#endif
250#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000252#endif
253#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000255#ifdef _MSC_VER
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000256#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#include <direct.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000258#endif
259#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#include <io.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000261#endif
262#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#include <process.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000264#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000265#include "osdefs.h"
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000266#define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000268#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000269#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000270#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000271#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272
Guido van Rossumd48f2521997-12-05 22:19:34 +0000273#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000275#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000276
Tim Petersbc2e10e2002-03-03 23:17:02 +0000277#ifndef MAXPATHLEN
Thomas Wouters1ddba602006-04-25 15:29:46 +0000278#if defined(PATH_MAX) && PATH_MAX > 1024
279#define MAXPATHLEN PATH_MAX
280#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000281#define MAXPATHLEN 1024
Thomas Wouters1ddba602006-04-25 15:29:46 +0000282#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000283#endif /* MAXPATHLEN */
284
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000285#ifdef UNION_WAIT
286/* Emulate some macros on systems that have a union instead of macros */
287
288#ifndef WIFEXITED
289#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
290#endif
291
292#ifndef WEXITSTATUS
293#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
294#endif
295
296#ifndef WTERMSIG
297#define WTERMSIG(u_wait) ((u_wait).w_termsig)
298#endif
299
Neal Norwitzd5a37542006-03-20 06:48:34 +0000300#define WAIT_TYPE union wait
301#define WAIT_STATUS_INT(s) (s.w_status)
302
303#else /* !UNION_WAIT */
304#define WAIT_TYPE int
305#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000306#endif /* UNION_WAIT */
307
Greg Wardb48bc172000-03-01 21:51:56 +0000308/* Don't use the "_r" form if we don't need it (also, won't have a
309 prototype for it, at least on Solaris -- maybe others as well?). */
310#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
311#define USE_CTERMID_R
312#endif
313
314#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
315#define USE_TMPNAM_R
316#endif
317
Fred Drake699f3522000-06-29 21:12:41 +0000318/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000319#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000320#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000321# define STAT win32_stat
322# define FSTAT win32_fstat
323# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000324#else
325# define STAT stat
326# define FSTAT fstat
327# define STRUCT_STAT struct stat
328#endif
329
Tim Peters11b23062003-04-23 02:39:17 +0000330#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000331#include <sys/mkdev.h>
332#else
333#if defined(MAJOR_IN_SYSMACROS)
334#include <sys/sysmacros.h>
335#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000336#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
337#include <sys/mkdev.h>
338#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000339#endif
Fred Drake699f3522000-06-29 21:12:41 +0000340
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000341/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000342#ifdef WITH_NEXT_FRAMEWORK
343/* On Darwin/MacOSX a shared library or framework has no access to
344** environ directly, we must obtain it with _NSGetEnviron().
345*/
346#include <crt_externs.h>
347static char **environ;
348#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000349extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000350#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000351
Barry Warsaw53699e91996-12-10 23:23:01 +0000352static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000353convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000354{
Barry Warsaw53699e91996-12-10 23:23:01 +0000355 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000356 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000357 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000358 if (d == NULL)
359 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000360#ifdef WITH_NEXT_FRAMEWORK
361 if (environ == NULL)
362 environ = *_NSGetEnviron();
363#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000364 if (environ == NULL)
365 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000366 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000367 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000368 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000369 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000370 char *p = strchr(*e, '=');
371 if (p == NULL)
372 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000373 k = PyString_FromStringAndSize(*e, (int)(p-*e));
374 if (k == NULL) {
375 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000376 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000377 }
378 v = PyString_FromString(p+1);
379 if (v == NULL) {
380 PyErr_Clear();
381 Py_DECREF(k);
382 continue;
383 }
384 if (PyDict_GetItem(d, k) == NULL) {
385 if (PyDict_SetItem(d, k, v) != 0)
386 PyErr_Clear();
387 }
388 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000389 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000390 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000391#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000392 {
393 APIRET rc;
394 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
395
396 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000397 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000398 PyObject *v = PyString_FromString(buffer);
399 PyDict_SetItemString(d, "BEGINLIBPATH", v);
400 Py_DECREF(v);
401 }
402 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
403 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
404 PyObject *v = PyString_FromString(buffer);
405 PyDict_SetItemString(d, "ENDLIBPATH", v);
406 Py_DECREF(v);
407 }
408 }
409#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000410 return d;
411}
412
413
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000414/* Set a POSIX-specific error from errno, and return NULL */
415
Barry Warsawd58d7641998-07-23 16:14:40 +0000416static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000417posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000418{
Barry Warsawca74da41999-02-09 19:31:45 +0000419 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000420}
Barry Warsawd58d7641998-07-23 16:14:40 +0000421static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000422posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000423{
Barry Warsawca74da41999-02-09 19:31:45 +0000424 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000425}
426
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000427#ifdef Py_WIN_WIDE_FILENAMES
428static PyObject *
429posix_error_with_unicode_filename(Py_UNICODE* name)
430{
431 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
432}
433#endif /* Py_WIN_WIDE_FILENAMES */
434
435
Mark Hammondef8b6542001-05-13 08:04:26 +0000436static PyObject *
437posix_error_with_allocated_filename(char* name)
438{
439 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
440 PyMem_Free(name);
441 return rc;
442}
443
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000444#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000445static PyObject *
446win32_error(char* function, char* filename)
447{
Mark Hammond33a6da92000-08-15 00:46:38 +0000448 /* XXX We should pass the function name along in the future.
449 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000450 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000451 Windows error object, which is non-trivial.
452 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000453 errno = GetLastError();
454 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000455 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000456 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000457 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000458}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000459
460#ifdef Py_WIN_WIDE_FILENAMES
461static PyObject *
462win32_error_unicode(char* function, Py_UNICODE* filename)
463{
464 /* XXX - see win32_error for comments on 'function' */
465 errno = GetLastError();
466 if (filename)
467 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
468 else
469 return PyErr_SetFromWindowsErr(errno);
470}
471
472static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
473{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000474}
475
476/* Function suitable for O& conversion */
477static int
478convert_to_unicode(PyObject *arg, void* _param)
479{
480 PyObject **param = (PyObject**)_param;
481 if (PyUnicode_CheckExact(arg)) {
482 Py_INCREF(arg);
483 *param = arg;
484 }
485 else if (PyUnicode_Check(arg)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000486 /* For a Unicode subtype that's not a Unicode object,
487 return a true Unicode object with the same data. */
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000488 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(arg),
489 PyUnicode_GET_SIZE(arg));
490 return *param != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000491 }
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000492 else
493 *param = PyUnicode_FromEncodedObject(arg,
494 Py_FileSystemDefaultEncoding,
495 "strict");
496 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000497}
498
499#endif /* Py_WIN_WIDE_FILENAMES */
500
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000501#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000502
Guido van Rossumd48f2521997-12-05 22:19:34 +0000503#if defined(PYOS_OS2)
504/**********************************************************************
505 * Helper Function to Trim and Format OS/2 Messages
506 **********************************************************************/
507 static void
508os2_formatmsg(char *msgbuf, int msglen, char *reason)
509{
510 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
511
512 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
513 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
514
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000515 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000516 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
517 }
518
519 /* Add Optional Reason Text */
520 if (reason) {
521 strcat(msgbuf, " : ");
522 strcat(msgbuf, reason);
523 }
524}
525
526/**********************************************************************
527 * Decode an OS/2 Operating System Error Code
528 *
529 * A convenience function to lookup an OS/2 error code and return a
530 * text message we can use to raise a Python exception.
531 *
532 * Notes:
533 * The messages for errors returned from the OS/2 kernel reside in
534 * the file OSO001.MSG in the \OS2 directory hierarchy.
535 *
536 **********************************************************************/
537 static char *
538os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
539{
540 APIRET rc;
541 ULONG msglen;
542
543 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
544 Py_BEGIN_ALLOW_THREADS
545 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
546 errorcode, "oso001.msg", &msglen);
547 Py_END_ALLOW_THREADS
548
549 if (rc == NO_ERROR)
550 os2_formatmsg(msgbuf, msglen, reason);
551 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000552 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000553 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000554
555 return msgbuf;
556}
557
558/* Set an OS/2-specific error and return NULL. OS/2 kernel
559 errors are not in a global variable e.g. 'errno' nor are
560 they congruent with posix error numbers. */
561
562static PyObject * os2_error(int code)
563{
564 char text[1024];
565 PyObject *v;
566
567 os2_strerror(text, sizeof(text), code, "");
568
569 v = Py_BuildValue("(is)", code, text);
570 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000571 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000572 Py_DECREF(v);
573 }
574 return NULL; /* Signal to Python that an Exception is Pending */
575}
576
577#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000578
579/* POSIX generic methods */
580
Barry Warsaw53699e91996-12-10 23:23:01 +0000581static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000582posix_fildes(PyObject *fdobj, int (*func)(int))
583{
584 int fd;
585 int res;
586 fd = PyObject_AsFileDescriptor(fdobj);
587 if (fd < 0)
588 return NULL;
589 Py_BEGIN_ALLOW_THREADS
590 res = (*func)(fd);
591 Py_END_ALLOW_THREADS
592 if (res < 0)
593 return posix_error();
594 Py_INCREF(Py_None);
595 return Py_None;
596}
Guido van Rossum21142a01999-01-08 21:05:37 +0000597
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000598#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000599static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000600unicode_file_names(void)
601{
602 static int canusewide = -1;
603 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000604 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000605 the Windows NT family. */
606 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
607 }
608 return canusewide;
609}
610#endif
Tim Peters11b23062003-04-23 02:39:17 +0000611
Guido van Rossum21142a01999-01-08 21:05:37 +0000612static PyObject *
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000613posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000614{
Mark Hammondef8b6542001-05-13 08:04:26 +0000615 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000616 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000617 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000618 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000619 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000620 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000621 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000622 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000623 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000624 return posix_error_with_allocated_filename(path1);
625 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000626 Py_INCREF(Py_None);
627 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000628}
629
Barry Warsaw53699e91996-12-10 23:23:01 +0000630static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000631posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000632 char *format,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000633 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000634{
Mark Hammondef8b6542001-05-13 08:04:26 +0000635 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000636 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000637 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000638 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000639 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000640 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000641 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000642 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000643 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000644 PyMem_Free(path1);
645 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000646 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000647 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000648 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000649 Py_INCREF(Py_None);
650 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000651}
652
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000653#ifdef Py_WIN_WIDE_FILENAMES
654static PyObject*
655win32_1str(PyObject* args, char* func,
656 char* format, BOOL (__stdcall *funcA)(LPCSTR),
657 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
658{
659 PyObject *uni;
660 char *ansi;
661 BOOL result;
662 if (unicode_file_names()) {
663 if (!PyArg_ParseTuple(args, wformat, &uni))
664 PyErr_Clear();
665 else {
666 Py_BEGIN_ALLOW_THREADS
667 result = funcW(PyUnicode_AsUnicode(uni));
668 Py_END_ALLOW_THREADS
669 if (!result)
670 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
671 Py_INCREF(Py_None);
672 return Py_None;
673 }
674 }
675 if (!PyArg_ParseTuple(args, format, &ansi))
676 return NULL;
677 Py_BEGIN_ALLOW_THREADS
678 result = funcA(ansi);
679 Py_END_ALLOW_THREADS
680 if (!result)
681 return win32_error(func, ansi);
682 Py_INCREF(Py_None);
683 return Py_None;
684
685}
686
687/* This is a reimplementation of the C library's chdir function,
688 but one that produces Win32 errors instead of DOS error codes.
689 chdir is essentially a wrapper around SetCurrentDirectory; however,
690 it also needs to set "magic" environment variables indicating
691 the per-drive current directory, which are of the form =<drive>: */
692BOOL __stdcall
693win32_chdir(LPCSTR path)
694{
695 char new_path[MAX_PATH+1];
696 int result;
697 char env[4] = "=x:";
698
699 if(!SetCurrentDirectoryA(path))
700 return FALSE;
701 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
702 if (!result)
703 return FALSE;
704 /* In the ANSI API, there should not be any paths longer
705 than MAX_PATH. */
706 assert(result <= MAX_PATH+1);
707 if (strncmp(new_path, "\\\\", 2) == 0 ||
708 strncmp(new_path, "//", 2) == 0)
709 /* UNC path, nothing to do. */
710 return TRUE;
711 env[1] = new_path[0];
712 return SetEnvironmentVariableA(env, new_path);
713}
714
715/* The Unicode version differs from the ANSI version
716 since the current directory might exceed MAX_PATH characters */
717BOOL __stdcall
718win32_wchdir(LPCWSTR path)
719{
720 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
721 int result;
722 wchar_t env[4] = L"=x:";
723
724 if(!SetCurrentDirectoryW(path))
725 return FALSE;
726 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
727 if (!result)
728 return FALSE;
729 if (result > MAX_PATH+1) {
730 new_path = malloc(result);
731 if (!new_path) {
732 SetLastError(ERROR_OUTOFMEMORY);
733 return FALSE;
734 }
735 }
736 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
737 wcsncmp(new_path, L"//", 2) == 0)
738 /* UNC path, nothing to do. */
739 return TRUE;
740 env[1] = new_path[0];
741 result = SetEnvironmentVariableW(env, new_path);
742 if (new_path != _new_path)
743 free(new_path);
744 return result;
745}
746#endif
747
Martin v. Löwis14694662006-02-03 12:54:16 +0000748#ifdef MS_WINDOWS
749/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
750 - time stamps are restricted to second resolution
751 - file modification times suffer from forth-and-back conversions between
752 UTC and local time
753 Therefore, we implement our own stat, based on the Win32 API directly.
754*/
755#define HAVE_STAT_NSEC 1
756
757struct win32_stat{
758 int st_dev;
759 __int64 st_ino;
760 unsigned short st_mode;
761 int st_nlink;
762 int st_uid;
763 int st_gid;
764 int st_rdev;
765 __int64 st_size;
766 int st_atime;
767 int st_atime_nsec;
768 int st_mtime;
769 int st_mtime_nsec;
770 int st_ctime;
771 int st_ctime_nsec;
772};
773
774static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
775
776static void
777FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
778{
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000779 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
780 /* Cannot simply cast and dereference in_ptr,
781 since it might not be aligned properly */
782 __int64 in;
783 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000784 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
785 /* XXX Win32 supports time stamps past 2038; we currently don't */
786 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
787}
788
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000789static void
790time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
791{
792 /* XXX endianness */
793 __int64 out;
794 out = time_in + secs_between_epochs;
795 out = out * 10000000 + nsec_in;
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000796 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000797}
798
Martin v. Löwis14694662006-02-03 12:54:16 +0000799/* Below, we *know* that ugo+r is 0444 */
800#if _S_IREAD != 0400
801#error Unsupported C library
802#endif
803static int
804attributes_to_mode(DWORD attr)
805{
806 int m = 0;
807 if (attr & FILE_ATTRIBUTE_DIRECTORY)
808 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
809 else
810 m |= _S_IFREG;
811 if (attr & FILE_ATTRIBUTE_READONLY)
812 m |= 0444;
813 else
814 m |= 0666;
815 return m;
816}
817
818static int
819attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
820{
821 memset(result, 0, sizeof(*result));
822 result->st_mode = attributes_to_mode(info->dwFileAttributes);
823 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
824 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
825 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
826 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
827
828 return 0;
829}
830
831static int
832win32_stat(const char* path, struct win32_stat *result)
833{
834 WIN32_FILE_ATTRIBUTE_DATA info;
835 int code;
836 char *dot;
837 /* XXX not supported on Win95 and NT 3.x */
838 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
839 /* Protocol violation: we explicitly clear errno, instead of
840 setting it to a POSIX error. Callers should use GetLastError. */
841 errno = 0;
842 return -1;
843 }
844 code = attribute_data_to_stat(&info, result);
845 if (code != 0)
846 return code;
847 /* Set S_IFEXEC if it is an .exe, .bat, ... */
848 dot = strrchr(path, '.');
849 if (dot) {
850 if (stricmp(dot, ".bat") == 0 ||
851 stricmp(dot, ".cmd") == 0 ||
852 stricmp(dot, ".exe") == 0 ||
853 stricmp(dot, ".com") == 0)
854 result->st_mode |= 0111;
855 }
856 return code;
857}
858
859static int
860win32_wstat(const wchar_t* path, struct win32_stat *result)
861{
862 int code;
863 const wchar_t *dot;
864 WIN32_FILE_ATTRIBUTE_DATA info;
865 /* XXX not supported on Win95 and NT 3.x */
866 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
867 /* Protocol violation: we explicitly clear errno, instead of
868 setting it to a POSIX error. Callers should use GetLastError. */
869 errno = 0;
870 return -1;
871 }
872 code = attribute_data_to_stat(&info, result);
873 if (code < 0)
874 return code;
875 /* Set IFEXEC if it is an .exe, .bat, ... */
876 dot = wcsrchr(path, '.');
877 if (dot) {
878 if (_wcsicmp(dot, L".bat") == 0 ||
879 _wcsicmp(dot, L".cmd") == 0 ||
880 _wcsicmp(dot, L".exe") == 0 ||
881 _wcsicmp(dot, L".com") == 0)
882 result->st_mode |= 0111;
883 }
884 return code;
885}
886
887static int
888win32_fstat(int file_number, struct win32_stat *result)
889{
890 BY_HANDLE_FILE_INFORMATION info;
891 HANDLE h;
892 int type;
893
894 h = (HANDLE)_get_osfhandle(file_number);
895
896 /* Protocol violation: we explicitly clear errno, instead of
897 setting it to a POSIX error. Callers should use GetLastError. */
898 errno = 0;
899
900 if (h == INVALID_HANDLE_VALUE) {
901 /* This is really a C library error (invalid file handle).
902 We set the Win32 error to the closes one matching. */
903 SetLastError(ERROR_INVALID_HANDLE);
904 return -1;
905 }
906 memset(result, 0, sizeof(*result));
907
908 type = GetFileType(h);
909 if (type == FILE_TYPE_UNKNOWN) {
910 DWORD error = GetLastError();
911 if (error != 0) {
912 return -1;
913 }
914 /* else: valid but unknown file */
915 }
916
917 if (type != FILE_TYPE_DISK) {
918 if (type == FILE_TYPE_CHAR)
919 result->st_mode = _S_IFCHR;
920 else if (type == FILE_TYPE_PIPE)
921 result->st_mode = _S_IFIFO;
922 return 0;
923 }
924
925 if (!GetFileInformationByHandle(h, &info)) {
926 return -1;
927 }
928
929 /* similar to stat() */
930 result->st_mode = attributes_to_mode(info.dwFileAttributes);
931 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
932 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
933 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
934 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
935 /* specific to fstat() */
936 result->st_nlink = info.nNumberOfLinks;
937 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
938 return 0;
939}
940
941#endif /* MS_WINDOWS */
942
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000943PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000944"stat_result: Result from stat or lstat.\n\n\
945This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000946 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000947or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
948\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000949Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
950or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000951\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000952See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000953
954static PyStructSequence_Field stat_result_fields[] = {
955 {"st_mode", "protection bits"},
956 {"st_ino", "inode"},
957 {"st_dev", "device"},
958 {"st_nlink", "number of hard links"},
959 {"st_uid", "user ID of owner"},
960 {"st_gid", "group ID of owner"},
961 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000962 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
963 {NULL, "integer time of last access"},
964 {NULL, "integer time of last modification"},
965 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000966 {"st_atime", "time of last access"},
967 {"st_mtime", "time of last modification"},
968 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000969#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000970 {"st_blksize", "blocksize for filesystem I/O"},
971#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000972#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000973 {"st_blocks", "number of blocks allocated"},
974#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000975#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000976 {"st_rdev", "device type (if inode device)"},
977#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000978#ifdef HAVE_STRUCT_STAT_ST_FLAGS
979 {"st_flags", "user defined flags for file"},
980#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000981#ifdef HAVE_STRUCT_STAT_ST_GEN
982 {"st_gen", "generation number"},
983#endif
984#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
985 {"st_birthtime", "time of creation"},
986#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000987 {0}
988};
989
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000990#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000991#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000992#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000993#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000994#endif
995
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000996#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000997#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
998#else
999#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1000#endif
1001
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001002#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001003#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1004#else
1005#define ST_RDEV_IDX ST_BLOCKS_IDX
1006#endif
1007
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001008#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1009#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1010#else
1011#define ST_FLAGS_IDX ST_RDEV_IDX
1012#endif
1013
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001014#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001015#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001016#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001017#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001018#endif
1019
1020#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1021#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1022#else
1023#define ST_BIRTHTIME_IDX ST_GEN_IDX
1024#endif
1025
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001026static PyStructSequence_Desc stat_result_desc = {
1027 "stat_result", /* name */
1028 stat_result__doc__, /* doc */
1029 stat_result_fields,
1030 10
1031};
1032
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001033PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001034"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1035This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001036 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001037or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001038\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001039See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001040
1041static PyStructSequence_Field statvfs_result_fields[] = {
1042 {"f_bsize", },
1043 {"f_frsize", },
1044 {"f_blocks", },
1045 {"f_bfree", },
1046 {"f_bavail", },
1047 {"f_files", },
1048 {"f_ffree", },
1049 {"f_favail", },
1050 {"f_flag", },
1051 {"f_namemax",},
1052 {0}
1053};
1054
1055static PyStructSequence_Desc statvfs_result_desc = {
1056 "statvfs_result", /* name */
1057 statvfs_result__doc__, /* doc */
1058 statvfs_result_fields,
1059 10
1060};
1061
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001062static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001063static PyTypeObject StatResultType;
1064static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001065static newfunc structseq_new;
1066
1067static PyObject *
1068statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1069{
1070 PyStructSequence *result;
1071 int i;
1072
1073 result = (PyStructSequence*)structseq_new(type, args, kwds);
1074 if (!result)
1075 return NULL;
1076 /* If we have been initialized from a tuple,
1077 st_?time might be set to None. Initialize it
1078 from the int slots. */
1079 for (i = 7; i <= 9; i++) {
1080 if (result->ob_item[i+3] == Py_None) {
1081 Py_DECREF(Py_None);
1082 Py_INCREF(result->ob_item[i]);
1083 result->ob_item[i+3] = result->ob_item[i];
1084 }
1085 }
1086 return (PyObject*)result;
1087}
1088
1089
1090
1091/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001092static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001093
1094PyDoc_STRVAR(stat_float_times__doc__,
1095"stat_float_times([newval]) -> oldval\n\n\
1096Determine whether os.[lf]stat represents time stamps as float objects.\n\
1097If newval is True, future calls to stat() return floats, if it is False,\n\
1098future calls return ints. \n\
1099If newval is omitted, return the current setting.\n");
1100
1101static PyObject*
1102stat_float_times(PyObject* self, PyObject *args)
1103{
1104 int newval = -1;
1105 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1106 return NULL;
1107 if (newval == -1)
1108 /* Return old value */
1109 return PyBool_FromLong(_stat_float_times);
1110 _stat_float_times = newval;
1111 Py_INCREF(Py_None);
1112 return Py_None;
1113}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001114
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001115static void
1116fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1117{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001118 PyObject *fval,*ival;
1119#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001120 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001121#else
1122 ival = PyInt_FromLong((long)sec);
1123#endif
1124 if (_stat_float_times) {
1125 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1126 } else {
1127 fval = ival;
1128 Py_INCREF(fval);
1129 }
1130 PyStructSequence_SET_ITEM(v, index, ival);
1131 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001132}
1133
Tim Peters5aa91602002-01-30 05:46:57 +00001134/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001135 (used by posix_stat() and posix_fstat()) */
1136static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001137_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001138{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001139 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001140 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001141 if (v == NULL)
1142 return NULL;
1143
Martin v. Löwis14694662006-02-03 12:54:16 +00001144 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001145#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001146 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001147 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001148#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001149 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001150#endif
1151#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001152 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001153 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001154#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001155 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001156#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001157 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1158 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1159 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001160#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001161 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001162 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001163#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001164 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001165#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001166
Martin v. Löwis14694662006-02-03 12:54:16 +00001167#if defined(HAVE_STAT_TV_NSEC)
1168 ansec = st->st_atim.tv_nsec;
1169 mnsec = st->st_mtim.tv_nsec;
1170 cnsec = st->st_ctim.tv_nsec;
1171#elif defined(HAVE_STAT_TV_NSEC2)
1172 ansec = st->st_atimespec.tv_nsec;
1173 mnsec = st->st_mtimespec.tv_nsec;
1174 cnsec = st->st_ctimespec.tv_nsec;
1175#elif defined(HAVE_STAT_NSEC)
1176 ansec = st->st_atime_nsec;
1177 mnsec = st->st_mtime_nsec;
1178 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001179#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001180 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001181#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001182 fill_time(v, 7, st->st_atime, ansec);
1183 fill_time(v, 8, st->st_mtime, mnsec);
1184 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001185
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001186#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001187 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001188 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001189#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001190#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001191 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001192 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001193#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001194#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001195 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001196 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001197#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001198#ifdef HAVE_STRUCT_STAT_ST_GEN
1199 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001200 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001201#endif
1202#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1203 {
1204 PyObject *val;
1205 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001206 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001207#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001208 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001209#else
1210 bnsec = 0;
1211#endif
1212 if (_stat_float_times) {
1213 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1214 } else {
1215 val = PyInt_FromLong((long)bsec);
1216 }
1217 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1218 val);
1219 }
1220#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001221#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1222 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001223 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001224#endif
Fred Drake699f3522000-06-29 21:12:41 +00001225
1226 if (PyErr_Occurred()) {
1227 Py_DECREF(v);
1228 return NULL;
1229 }
1230
1231 return v;
1232}
1233
Martin v. Löwisd8948722004-06-02 09:57:56 +00001234#ifdef MS_WINDOWS
1235
1236/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1237 where / can be used in place of \ and the trailing slash is optional.
1238 Both SERVER and SHARE must have at least one character.
1239*/
1240
1241#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1242#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001243#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001244#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001245#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001246
Tim Peters4ad82172004-08-30 17:02:04 +00001247static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001248IsUNCRootA(char *path, int pathlen)
1249{
1250 #define ISSLASH ISSLASHA
1251
1252 int i, share;
1253
1254 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1255 /* minimum UNCRoot is \\x\y */
1256 return FALSE;
1257 for (i = 2; i < pathlen ; i++)
1258 if (ISSLASH(path[i])) break;
1259 if (i == 2 || i == pathlen)
1260 /* do not allow \\\SHARE or \\SERVER */
1261 return FALSE;
1262 share = i+1;
1263 for (i = share; i < pathlen; i++)
1264 if (ISSLASH(path[i])) break;
1265 return (i != share && (i == pathlen || i == pathlen-1));
1266
1267 #undef ISSLASH
1268}
1269
1270#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001271static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001272IsUNCRootW(Py_UNICODE *path, int pathlen)
1273{
1274 #define ISSLASH ISSLASHW
1275
1276 int i, share;
1277
1278 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1279 /* minimum UNCRoot is \\x\y */
1280 return FALSE;
1281 for (i = 2; i < pathlen ; i++)
1282 if (ISSLASH(path[i])) break;
1283 if (i == 2 || i == pathlen)
1284 /* do not allow \\\SHARE or \\SERVER */
1285 return FALSE;
1286 share = i+1;
1287 for (i = share; i < pathlen; i++)
1288 if (ISSLASH(path[i])) break;
1289 return (i != share && (i == pathlen || i == pathlen-1));
1290
1291 #undef ISSLASH
1292}
1293#endif /* Py_WIN_WIDE_FILENAMES */
1294#endif /* MS_WINDOWS */
1295
Barry Warsaw53699e91996-12-10 23:23:01 +00001296static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001297posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001298 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001299#ifdef __VMS
1300 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1301#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001302 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001303#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001304 char *wformat,
1305 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001306{
Fred Drake699f3522000-06-29 21:12:41 +00001307 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001308 char *path = NULL; /* pass this to stat; do not free() it */
1309 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001310 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001311 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001312
1313#ifdef Py_WIN_WIDE_FILENAMES
1314 /* If on wide-character-capable OS see if argument
1315 is Unicode and if so use wide API. */
1316 if (unicode_file_names()) {
1317 PyUnicodeObject *po;
1318 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001319 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1320
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001321 Py_BEGIN_ALLOW_THREADS
1322 /* PyUnicode_AS_UNICODE result OK without
1323 thread lock as it is a simple dereference. */
1324 res = wstatfunc(wpath, &st);
1325 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001326
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001327 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001328 return win32_error_unicode("stat", wpath);
1329 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001330 }
1331 /* Drop the argument parsing error as narrow strings
1332 are also valid. */
1333 PyErr_Clear();
1334 }
1335#endif
1336
Tim Peters5aa91602002-01-30 05:46:57 +00001337 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001338 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001339 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001340 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001341
Barry Warsaw53699e91996-12-10 23:23:01 +00001342 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001343 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001344 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001345
1346 if (res != 0) {
1347#ifdef MS_WINDOWS
1348 result = win32_error("stat", pathfree);
1349#else
1350 result = posix_error_with_filename(pathfree);
1351#endif
1352 }
1353 else
1354 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001355
Tim Peters500bd032001-12-19 19:05:01 +00001356 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001357 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001358}
1359
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001360/* POSIX methods */
1361
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001362PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001363"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001364Use the real uid/gid to test for access to a path. Note that most\n\
1365operations will use the effective uid/gid, therefore this routine can\n\
1366be used in a suid/sgid environment to test if the invoking user has the\n\
1367specified access to the path. The mode argument can be F_OK to test\n\
1368existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001369
1370static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001371posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001372{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001373 char *path;
1374 int mode;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001375
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001376#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001377 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001378 if (unicode_file_names()) {
1379 PyUnicodeObject *po;
1380 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1381 Py_BEGIN_ALLOW_THREADS
1382 /* PyUnicode_AS_UNICODE OK without thread lock as
1383 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001384 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001385 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001386 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001387 }
1388 /* Drop the argument parsing error as narrow strings
1389 are also valid. */
1390 PyErr_Clear();
1391 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001392 if (!PyArg_ParseTuple(args, "eti:access",
1393 Py_FileSystemDefaultEncoding, &path, &mode))
1394 return 0;
1395 Py_BEGIN_ALLOW_THREADS
1396 attr = GetFileAttributesA(path);
1397 Py_END_ALLOW_THREADS
1398 PyMem_Free(path);
1399finish:
1400 if (attr == 0xFFFFFFFF)
1401 /* File does not exist, or cannot read attributes */
1402 return PyBool_FromLong(0);
1403 /* Access is possible if either write access wasn't requested, or
1404 the file isn't read-only. */
1405 return PyBool_FromLong(!(mode & 2) || !(attr && FILE_ATTRIBUTE_READONLY));
1406#else
1407 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001408 if (!PyArg_ParseTuple(args, "eti:access",
1409 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001410 return NULL;
1411 Py_BEGIN_ALLOW_THREADS
1412 res = access(path, mode);
1413 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001414 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001415 return PyBool_FromLong(res == 0);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001416#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001417}
1418
Guido van Rossumd371ff11999-01-25 16:12:23 +00001419#ifndef F_OK
1420#define F_OK 0
1421#endif
1422#ifndef R_OK
1423#define R_OK 4
1424#endif
1425#ifndef W_OK
1426#define W_OK 2
1427#endif
1428#ifndef X_OK
1429#define X_OK 1
1430#endif
1431
1432#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001433PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001434"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001435Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001436
1437static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001438posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001439{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001440 int id;
1441 char *ret;
1442
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001443 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001444 return NULL;
1445
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001446#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001447 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001448 if (id == 0) {
1449 ret = ttyname();
1450 }
1451 else {
1452 ret = NULL;
1453 }
1454#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001455 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001456#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001457 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001458 return posix_error();
1459 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001460}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001461#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001462
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001463#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001464PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001465"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001466Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001467
1468static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001469posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001470{
1471 char *ret;
1472 char buffer[L_ctermid];
1473
Greg Wardb48bc172000-03-01 21:51:56 +00001474#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001475 ret = ctermid_r(buffer);
1476#else
1477 ret = ctermid(buffer);
1478#endif
1479 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001480 return posix_error();
1481 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001482}
1483#endif
1484
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001485PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001486"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001487Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001488
Barry Warsaw53699e91996-12-10 23:23:01 +00001489static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001490posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001491{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001492#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001493 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001494#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001495 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001496#elif defined(__VMS)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001497 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001498#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001499 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001500#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001501}
1502
Fred Drake4d1e64b2002-04-15 19:40:07 +00001503#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001504PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001505"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001506Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001507opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001508
1509static PyObject *
1510posix_fchdir(PyObject *self, PyObject *fdobj)
1511{
1512 return posix_fildes(fdobj, fchdir);
1513}
1514#endif /* HAVE_FCHDIR */
1515
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001516
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001517PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001518"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001519Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001520
Barry Warsaw53699e91996-12-10 23:23:01 +00001521static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001522posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001523{
Mark Hammondef8b6542001-05-13 08:04:26 +00001524 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001525 int i;
1526 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001527#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001528 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001529 if (unicode_file_names()) {
1530 PyUnicodeObject *po;
1531 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1532 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001533 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1534 if (attr != 0xFFFFFFFF) {
1535 if (i & _S_IWRITE)
1536 attr &= ~FILE_ATTRIBUTE_READONLY;
1537 else
1538 attr |= FILE_ATTRIBUTE_READONLY;
1539 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1540 }
1541 else
1542 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001543 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001544 if (!res)
1545 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001546 PyUnicode_AS_UNICODE(po));
1547 Py_INCREF(Py_None);
1548 return Py_None;
1549 }
1550 /* Drop the argument parsing error as narrow strings
1551 are also valid. */
1552 PyErr_Clear();
1553 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001554 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1555 &path, &i))
1556 return NULL;
1557 Py_BEGIN_ALLOW_THREADS
1558 attr = GetFileAttributesA(path);
1559 if (attr != 0xFFFFFFFF) {
1560 if (i & _S_IWRITE)
1561 attr &= ~FILE_ATTRIBUTE_READONLY;
1562 else
1563 attr |= FILE_ATTRIBUTE_READONLY;
1564 res = SetFileAttributesA(path, attr);
1565 }
1566 else
1567 res = 0;
1568 Py_END_ALLOW_THREADS
1569 if (!res) {
1570 win32_error("chmod", path);
1571 PyMem_Free(path);
1572 return NULL;
1573 }
Martin v. Löwis9f485bc2006-05-08 05:25:56 +00001574 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001575 Py_INCREF(Py_None);
1576 return Py_None;
1577#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001578 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001579 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001580 return NULL;
1581 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001582 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001583 Py_END_ALLOW_THREADS
1584 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001585 return posix_error_with_allocated_filename(path);
1586 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001587 Py_INCREF(Py_None);
1588 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001589#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001590}
1591
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001592
Martin v. Löwis244edc82001-10-04 22:44:26 +00001593#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001594PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001595"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001596Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001597
1598static PyObject *
1599posix_chroot(PyObject *self, PyObject *args)
1600{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001601 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001602}
1603#endif
1604
Guido van Rossum21142a01999-01-08 21:05:37 +00001605#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001606PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001607"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001608force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001609
1610static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001611posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001612{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001613 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001614}
1615#endif /* HAVE_FSYNC */
1616
1617#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001618
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001619#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001620extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1621#endif
1622
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001623PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001624"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001625force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001626 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001627
1628static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001629posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001630{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001631 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001632}
1633#endif /* HAVE_FDATASYNC */
1634
1635
Fredrik Lundh10723342000-07-10 16:38:09 +00001636#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001637PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001638"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001639Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001640
Barry Warsaw53699e91996-12-10 23:23:01 +00001641static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001642posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001643{
Mark Hammondef8b6542001-05-13 08:04:26 +00001644 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001645 int uid, gid;
1646 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001647 if (!PyArg_ParseTuple(args, "etii:chown",
1648 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001649 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001650 return NULL;
1651 Py_BEGIN_ALLOW_THREADS
1652 res = chown(path, (uid_t) uid, (gid_t) gid);
1653 Py_END_ALLOW_THREADS
1654 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001655 return posix_error_with_allocated_filename(path);
1656 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001657 Py_INCREF(Py_None);
1658 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001659}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001660#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001661
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001662#ifdef HAVE_LCHOWN
1663PyDoc_STRVAR(posix_lchown__doc__,
1664"lchown(path, uid, gid)\n\n\
1665Change the owner and group id of path to the numeric uid and gid.\n\
1666This function will not follow symbolic links.");
1667
1668static PyObject *
1669posix_lchown(PyObject *self, PyObject *args)
1670{
1671 char *path = NULL;
1672 int uid, gid;
1673 int res;
1674 if (!PyArg_ParseTuple(args, "etii:lchown",
1675 Py_FileSystemDefaultEncoding, &path,
1676 &uid, &gid))
1677 return NULL;
1678 Py_BEGIN_ALLOW_THREADS
1679 res = lchown(path, (uid_t) uid, (gid_t) gid);
1680 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001681 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001682 return posix_error_with_allocated_filename(path);
1683 PyMem_Free(path);
1684 Py_INCREF(Py_None);
1685 return Py_None;
1686}
1687#endif /* HAVE_LCHOWN */
1688
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001689
Guido van Rossum36bc6801995-06-14 22:54:23 +00001690#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001691PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001692"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001693Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001694
Barry Warsaw53699e91996-12-10 23:23:01 +00001695static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001696posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001697{
1698 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001699 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001700
Barry Warsaw53699e91996-12-10 23:23:01 +00001701 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001702#if defined(PYOS_OS2) && defined(PYCC_GCC)
1703 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001704#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001705 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001706#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001707 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001708 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001709 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001710 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001711}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001712
Walter Dörwald3b918c32002-11-21 20:18:46 +00001713#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001714PyDoc_STRVAR(posix_getcwdu__doc__,
1715"getcwdu() -> path\n\n\
1716Return a unicode string representing the current working directory.");
1717
1718static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001719posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001720{
1721 char buf[1026];
1722 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001723
1724#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001725 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001726 if (unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001727 wchar_t wbuf[1026];
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001728 wchar_t *wbuf2 = wbuf;
1729 PyObject *resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001730 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001731 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
1732 /* If the buffer is large enough, len does not include the
1733 terminating \0. If the buffer is too small, len includes
1734 the space needed for the terminator. */
1735 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
1736 wbuf2 = malloc(len * sizeof(wchar_t));
1737 if (wbuf2)
1738 len = GetCurrentDirectoryW(len, wbuf2);
1739 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001740 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001741 if (!wbuf2) {
1742 PyErr_NoMemory();
1743 return NULL;
1744 }
1745 if (!len) {
1746 if (wbuf2 != wbuf) free(wbuf2);
1747 return win32_error("getcwdu", NULL);
1748 }
1749 resobj = PyUnicode_FromWideChar(wbuf2, len);
1750 if (wbuf2 != wbuf) free(wbuf2);
1751 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001752 }
1753#endif
1754
1755 Py_BEGIN_ALLOW_THREADS
1756#if defined(PYOS_OS2) && defined(PYCC_GCC)
1757 res = _getcwd2(buf, sizeof buf);
1758#else
1759 res = getcwd(buf, sizeof buf);
1760#endif
1761 Py_END_ALLOW_THREADS
1762 if (res == NULL)
1763 return posix_error();
1764 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1765}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001766#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001767#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001768
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001769
Guido van Rossumb6775db1994-08-01 11:34:53 +00001770#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001771PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001772"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001773Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001774
Barry Warsaw53699e91996-12-10 23:23:01 +00001775static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001776posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001777{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00001778 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001779}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001780#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001781
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001782
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001783PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001784"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001785Return a list containing the names of the entries in the directory.\n\
1786\n\
1787 path: path of directory to list\n\
1788\n\
1789The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001790entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001791
Barry Warsaw53699e91996-12-10 23:23:01 +00001792static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001793posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001794{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001795 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001796 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001797#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001798
Barry Warsaw53699e91996-12-10 23:23:01 +00001799 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001800 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001801 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001802 WIN32_FIND_DATA FileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001803 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00001804 char *bufptr = namebuf;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001805 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001806
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001807#ifdef Py_WIN_WIDE_FILENAMES
1808 /* If on wide-character-capable OS see if argument
1809 is Unicode and if so use wide API. */
1810 if (unicode_file_names()) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001811 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001812 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1813 WIN32_FIND_DATAW wFileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001814 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001815 Py_UNICODE wch;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001816 /* Overallocate for \\*.*\0 */
1817 len = PyUnicode_GET_SIZE(po);
1818 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
1819 if (!wnamebuf) {
1820 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001821 return NULL;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001822 }
1823 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
1824 wch = len > 0 ? wnamebuf[len-1] : '\0';
1825 if (wch != L'/' && wch != L'\\' && wch != L':')
1826 wnamebuf[len++] = L'\\';
1827 wcscpy(wnamebuf + len, L"*.*");
1828 if ((d = PyList_New(0)) == NULL) {
1829 free(wnamebuf);
1830 return NULL;
1831 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001832 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1833 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001834 int error = GetLastError();
1835 if (error == ERROR_FILE_NOT_FOUND) {
1836 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001837 return d;
1838 }
1839 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001840 win32_error_unicode("FindFirstFileW", wnamebuf);
1841 free(wnamebuf);
1842 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001843 }
1844 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001845 /* Skip over . and .. */
1846 if (wcscmp(wFileData.cFileName, L".") != 0 &&
1847 wcscmp(wFileData.cFileName, L"..") != 0) {
1848 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1849 if (v == NULL) {
1850 Py_DECREF(d);
1851 d = NULL;
1852 break;
1853 }
1854 if (PyList_Append(d, v) != 0) {
1855 Py_DECREF(v);
1856 Py_DECREF(d);
1857 d = NULL;
1858 break;
1859 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001860 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001861 }
Georg Brandl622927b2006-03-07 12:48:03 +00001862 Py_BEGIN_ALLOW_THREADS
1863 result = FindNextFileW(hFindFile, &wFileData);
1864 Py_END_ALLOW_THREADS
1865 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001866
1867 if (FindClose(hFindFile) == FALSE) {
1868 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001869 win32_error_unicode("FindClose", wnamebuf);
1870 free(wnamebuf);
1871 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001872 }
Martin v. Löwise3edaea2006-05-15 05:51:36 +00001873 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001874 return d;
1875 }
1876 /* Drop the argument parsing error as narrow strings
1877 are also valid. */
1878 PyErr_Clear();
1879 }
1880#endif
1881
Tim Peters5aa91602002-01-30 05:46:57 +00001882 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001883 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001884 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001885 if (len > 0) {
1886 char ch = namebuf[len-1];
1887 if (ch != SEP && ch != ALTSEP && ch != ':')
1888 namebuf[len++] = '/';
1889 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001890 strcpy(namebuf + len, "*.*");
1891
Barry Warsaw53699e91996-12-10 23:23:01 +00001892 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001893 return NULL;
1894
1895 hFindFile = FindFirstFile(namebuf, &FileData);
1896 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001897 int error = GetLastError();
1898 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001899 return d;
1900 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001901 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001902 }
1903 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001904 /* Skip over . and .. */
1905 if (strcmp(FileData.cFileName, ".") != 0 &&
1906 strcmp(FileData.cFileName, "..") != 0) {
1907 v = PyString_FromString(FileData.cFileName);
1908 if (v == NULL) {
1909 Py_DECREF(d);
1910 d = NULL;
1911 break;
1912 }
1913 if (PyList_Append(d, v) != 0) {
1914 Py_DECREF(v);
1915 Py_DECREF(d);
1916 d = NULL;
1917 break;
1918 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001919 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001920 }
Georg Brandl622927b2006-03-07 12:48:03 +00001921 Py_BEGIN_ALLOW_THREADS
1922 result = FindNextFile(hFindFile, &FileData);
1923 Py_END_ALLOW_THREADS
1924 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001925
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001926 if (FindClose(hFindFile) == FALSE) {
1927 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001928 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001929 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001930
1931 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001932
Tim Peters0bb44a42000-09-15 07:44:49 +00001933#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001934
1935#ifndef MAX_PATH
1936#define MAX_PATH CCHMAXPATH
1937#endif
1938 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00001939 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001940 PyObject *d, *v;
1941 char namebuf[MAX_PATH+5];
1942 HDIR hdir = 1;
1943 ULONG srchcnt = 1;
1944 FILEFINDBUF3 ep;
1945 APIRET rc;
1946
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001947 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001948 return NULL;
1949 if (len >= MAX_PATH) {
1950 PyErr_SetString(PyExc_ValueError, "path too long");
1951 return NULL;
1952 }
1953 strcpy(namebuf, name);
1954 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001955 if (*pt == ALTSEP)
1956 *pt = SEP;
1957 if (namebuf[len-1] != SEP)
1958 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001959 strcpy(namebuf + len, "*.*");
1960
1961 if ((d = PyList_New(0)) == NULL)
1962 return NULL;
1963
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001964 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1965 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001966 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001967 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1968 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1969 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001970
1971 if (rc != NO_ERROR) {
1972 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001973 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001974 }
1975
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001976 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001977 do {
1978 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001979 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001980 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001981
1982 strcpy(namebuf, ep.achName);
1983
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001984 /* Leave Case of Name Alone -- In Native Form */
1985 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001986
1987 v = PyString_FromString(namebuf);
1988 if (v == NULL) {
1989 Py_DECREF(d);
1990 d = NULL;
1991 break;
1992 }
1993 if (PyList_Append(d, v) != 0) {
1994 Py_DECREF(v);
1995 Py_DECREF(d);
1996 d = NULL;
1997 break;
1998 }
1999 Py_DECREF(v);
2000 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2001 }
2002
2003 return d;
2004#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002005
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002006 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002007 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002008 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002009 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002010 int arg_is_unicode = 1;
2011
Georg Brandl05e89b82006-04-11 07:04:06 +00002012 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002013 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2014 arg_is_unicode = 0;
2015 PyErr_Clear();
2016 }
2017 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002018 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002019 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002020 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002021 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002022 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002023 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002024 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002025 return NULL;
2026 }
Georg Brandl622927b2006-03-07 12:48:03 +00002027 for (;;) {
2028 Py_BEGIN_ALLOW_THREADS
2029 ep = readdir(dirp);
2030 Py_END_ALLOW_THREADS
2031 if (ep == NULL)
2032 break;
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002033 if (ep->d_name[0] == '.' &&
2034 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002035 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002036 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00002037 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002038 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002039 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002040 d = NULL;
2041 break;
2042 }
Just van Rossum46c97842003-02-25 21:42:15 +00002043#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00002044 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002045 PyObject *w;
2046
2047 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002048 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002049 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002050 if (w != NULL) {
2051 Py_DECREF(v);
2052 v = w;
2053 }
2054 else {
2055 /* fall back to the original byte string, as
2056 discussed in patch #683592 */
2057 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002058 }
Just van Rossum46c97842003-02-25 21:42:15 +00002059 }
2060#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002061 if (PyList_Append(d, v) != 0) {
2062 Py_DECREF(v);
2063 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002064 d = NULL;
2065 break;
2066 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002067 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002068 }
Georg Brandlbbfe4fa2006-04-11 06:47:43 +00002069 if (errno != 0 && d != NULL) {
2070 /* readdir() returned NULL and set errno */
2071 closedir(dirp);
2072 Py_DECREF(d);
2073 return posix_error_with_allocated_filename(name);
2074 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002075 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002076 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002077
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002078 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002079
Tim Peters0bb44a42000-09-15 07:44:49 +00002080#endif /* which OS */
2081} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002082
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002083#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002084/* A helper function for abspath on win32 */
2085static PyObject *
2086posix__getfullpathname(PyObject *self, PyObject *args)
2087{
2088 /* assume encoded strings wont more than double no of chars */
2089 char inbuf[MAX_PATH*2];
2090 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002091 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002092 char outbuf[MAX_PATH*2];
2093 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002094#ifdef Py_WIN_WIDE_FILENAMES
2095 if (unicode_file_names()) {
2096 PyUnicodeObject *po;
2097 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2098 Py_UNICODE woutbuf[MAX_PATH*2];
2099 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00002100 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002101 sizeof(woutbuf)/sizeof(woutbuf[0]),
2102 woutbuf, &wtemp))
2103 return win32_error("GetFullPathName", "");
2104 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
2105 }
2106 /* Drop the argument parsing error as narrow strings
2107 are also valid. */
2108 PyErr_Clear();
2109 }
2110#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002111 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2112 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002113 &insize))
2114 return NULL;
2115 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2116 outbuf, &temp))
2117 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002118 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2119 return PyUnicode_Decode(outbuf, strlen(outbuf),
2120 Py_FileSystemDefaultEncoding, NULL);
2121 }
Mark Hammondef8b6542001-05-13 08:04:26 +00002122 return PyString_FromString(outbuf);
2123} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002124#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002125
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002126PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002127"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002128Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002129
Barry Warsaw53699e91996-12-10 23:23:01 +00002130static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002131posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002132{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002133 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002134 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002135 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002136
2137#ifdef Py_WIN_WIDE_FILENAMES
2138 if (unicode_file_names()) {
2139 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002140 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002141 Py_BEGIN_ALLOW_THREADS
2142 /* PyUnicode_AS_UNICODE OK without thread lock as
2143 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002144 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002145 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002146 if (!res)
2147 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002148 Py_INCREF(Py_None);
2149 return Py_None;
2150 }
2151 /* Drop the argument parsing error as narrow strings
2152 are also valid. */
2153 PyErr_Clear();
2154 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002155 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2156 Py_FileSystemDefaultEncoding, &path, &mode))
2157 return NULL;
2158 Py_BEGIN_ALLOW_THREADS
2159 /* PyUnicode_AS_UNICODE OK without thread lock as
2160 it is a simple dereference. */
2161 res = CreateDirectoryA(path, NULL);
2162 Py_END_ALLOW_THREADS
2163 if (!res) {
2164 win32_error("mkdir", path);
2165 PyMem_Free(path);
2166 return NULL;
2167 }
2168 PyMem_Free(path);
2169 Py_INCREF(Py_None);
2170 return Py_None;
2171#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002172
Tim Peters5aa91602002-01-30 05:46:57 +00002173 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002174 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002175 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002176 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002177#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002178 res = mkdir(path);
2179#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002180 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002181#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002182 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002183 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002184 return posix_error_with_allocated_filename(path);
2185 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002186 Py_INCREF(Py_None);
2187 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002188#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002189}
2190
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002191
Neal Norwitz1818ed72006-03-26 00:29:48 +00002192/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2193#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002194#include <sys/resource.h>
2195#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002196
Neal Norwitz1818ed72006-03-26 00:29:48 +00002197
2198#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002199PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002200"nice(inc) -> new_priority\n\n\
2201Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002202
Barry Warsaw53699e91996-12-10 23:23:01 +00002203static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002204posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002205{
2206 int increment, value;
2207
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002208 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002209 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002210
2211 /* There are two flavours of 'nice': one that returns the new
2212 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002213 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2214 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002215
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002216 If we are of the nice family that returns the new priority, we
2217 need to clear errno before the call, and check if errno is filled
2218 before calling posix_error() on a returnvalue of -1, because the
2219 -1 may be the actual new priority! */
2220
2221 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002222 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002223#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002224 if (value == 0)
2225 value = getpriority(PRIO_PROCESS, 0);
2226#endif
2227 if (value == -1 && errno != 0)
2228 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002229 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002230 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002231}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002232#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002233
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002234PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002235"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002236Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002237
Barry Warsaw53699e91996-12-10 23:23:01 +00002238static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002239posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002240{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002241#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002242 PyObject *o1, *o2;
2243 char *p1, *p2;
2244 BOOL result;
2245 if (unicode_file_names()) {
2246 if (!PyArg_ParseTuple(args, "O&O&:rename",
2247 convert_to_unicode, &o1,
2248 convert_to_unicode, &o2))
2249 PyErr_Clear();
2250 else {
2251 Py_BEGIN_ALLOW_THREADS
2252 result = MoveFileW(PyUnicode_AsUnicode(o1),
2253 PyUnicode_AsUnicode(o2));
2254 Py_END_ALLOW_THREADS
2255 Py_DECREF(o1);
2256 Py_DECREF(o2);
2257 if (!result)
2258 return win32_error("rename", NULL);
2259 Py_INCREF(Py_None);
2260 return Py_None;
2261 }
2262 }
2263 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2264 return NULL;
2265 Py_BEGIN_ALLOW_THREADS
2266 result = MoveFileA(p1, p2);
2267 Py_END_ALLOW_THREADS
2268 if (!result)
2269 return win32_error("rename", NULL);
2270 Py_INCREF(Py_None);
2271 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002272#else
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002273 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002274#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002275}
2276
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002277
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002278PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002279"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002280Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002281
Barry Warsaw53699e91996-12-10 23:23:01 +00002282static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002283posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002284{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002285#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002286 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002287#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002288 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002289#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002290}
2291
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002292
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002293PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002294"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002295Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002296
Barry Warsaw53699e91996-12-10 23:23:01 +00002297static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002298posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002299{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002300#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002301 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002302#else
2303 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2304#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002305}
2306
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002307
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002308#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002309PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002310"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002311Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002312
Barry Warsaw53699e91996-12-10 23:23:01 +00002313static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002314posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002315{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002316 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002317 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002318 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002319 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002320 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002321 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002322 Py_END_ALLOW_THREADS
2323 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002324}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002325#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002326
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002327
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002328PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002329"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002330Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002331
Barry Warsaw53699e91996-12-10 23:23:01 +00002332static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002333posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002334{
2335 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002336 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002337 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002338 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002339 if (i < 0)
2340 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002341 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002342}
2343
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002344
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002345PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002346"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002347Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002348
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002349PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002350"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002351Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002352
Barry Warsaw53699e91996-12-10 23:23:01 +00002353static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002354posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002355{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002356#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002357 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002358#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002359 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002360#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002361}
2362
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002363
Guido van Rossumb6775db1994-08-01 11:34:53 +00002364#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002365PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002366"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002367Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002368
Barry Warsaw53699e91996-12-10 23:23:01 +00002369static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002370posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002371{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002372 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002373 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002374
Barry Warsaw53699e91996-12-10 23:23:01 +00002375 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002376 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002377 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002378 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002379 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002380 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002381 u.sysname,
2382 u.nodename,
2383 u.release,
2384 u.version,
2385 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002386}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002387#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002388
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002389static int
2390extract_time(PyObject *t, long* sec, long* usec)
2391{
2392 long intval;
2393 if (PyFloat_Check(t)) {
2394 double tval = PyFloat_AsDouble(t);
2395 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2396 if (!intobj)
2397 return -1;
2398 intval = PyInt_AsLong(intobj);
2399 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002400 if (intval == -1 && PyErr_Occurred())
2401 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002402 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002403 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002404 if (*usec < 0)
2405 /* If rounding gave us a negative number,
2406 truncate. */
2407 *usec = 0;
2408 return 0;
2409 }
2410 intval = PyInt_AsLong(t);
2411 if (intval == -1 && PyErr_Occurred())
2412 return -1;
2413 *sec = intval;
2414 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002415 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002416}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002417
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002418PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002419"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002420utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002421Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002422second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002423
Barry Warsaw53699e91996-12-10 23:23:01 +00002424static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002425posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002426{
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002427#ifdef Py_WIN_WIDE_FILENAMES
2428 PyObject *arg;
2429 PyUnicodeObject *obwpath;
2430 wchar_t *wpath = NULL;
2431 char *apath = NULL;
2432 HANDLE hFile;
2433 long atimesec, mtimesec, ausec, musec;
2434 FILETIME atime, mtime;
2435 PyObject *result = NULL;
2436
2437 if (unicode_file_names()) {
2438 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2439 wpath = PyUnicode_AS_UNICODE(obwpath);
2440 Py_BEGIN_ALLOW_THREADS
2441 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2442 NULL, OPEN_EXISTING, 0, NULL);
2443 Py_END_ALLOW_THREADS
2444 if (hFile == INVALID_HANDLE_VALUE)
2445 return win32_error_unicode("utime", wpath);
2446 } else
2447 /* Drop the argument parsing error as narrow strings
2448 are also valid. */
2449 PyErr_Clear();
2450 }
2451 if (!wpath) {
2452 if (!PyArg_ParseTuple(args, "etO:utime",
2453 Py_FileSystemDefaultEncoding, &apath, &arg))
2454 return NULL;
2455 Py_BEGIN_ALLOW_THREADS
2456 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2457 NULL, OPEN_EXISTING, 0, NULL);
2458 Py_END_ALLOW_THREADS
2459 if (hFile == INVALID_HANDLE_VALUE) {
2460 win32_error("utime", apath);
2461 PyMem_Free(apath);
2462 return NULL;
2463 }
2464 PyMem_Free(apath);
2465 }
2466
2467 if (arg == Py_None) {
2468 SYSTEMTIME now;
2469 GetSystemTime(&now);
2470 if (!SystemTimeToFileTime(&now, &mtime) ||
2471 !SystemTimeToFileTime(&now, &atime)) {
2472 win32_error("utime", NULL);
2473 goto done;
2474 }
2475 }
2476 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2477 PyErr_SetString(PyExc_TypeError,
2478 "utime() arg 2 must be a tuple (atime, mtime)");
2479 goto done;
2480 }
2481 else {
2482 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2483 &atimesec, &ausec) == -1)
2484 goto done;
2485 time_t_to_FILE_TIME(atimesec, ausec, &atime);
2486 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2487 &mtimesec, &musec) == -1)
2488 goto done;
2489 time_t_to_FILE_TIME(mtimesec, musec, &mtime);
2490 }
2491 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2492 /* Avoid putting the file name into the error here,
2493 as that may confuse the user into believing that
2494 something is wrong with the file, when it also
2495 could be the time stamp that gives a problem. */
2496 win32_error("utime", NULL);
2497 }
2498 Py_INCREF(Py_None);
2499 result = Py_None;
2500done:
2501 CloseHandle(hFile);
2502 return result;
2503#else /* Py_WIN_WIDE_FILENAMES */
2504
Neal Norwitz2adf2102004-06-09 01:46:02 +00002505 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002506 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002507 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002508 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002509
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002510#if defined(HAVE_UTIMES)
2511 struct timeval buf[2];
2512#define ATIME buf[0].tv_sec
2513#define MTIME buf[1].tv_sec
2514#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002515/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002516 struct utimbuf buf;
2517#define ATIME buf.actime
2518#define MTIME buf.modtime
2519#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002520#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002521 time_t buf[2];
2522#define ATIME buf[0]
2523#define MTIME buf[1]
2524#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002525#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002526
Mark Hammond817c9292003-12-03 01:22:38 +00002527
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002528 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002529 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002530 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002531 if (arg == Py_None) {
2532 /* optional time values not given */
2533 Py_BEGIN_ALLOW_THREADS
2534 res = utime(path, NULL);
2535 Py_END_ALLOW_THREADS
2536 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002537 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002538 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002539 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002540 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002541 return NULL;
2542 }
2543 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002544 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002545 &atime, &ausec) == -1) {
2546 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002547 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002548 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002549 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002550 &mtime, &musec) == -1) {
2551 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002552 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002553 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002554 ATIME = atime;
2555 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002556#ifdef HAVE_UTIMES
2557 buf[0].tv_usec = ausec;
2558 buf[1].tv_usec = musec;
2559 Py_BEGIN_ALLOW_THREADS
2560 res = utimes(path, buf);
2561 Py_END_ALLOW_THREADS
2562#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002563 Py_BEGIN_ALLOW_THREADS
2564 res = utime(path, UTIME_ARG);
2565 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002566#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002567 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002568 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002569 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002570 }
Neal Norwitz96652712004-06-06 20:40:27 +00002571 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002572 Py_INCREF(Py_None);
2573 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002574#undef UTIME_ARG
2575#undef ATIME
2576#undef MTIME
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002577#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002578}
2579
Guido van Rossum85e3b011991-06-03 12:42:10 +00002580
Guido van Rossum3b066191991-06-04 19:40:25 +00002581/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002582
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002583PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002584"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002585Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002586
Barry Warsaw53699e91996-12-10 23:23:01 +00002587static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002588posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002589{
2590 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002591 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002592 return NULL;
2593 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002594 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002595}
2596
Martin v. Löwis114619e2002-10-07 06:44:21 +00002597#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2598static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002599free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002600{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002601 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002602 for (i = 0; i < count; i++)
2603 PyMem_Free(array[i]);
2604 PyMem_DEL(array);
2605}
2606#endif
2607
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002608
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002609#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002610PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002611"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002612Execute an executable path with arguments, replacing current process.\n\
2613\n\
2614 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002615 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002616
Barry Warsaw53699e91996-12-10 23:23:01 +00002617static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002618posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002619{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002620 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002621 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002622 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002623 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002624 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002625
Guido van Rossum89b33251993-10-22 14:26:06 +00002626 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002627 argv is a list or tuple of strings. */
2628
Martin v. Löwis114619e2002-10-07 06:44:21 +00002629 if (!PyArg_ParseTuple(args, "etO:execv",
2630 Py_FileSystemDefaultEncoding,
2631 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002632 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002633 if (PyList_Check(argv)) {
2634 argc = PyList_Size(argv);
2635 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002636 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002637 else if (PyTuple_Check(argv)) {
2638 argc = PyTuple_Size(argv);
2639 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002640 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002641 else {
Fred Drake661ea262000-10-24 19:57:45 +00002642 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002643 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002644 return NULL;
2645 }
2646
Barry Warsaw53699e91996-12-10 23:23:01 +00002647 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002648 if (argvlist == NULL) {
2649 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002650 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002651 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002652 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002653 if (!PyArg_Parse((*getitem)(argv, i), "et",
2654 Py_FileSystemDefaultEncoding,
2655 &argvlist[i])) {
2656 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002657 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002658 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002659 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002660 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002661
Guido van Rossum85e3b011991-06-03 12:42:10 +00002662 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002663 }
2664 argvlist[argc] = NULL;
2665
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002666 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002667
Guido van Rossum85e3b011991-06-03 12:42:10 +00002668 /* If we get here it's definitely an error */
2669
Martin v. Löwis114619e2002-10-07 06:44:21 +00002670 free_string_array(argvlist, argc);
2671 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002672 return posix_error();
2673}
2674
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002675
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002676PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002677"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002678Execute a path with arguments and environment, replacing current process.\n\
2679\n\
2680 path: path of executable file\n\
2681 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002682 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002683
Barry Warsaw53699e91996-12-10 23:23:01 +00002684static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002685posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002686{
2687 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002688 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002689 char **argvlist;
2690 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002691 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002692 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002693 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002694 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002695
2696 /* execve has three arguments: (path, argv, env), where
2697 argv is a list or tuple of strings and env is a dictionary
2698 like posix.environ. */
2699
Martin v. Löwis114619e2002-10-07 06:44:21 +00002700 if (!PyArg_ParseTuple(args, "etOO:execve",
2701 Py_FileSystemDefaultEncoding,
2702 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002703 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002704 if (PyList_Check(argv)) {
2705 argc = PyList_Size(argv);
2706 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002707 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002708 else if (PyTuple_Check(argv)) {
2709 argc = PyTuple_Size(argv);
2710 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002711 }
2712 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002713 PyErr_SetString(PyExc_TypeError,
2714 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002715 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002716 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002717 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002718 PyErr_SetString(PyExc_TypeError,
2719 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002720 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002721 }
2722
Barry Warsaw53699e91996-12-10 23:23:01 +00002723 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002724 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002725 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002726 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002727 }
2728 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002729 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002730 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002731 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002732 &argvlist[i]))
2733 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002734 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002735 goto fail_1;
2736 }
2737 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002738 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002739 argvlist[argc] = NULL;
2740
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002741 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002742 if (i < 0)
2743 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002744 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002745 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002746 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002747 goto fail_1;
2748 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002749 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002750 keys = PyMapping_Keys(env);
2751 vals = PyMapping_Values(env);
2752 if (!keys || !vals)
2753 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002754 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2755 PyErr_SetString(PyExc_TypeError,
2756 "execve(): env.keys() or env.values() is not a list");
2757 goto fail_2;
2758 }
Tim Peters5aa91602002-01-30 05:46:57 +00002759
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002760 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002761 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002762 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002763
2764 key = PyList_GetItem(keys, pos);
2765 val = PyList_GetItem(vals, pos);
2766 if (!key || !val)
2767 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002768
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002769 if (!PyArg_Parse(
2770 key,
2771 "s;execve() arg 3 contains a non-string key",
2772 &k) ||
2773 !PyArg_Parse(
2774 val,
2775 "s;execve() arg 3 contains a non-string value",
2776 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002777 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002778 goto fail_2;
2779 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002780
2781#if defined(PYOS_OS2)
2782 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2783 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2784#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002785 len = PyString_Size(key) + PyString_Size(val) + 2;
2786 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002787 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002788 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002789 goto fail_2;
2790 }
Tim Petersc8996f52001-12-03 20:41:00 +00002791 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002792 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002793#if defined(PYOS_OS2)
2794 }
2795#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002796 }
2797 envlist[envc] = 0;
2798
2799 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002800
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002801 /* If we get here it's definitely an error */
2802
2803 (void) posix_error();
2804
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002805 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002806 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002807 PyMem_DEL(envlist[envc]);
2808 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002809 fail_1:
2810 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002811 Py_XDECREF(vals);
2812 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002813 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002814 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002815 return NULL;
2816}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002817#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002818
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002819
Guido van Rossuma1065681999-01-25 23:20:23 +00002820#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002821PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002822"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002823Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002824\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002825 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002826 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002827 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002828
2829static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002830posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002831{
2832 char *path;
2833 PyObject *argv;
2834 char **argvlist;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002835 int mode, i;
2836 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002837 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002838 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00002839
2840 /* spawnv has three arguments: (mode, path, argv), where
2841 argv is a list or tuple of strings. */
2842
Martin v. Löwis114619e2002-10-07 06:44:21 +00002843 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2844 Py_FileSystemDefaultEncoding,
2845 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002846 return NULL;
2847 if (PyList_Check(argv)) {
2848 argc = PyList_Size(argv);
2849 getitem = PyList_GetItem;
2850 }
2851 else if (PyTuple_Check(argv)) {
2852 argc = PyTuple_Size(argv);
2853 getitem = PyTuple_GetItem;
2854 }
2855 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002856 PyErr_SetString(PyExc_TypeError,
2857 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002858 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002859 return NULL;
2860 }
2861
2862 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002863 if (argvlist == NULL) {
2864 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002865 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002866 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002867 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002868 if (!PyArg_Parse((*getitem)(argv, i), "et",
2869 Py_FileSystemDefaultEncoding,
2870 &argvlist[i])) {
2871 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002872 PyErr_SetString(
2873 PyExc_TypeError,
2874 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002875 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002876 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002877 }
2878 }
2879 argvlist[argc] = NULL;
2880
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002881#if defined(PYOS_OS2) && defined(PYCC_GCC)
2882 Py_BEGIN_ALLOW_THREADS
2883 spawnval = spawnv(mode, path, argvlist);
2884 Py_END_ALLOW_THREADS
2885#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002886 if (mode == _OLD_P_OVERLAY)
2887 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002888
Tim Peters25059d32001-12-07 20:35:43 +00002889 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002890 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002891 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002892#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002893
Martin v. Löwis114619e2002-10-07 06:44:21 +00002894 free_string_array(argvlist, argc);
2895 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002896
Fred Drake699f3522000-06-29 21:12:41 +00002897 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002898 return posix_error();
2899 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002900#if SIZEOF_LONG == SIZEOF_VOID_P
2901 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002902#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002903 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002904#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002905}
2906
2907
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002908PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002909"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002910Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002911\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002912 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002913 path: path of executable file\n\
2914 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002915 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002916
2917static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002918posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002919{
2920 char *path;
2921 PyObject *argv, *env;
2922 char **argvlist;
2923 char **envlist;
2924 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002925 int mode, pos, envc;
2926 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00002927 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002928 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002929 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002930
2931 /* spawnve has four arguments: (mode, path, argv, env), where
2932 argv is a list or tuple of strings and env is a dictionary
2933 like posix.environ. */
2934
Martin v. Löwis114619e2002-10-07 06:44:21 +00002935 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2936 Py_FileSystemDefaultEncoding,
2937 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002938 return NULL;
2939 if (PyList_Check(argv)) {
2940 argc = PyList_Size(argv);
2941 getitem = PyList_GetItem;
2942 }
2943 else if (PyTuple_Check(argv)) {
2944 argc = PyTuple_Size(argv);
2945 getitem = PyTuple_GetItem;
2946 }
2947 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002948 PyErr_SetString(PyExc_TypeError,
2949 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002950 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002951 }
2952 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002953 PyErr_SetString(PyExc_TypeError,
2954 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002955 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002956 }
2957
2958 argvlist = PyMem_NEW(char *, argc+1);
2959 if (argvlist == NULL) {
2960 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002961 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002962 }
2963 for (i = 0; i < argc; i++) {
2964 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002965 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002966 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002967 &argvlist[i]))
2968 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002969 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002970 goto fail_1;
2971 }
2972 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002973 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002974 argvlist[argc] = NULL;
2975
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002976 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002977 if (i < 0)
2978 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002979 envlist = PyMem_NEW(char *, i + 1);
2980 if (envlist == NULL) {
2981 PyErr_NoMemory();
2982 goto fail_1;
2983 }
2984 envc = 0;
2985 keys = PyMapping_Keys(env);
2986 vals = PyMapping_Values(env);
2987 if (!keys || !vals)
2988 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002989 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2990 PyErr_SetString(PyExc_TypeError,
2991 "spawnve(): env.keys() or env.values() is not a list");
2992 goto fail_2;
2993 }
Tim Peters5aa91602002-01-30 05:46:57 +00002994
Guido van Rossuma1065681999-01-25 23:20:23 +00002995 for (pos = 0; pos < i; pos++) {
2996 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002997 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002998
2999 key = PyList_GetItem(keys, pos);
3000 val = PyList_GetItem(vals, pos);
3001 if (!key || !val)
3002 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003003
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003004 if (!PyArg_Parse(
3005 key,
3006 "s;spawnve() arg 3 contains a non-string key",
3007 &k) ||
3008 !PyArg_Parse(
3009 val,
3010 "s;spawnve() arg 3 contains a non-string value",
3011 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003012 {
3013 goto fail_2;
3014 }
Tim Petersc8996f52001-12-03 20:41:00 +00003015 len = PyString_Size(key) + PyString_Size(val) + 2;
3016 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003017 if (p == NULL) {
3018 PyErr_NoMemory();
3019 goto fail_2;
3020 }
Tim Petersc8996f52001-12-03 20:41:00 +00003021 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003022 envlist[envc++] = p;
3023 }
3024 envlist[envc] = 0;
3025
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003026#if defined(PYOS_OS2) && defined(PYCC_GCC)
3027 Py_BEGIN_ALLOW_THREADS
3028 spawnval = spawnve(mode, path, argvlist, envlist);
3029 Py_END_ALLOW_THREADS
3030#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003031 if (mode == _OLD_P_OVERLAY)
3032 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003033
3034 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003035 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003036 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003037#endif
Tim Peters25059d32001-12-07 20:35:43 +00003038
Fred Drake699f3522000-06-29 21:12:41 +00003039 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003040 (void) posix_error();
3041 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003042#if SIZEOF_LONG == SIZEOF_VOID_P
3043 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003044#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003045 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003046#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003047
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003048 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003049 while (--envc >= 0)
3050 PyMem_DEL(envlist[envc]);
3051 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003052 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003053 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003054 Py_XDECREF(vals);
3055 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003056 fail_0:
3057 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003058 return res;
3059}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003060
3061/* OS/2 supports spawnvp & spawnvpe natively */
3062#if defined(PYOS_OS2)
3063PyDoc_STRVAR(posix_spawnvp__doc__,
3064"spawnvp(mode, file, args)\n\n\
3065Execute the program 'file' in a new process, using the environment\n\
3066search path to find the file.\n\
3067\n\
3068 mode: mode of process creation\n\
3069 file: executable file name\n\
3070 args: tuple or list of strings");
3071
3072static PyObject *
3073posix_spawnvp(PyObject *self, PyObject *args)
3074{
3075 char *path;
3076 PyObject *argv;
3077 char **argvlist;
3078 int mode, i, argc;
3079 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003080 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003081
3082 /* spawnvp has three arguments: (mode, path, argv), where
3083 argv is a list or tuple of strings. */
3084
3085 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3086 Py_FileSystemDefaultEncoding,
3087 &path, &argv))
3088 return NULL;
3089 if (PyList_Check(argv)) {
3090 argc = PyList_Size(argv);
3091 getitem = PyList_GetItem;
3092 }
3093 else if (PyTuple_Check(argv)) {
3094 argc = PyTuple_Size(argv);
3095 getitem = PyTuple_GetItem;
3096 }
3097 else {
3098 PyErr_SetString(PyExc_TypeError,
3099 "spawnvp() arg 2 must be a tuple or list");
3100 PyMem_Free(path);
3101 return NULL;
3102 }
3103
3104 argvlist = PyMem_NEW(char *, argc+1);
3105 if (argvlist == NULL) {
3106 PyMem_Free(path);
3107 return PyErr_NoMemory();
3108 }
3109 for (i = 0; i < argc; i++) {
3110 if (!PyArg_Parse((*getitem)(argv, i), "et",
3111 Py_FileSystemDefaultEncoding,
3112 &argvlist[i])) {
3113 free_string_array(argvlist, i);
3114 PyErr_SetString(
3115 PyExc_TypeError,
3116 "spawnvp() arg 2 must contain only strings");
3117 PyMem_Free(path);
3118 return NULL;
3119 }
3120 }
3121 argvlist[argc] = NULL;
3122
3123 Py_BEGIN_ALLOW_THREADS
3124#if defined(PYCC_GCC)
3125 spawnval = spawnvp(mode, path, argvlist);
3126#else
3127 spawnval = _spawnvp(mode, path, argvlist);
3128#endif
3129 Py_END_ALLOW_THREADS
3130
3131 free_string_array(argvlist, argc);
3132 PyMem_Free(path);
3133
3134 if (spawnval == -1)
3135 return posix_error();
3136 else
3137 return Py_BuildValue("l", (long) spawnval);
3138}
3139
3140
3141PyDoc_STRVAR(posix_spawnvpe__doc__,
3142"spawnvpe(mode, file, args, env)\n\n\
3143Execute the program 'file' in a new process, using the environment\n\
3144search path to find the file.\n\
3145\n\
3146 mode: mode of process creation\n\
3147 file: executable file name\n\
3148 args: tuple or list of arguments\n\
3149 env: dictionary of strings mapping to strings");
3150
3151static PyObject *
3152posix_spawnvpe(PyObject *self, PyObject *args)
3153{
3154 char *path;
3155 PyObject *argv, *env;
3156 char **argvlist;
3157 char **envlist;
3158 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3159 int mode, i, pos, argc, envc;
3160 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003161 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003162 int lastarg = 0;
3163
3164 /* spawnvpe has four arguments: (mode, path, argv, env), where
3165 argv is a list or tuple of strings and env is a dictionary
3166 like posix.environ. */
3167
3168 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3169 Py_FileSystemDefaultEncoding,
3170 &path, &argv, &env))
3171 return NULL;
3172 if (PyList_Check(argv)) {
3173 argc = PyList_Size(argv);
3174 getitem = PyList_GetItem;
3175 }
3176 else if (PyTuple_Check(argv)) {
3177 argc = PyTuple_Size(argv);
3178 getitem = PyTuple_GetItem;
3179 }
3180 else {
3181 PyErr_SetString(PyExc_TypeError,
3182 "spawnvpe() arg 2 must be a tuple or list");
3183 goto fail_0;
3184 }
3185 if (!PyMapping_Check(env)) {
3186 PyErr_SetString(PyExc_TypeError,
3187 "spawnvpe() arg 3 must be a mapping object");
3188 goto fail_0;
3189 }
3190
3191 argvlist = PyMem_NEW(char *, argc+1);
3192 if (argvlist == NULL) {
3193 PyErr_NoMemory();
3194 goto fail_0;
3195 }
3196 for (i = 0; i < argc; i++) {
3197 if (!PyArg_Parse((*getitem)(argv, i),
3198 "et;spawnvpe() arg 2 must contain only strings",
3199 Py_FileSystemDefaultEncoding,
3200 &argvlist[i]))
3201 {
3202 lastarg = i;
3203 goto fail_1;
3204 }
3205 }
3206 lastarg = argc;
3207 argvlist[argc] = NULL;
3208
3209 i = PyMapping_Size(env);
3210 if (i < 0)
3211 goto fail_1;
3212 envlist = PyMem_NEW(char *, i + 1);
3213 if (envlist == NULL) {
3214 PyErr_NoMemory();
3215 goto fail_1;
3216 }
3217 envc = 0;
3218 keys = PyMapping_Keys(env);
3219 vals = PyMapping_Values(env);
3220 if (!keys || !vals)
3221 goto fail_2;
3222 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3223 PyErr_SetString(PyExc_TypeError,
3224 "spawnvpe(): env.keys() or env.values() is not a list");
3225 goto fail_2;
3226 }
3227
3228 for (pos = 0; pos < i; pos++) {
3229 char *p, *k, *v;
3230 size_t len;
3231
3232 key = PyList_GetItem(keys, pos);
3233 val = PyList_GetItem(vals, pos);
3234 if (!key || !val)
3235 goto fail_2;
3236
3237 if (!PyArg_Parse(
3238 key,
3239 "s;spawnvpe() arg 3 contains a non-string key",
3240 &k) ||
3241 !PyArg_Parse(
3242 val,
3243 "s;spawnvpe() arg 3 contains a non-string value",
3244 &v))
3245 {
3246 goto fail_2;
3247 }
3248 len = PyString_Size(key) + PyString_Size(val) + 2;
3249 p = PyMem_NEW(char, len);
3250 if (p == NULL) {
3251 PyErr_NoMemory();
3252 goto fail_2;
3253 }
3254 PyOS_snprintf(p, len, "%s=%s", k, v);
3255 envlist[envc++] = p;
3256 }
3257 envlist[envc] = 0;
3258
3259 Py_BEGIN_ALLOW_THREADS
3260#if defined(PYCC_GCC)
3261 spawnval = spawnve(mode, path, argvlist, envlist);
3262#else
3263 spawnval = _spawnve(mode, path, argvlist, envlist);
3264#endif
3265 Py_END_ALLOW_THREADS
3266
3267 if (spawnval == -1)
3268 (void) posix_error();
3269 else
3270 res = Py_BuildValue("l", (long) spawnval);
3271
3272 fail_2:
3273 while (--envc >= 0)
3274 PyMem_DEL(envlist[envc]);
3275 PyMem_DEL(envlist);
3276 fail_1:
3277 free_string_array(argvlist, lastarg);
3278 Py_XDECREF(vals);
3279 Py_XDECREF(keys);
3280 fail_0:
3281 PyMem_Free(path);
3282 return res;
3283}
3284#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003285#endif /* HAVE_SPAWNV */
3286
3287
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003288#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003289PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003290"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003291Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3292\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003293Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003294
3295static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003296posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003297{
Neal Norwitze241ce82003-02-17 18:17:05 +00003298 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003299 if (pid == -1)
3300 return posix_error();
3301 PyOS_AfterFork();
3302 return PyInt_FromLong((long)pid);
3303}
3304#endif
3305
3306
Guido van Rossumad0ee831995-03-01 10:34:45 +00003307#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003308PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003309"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003310Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003311Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003312
Barry Warsaw53699e91996-12-10 23:23:01 +00003313static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003314posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003315{
Neal Norwitze241ce82003-02-17 18:17:05 +00003316 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003317 if (pid == -1)
3318 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003319 if (pid == 0)
3320 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003321 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003322}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003323#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003324
Neal Norwitzb59798b2003-03-21 01:43:31 +00003325/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003326/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3327#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003328#define DEV_PTY_FILE "/dev/ptc"
3329#define HAVE_DEV_PTMX
3330#else
3331#define DEV_PTY_FILE "/dev/ptmx"
3332#endif
3333
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003334#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003335#ifdef HAVE_PTY_H
3336#include <pty.h>
3337#else
3338#ifdef HAVE_LIBUTIL_H
3339#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003340#endif /* HAVE_LIBUTIL_H */
3341#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003342#ifdef HAVE_STROPTS_H
3343#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003344#endif
3345#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003346
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003347#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003348PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003349"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003350Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003351
3352static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003353posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003354{
3355 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003356#ifndef HAVE_OPENPTY
3357 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003358#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003359#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003360 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003361#ifdef sun
Neal Norwitz84a98e02006-04-10 07:44:23 +00003362 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003363#endif
3364#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003365
Thomas Wouters70c21a12000-07-14 14:28:33 +00003366#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003367 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3368 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003369#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003370 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3371 if (slave_name == NULL)
3372 return posix_error();
3373
3374 slave_fd = open(slave_name, O_RDWR);
3375 if (slave_fd < 0)
3376 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003377#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003378 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003379 if (master_fd < 0)
3380 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003381 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003382 /* change permission of slave */
3383 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003384 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003385 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003386 }
3387 /* unlock slave */
3388 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003389 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003390 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003391 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003392 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003393 slave_name = ptsname(master_fd); /* get name of slave */
3394 if (slave_name == NULL)
3395 return posix_error();
3396 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3397 if (slave_fd < 0)
3398 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003399#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003400 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3401 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003402#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003403 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003404#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003405#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003406#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003407
Fred Drake8cef4cf2000-06-28 16:40:38 +00003408 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003409
Fred Drake8cef4cf2000-06-28 16:40:38 +00003410}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003411#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003412
3413#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003414PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003415"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003416Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3417Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003418To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003419
3420static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003421posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003422{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003423 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003424
Fred Drake8cef4cf2000-06-28 16:40:38 +00003425 pid = forkpty(&master_fd, NULL, NULL, NULL);
3426 if (pid == -1)
3427 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003428 if (pid == 0)
3429 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003430 return Py_BuildValue("(ii)", pid, master_fd);
3431}
3432#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003433
Guido van Rossumad0ee831995-03-01 10:34:45 +00003434#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003435PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003436"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003437Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003438
Barry Warsaw53699e91996-12-10 23:23:01 +00003439static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003440posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003441{
Barry Warsaw53699e91996-12-10 23:23:01 +00003442 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003443}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003444#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003445
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003446
Guido van Rossumad0ee831995-03-01 10:34:45 +00003447#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003448PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003449"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003450Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003451
Barry Warsaw53699e91996-12-10 23:23:01 +00003452static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003453posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003454{
Barry Warsaw53699e91996-12-10 23:23:01 +00003455 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003456}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003457#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003458
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003459
Guido van Rossumad0ee831995-03-01 10:34:45 +00003460#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003461PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003462"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003463Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003464
Barry Warsaw53699e91996-12-10 23:23:01 +00003465static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003466posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003467{
Barry Warsaw53699e91996-12-10 23:23:01 +00003468 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003469}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003470#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003471
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003472
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003473PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003474"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003475Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003476
Barry Warsaw53699e91996-12-10 23:23:01 +00003477static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003478posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003479{
Barry Warsaw53699e91996-12-10 23:23:01 +00003480 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003481}
3482
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003483
Fred Drakec9680921999-12-13 16:37:25 +00003484#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003485PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003486"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003487Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003488
3489static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003490posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003491{
3492 PyObject *result = NULL;
3493
Fred Drakec9680921999-12-13 16:37:25 +00003494#ifdef NGROUPS_MAX
3495#define MAX_GROUPS NGROUPS_MAX
3496#else
3497 /* defined to be 16 on Solaris7, so this should be a small number */
3498#define MAX_GROUPS 64
3499#endif
3500 gid_t grouplist[MAX_GROUPS];
3501 int n;
3502
3503 n = getgroups(MAX_GROUPS, grouplist);
3504 if (n < 0)
3505 posix_error();
3506 else {
3507 result = PyList_New(n);
3508 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003509 int i;
3510 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003511 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003512 if (o == NULL) {
3513 Py_DECREF(result);
3514 result = NULL;
3515 break;
3516 }
3517 PyList_SET_ITEM(result, i, o);
3518 }
3519 }
3520 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003521
Fred Drakec9680921999-12-13 16:37:25 +00003522 return result;
3523}
3524#endif
3525
Martin v. Löwis606edc12002-06-13 21:09:11 +00003526#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003527PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003528"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003529Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003530
3531static PyObject *
3532posix_getpgid(PyObject *self, PyObject *args)
3533{
3534 int pid, pgid;
3535 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3536 return NULL;
3537 pgid = getpgid(pid);
3538 if (pgid < 0)
3539 return posix_error();
3540 return PyInt_FromLong((long)pgid);
3541}
3542#endif /* HAVE_GETPGID */
3543
3544
Guido van Rossumb6775db1994-08-01 11:34:53 +00003545#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003546PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003547"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003548Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003549
Barry Warsaw53699e91996-12-10 23:23:01 +00003550static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003551posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003552{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003553#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003554 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003555#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003556 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003557#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003558}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003559#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003560
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003561
Guido van Rossumb6775db1994-08-01 11:34:53 +00003562#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003563PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003564"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003565Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003566
Barry Warsaw53699e91996-12-10 23:23:01 +00003567static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003568posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003569{
Guido van Rossum64933891994-10-20 21:56:42 +00003570#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003571 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003572#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003573 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003574#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003575 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003576 Py_INCREF(Py_None);
3577 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003578}
3579
Guido van Rossumb6775db1994-08-01 11:34:53 +00003580#endif /* HAVE_SETPGRP */
3581
Guido van Rossumad0ee831995-03-01 10:34:45 +00003582#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003583PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003584"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003585Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003586
Barry Warsaw53699e91996-12-10 23:23:01 +00003587static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003588posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003589{
Barry Warsaw53699e91996-12-10 23:23:01 +00003590 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003591}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003592#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003593
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003594
Fred Drake12c6e2d1999-12-14 21:25:03 +00003595#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003596PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003597"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003598Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003599
3600static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003601posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003602{
Neal Norwitze241ce82003-02-17 18:17:05 +00003603 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003604 char *name;
3605 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003606
Fred Drakea30680b2000-12-06 21:24:28 +00003607 errno = 0;
3608 name = getlogin();
3609 if (name == NULL) {
3610 if (errno)
3611 posix_error();
3612 else
3613 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003614 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003615 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003616 else
3617 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003618 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003619
Fred Drake12c6e2d1999-12-14 21:25:03 +00003620 return result;
3621}
3622#endif
3623
Guido van Rossumad0ee831995-03-01 10:34:45 +00003624#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003625PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003626"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003627Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003628
Barry Warsaw53699e91996-12-10 23:23:01 +00003629static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003630posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003631{
Barry Warsaw53699e91996-12-10 23:23:01 +00003632 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003633}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003634#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003635
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003636
Guido van Rossumad0ee831995-03-01 10:34:45 +00003637#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003638PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003639"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003640Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003641
Barry Warsaw53699e91996-12-10 23:23:01 +00003642static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003643posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003644{
3645 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003646 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003647 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003648#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003649 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3650 APIRET rc;
3651 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003652 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003653
3654 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3655 APIRET rc;
3656 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003657 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003658
3659 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003660 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003661#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003662 if (kill(pid, sig) == -1)
3663 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003664#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003665 Py_INCREF(Py_None);
3666 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003667}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003668#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003669
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003670#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003671PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003672"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003673Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003674
3675static PyObject *
3676posix_killpg(PyObject *self, PyObject *args)
3677{
3678 int pgid, sig;
3679 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3680 return NULL;
3681 if (killpg(pgid, sig) == -1)
3682 return posix_error();
3683 Py_INCREF(Py_None);
3684 return Py_None;
3685}
3686#endif
3687
Guido van Rossumc0125471996-06-28 18:55:32 +00003688#ifdef HAVE_PLOCK
3689
3690#ifdef HAVE_SYS_LOCK_H
3691#include <sys/lock.h>
3692#endif
3693
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003694PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003695"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003696Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003697
Barry Warsaw53699e91996-12-10 23:23:01 +00003698static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003699posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003700{
3701 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003702 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003703 return NULL;
3704 if (plock(op) == -1)
3705 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003706 Py_INCREF(Py_None);
3707 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003708}
3709#endif
3710
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003711
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003712#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003713PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003714"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003715Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003716
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003717#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003718#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003719static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003720async_system(const char *command)
3721{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003722 char errormsg[256], args[1024];
3723 RESULTCODES rcodes;
3724 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003725
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003726 char *shell = getenv("COMSPEC");
3727 if (!shell)
3728 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003729
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003730 /* avoid overflowing the argument buffer */
3731 if (strlen(shell) + 3 + strlen(command) >= 1024)
3732 return ERROR_NOT_ENOUGH_MEMORY
3733
3734 args[0] = '\0';
3735 strcat(args, shell);
3736 strcat(args, "/c ");
3737 strcat(args, command);
3738
3739 /* execute asynchronously, inheriting the environment */
3740 rc = DosExecPgm(errormsg,
3741 sizeof(errormsg),
3742 EXEC_ASYNC,
3743 args,
3744 NULL,
3745 &rcodes,
3746 shell);
3747 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003748}
3749
Guido van Rossumd48f2521997-12-05 22:19:34 +00003750static FILE *
3751popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003752{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003753 int oldfd, tgtfd;
3754 HFILE pipeh[2];
3755 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003756
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003757 /* mode determines which of stdin or stdout is reconnected to
3758 * the pipe to the child
3759 */
3760 if (strchr(mode, 'r') != NULL) {
3761 tgt_fd = 1; /* stdout */
3762 } else if (strchr(mode, 'w')) {
3763 tgt_fd = 0; /* stdin */
3764 } else {
3765 *err = ERROR_INVALID_ACCESS;
3766 return NULL;
3767 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003768
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00003769 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003770 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3771 *err = rc;
3772 return NULL;
3773 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003774
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003775 /* prevent other threads accessing stdio */
3776 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003777
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003778 /* reconnect stdio and execute child */
3779 oldfd = dup(tgtfd);
3780 close(tgtfd);
3781 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3782 DosClose(pipeh[tgtfd]);
3783 rc = async_system(command);
3784 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003785
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003786 /* restore stdio */
3787 dup2(oldfd, tgtfd);
3788 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003789
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003790 /* allow other threads access to stdio */
3791 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003792
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003793 /* if execution of child was successful return file stream */
3794 if (rc == NO_ERROR)
3795 return fdopen(pipeh[1 - tgtfd], mode);
3796 else {
3797 DosClose(pipeh[1 - tgtfd]);
3798 *err = rc;
3799 return NULL;
3800 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003801}
3802
3803static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003804posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003805{
3806 char *name;
3807 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003808 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003809 FILE *fp;
3810 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003811 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003812 return NULL;
3813 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003814 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003815 Py_END_ALLOW_THREADS
3816 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003817 return os2_error(err);
3818
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003819 f = PyFile_FromFile(fp, name, mode, fclose);
3820 if (f != NULL)
3821 PyFile_SetBufSize(f, bufsize);
3822 return f;
3823}
3824
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003825#elif defined(PYCC_GCC)
3826
3827/* standard posix version of popen() support */
3828static PyObject *
3829posix_popen(PyObject *self, PyObject *args)
3830{
3831 char *name;
3832 char *mode = "r";
3833 int bufsize = -1;
3834 FILE *fp;
3835 PyObject *f;
3836 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3837 return NULL;
3838 Py_BEGIN_ALLOW_THREADS
3839 fp = popen(name, mode);
3840 Py_END_ALLOW_THREADS
3841 if (fp == NULL)
3842 return posix_error();
3843 f = PyFile_FromFile(fp, name, mode, pclose);
3844 if (f != NULL)
3845 PyFile_SetBufSize(f, bufsize);
3846 return f;
3847}
3848
3849/* fork() under OS/2 has lots'o'warts
3850 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3851 * most of this code is a ripoff of the win32 code, but using the
3852 * capabilities of EMX's C library routines
3853 */
3854
3855/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3856#define POPEN_1 1
3857#define POPEN_2 2
3858#define POPEN_3 3
3859#define POPEN_4 4
3860
3861static PyObject *_PyPopen(char *, int, int, int);
3862static int _PyPclose(FILE *file);
3863
3864/*
3865 * Internal dictionary mapping popen* file pointers to process handles,
3866 * for use when retrieving the process exit code. See _PyPclose() below
3867 * for more information on this dictionary's use.
3868 */
3869static PyObject *_PyPopenProcs = NULL;
3870
3871/* os2emx version of popen2()
3872 *
3873 * The result of this function is a pipe (file) connected to the
3874 * process's stdin, and a pipe connected to the process's stdout.
3875 */
3876
3877static PyObject *
3878os2emx_popen2(PyObject *self, PyObject *args)
3879{
3880 PyObject *f;
3881 int tm=0;
3882
3883 char *cmdstring;
3884 char *mode = "t";
3885 int bufsize = -1;
3886 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3887 return NULL;
3888
3889 if (*mode == 't')
3890 tm = O_TEXT;
3891 else if (*mode != 'b') {
3892 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3893 return NULL;
3894 } else
3895 tm = O_BINARY;
3896
3897 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3898
3899 return f;
3900}
3901
3902/*
3903 * Variation on os2emx.popen2
3904 *
3905 * The result of this function is 3 pipes - the process's stdin,
3906 * stdout and stderr
3907 */
3908
3909static PyObject *
3910os2emx_popen3(PyObject *self, PyObject *args)
3911{
3912 PyObject *f;
3913 int tm = 0;
3914
3915 char *cmdstring;
3916 char *mode = "t";
3917 int bufsize = -1;
3918 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3919 return NULL;
3920
3921 if (*mode == 't')
3922 tm = O_TEXT;
3923 else if (*mode != 'b') {
3924 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3925 return NULL;
3926 } else
3927 tm = O_BINARY;
3928
3929 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3930
3931 return f;
3932}
3933
3934/*
3935 * Variation on os2emx.popen2
3936 *
Tim Peters11b23062003-04-23 02:39:17 +00003937 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003938 * and stdout+stderr combined as a single pipe.
3939 */
3940
3941static PyObject *
3942os2emx_popen4(PyObject *self, PyObject *args)
3943{
3944 PyObject *f;
3945 int tm = 0;
3946
3947 char *cmdstring;
3948 char *mode = "t";
3949 int bufsize = -1;
3950 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3951 return NULL;
3952
3953 if (*mode == 't')
3954 tm = O_TEXT;
3955 else if (*mode != 'b') {
3956 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3957 return NULL;
3958 } else
3959 tm = O_BINARY;
3960
3961 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3962
3963 return f;
3964}
3965
3966/* a couple of structures for convenient handling of multiple
3967 * file handles and pipes
3968 */
3969struct file_ref
3970{
3971 int handle;
3972 int flags;
3973};
3974
3975struct pipe_ref
3976{
3977 int rd;
3978 int wr;
3979};
3980
3981/* The following code is derived from the win32 code */
3982
3983static PyObject *
3984_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3985{
3986 struct file_ref stdio[3];
3987 struct pipe_ref p_fd[3];
3988 FILE *p_s[3];
3989 int file_count, i, pipe_err, pipe_pid;
3990 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3991 PyObject *f, *p_f[3];
3992
3993 /* file modes for subsequent fdopen's on pipe handles */
3994 if (mode == O_TEXT)
3995 {
3996 rd_mode = "rt";
3997 wr_mode = "wt";
3998 }
3999 else
4000 {
4001 rd_mode = "rb";
4002 wr_mode = "wb";
4003 }
4004
4005 /* prepare shell references */
4006 if ((shell = getenv("EMXSHELL")) == NULL)
4007 if ((shell = getenv("COMSPEC")) == NULL)
4008 {
4009 errno = ENOENT;
4010 return posix_error();
4011 }
4012
4013 sh_name = _getname(shell);
4014 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4015 opt = "/c";
4016 else
4017 opt = "-c";
4018
4019 /* save current stdio fds + their flags, and set not inheritable */
4020 i = pipe_err = 0;
4021 while (pipe_err >= 0 && i < 3)
4022 {
4023 pipe_err = stdio[i].handle = dup(i);
4024 stdio[i].flags = fcntl(i, F_GETFD, 0);
4025 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4026 i++;
4027 }
4028 if (pipe_err < 0)
4029 {
4030 /* didn't get them all saved - clean up and bail out */
4031 int saved_err = errno;
4032 while (i-- > 0)
4033 {
4034 close(stdio[i].handle);
4035 }
4036 errno = saved_err;
4037 return posix_error();
4038 }
4039
4040 /* create pipe ends */
4041 file_count = 2;
4042 if (n == POPEN_3)
4043 file_count = 3;
4044 i = pipe_err = 0;
4045 while ((pipe_err == 0) && (i < file_count))
4046 pipe_err = pipe((int *)&p_fd[i++]);
4047 if (pipe_err < 0)
4048 {
4049 /* didn't get them all made - clean up and bail out */
4050 while (i-- > 0)
4051 {
4052 close(p_fd[i].wr);
4053 close(p_fd[i].rd);
4054 }
4055 errno = EPIPE;
4056 return posix_error();
4057 }
4058
4059 /* change the actual standard IO streams over temporarily,
4060 * making the retained pipe ends non-inheritable
4061 */
4062 pipe_err = 0;
4063
4064 /* - stdin */
4065 if (dup2(p_fd[0].rd, 0) == 0)
4066 {
4067 close(p_fd[0].rd);
4068 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4069 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4070 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4071 {
4072 close(p_fd[0].wr);
4073 pipe_err = -1;
4074 }
4075 }
4076 else
4077 {
4078 pipe_err = -1;
4079 }
4080
4081 /* - stdout */
4082 if (pipe_err == 0)
4083 {
4084 if (dup2(p_fd[1].wr, 1) == 1)
4085 {
4086 close(p_fd[1].wr);
4087 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4088 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4089 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4090 {
4091 close(p_fd[1].rd);
4092 pipe_err = -1;
4093 }
4094 }
4095 else
4096 {
4097 pipe_err = -1;
4098 }
4099 }
4100
4101 /* - stderr, as required */
4102 if (pipe_err == 0)
4103 switch (n)
4104 {
4105 case POPEN_3:
4106 {
4107 if (dup2(p_fd[2].wr, 2) == 2)
4108 {
4109 close(p_fd[2].wr);
4110 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4111 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4112 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4113 {
4114 close(p_fd[2].rd);
4115 pipe_err = -1;
4116 }
4117 }
4118 else
4119 {
4120 pipe_err = -1;
4121 }
4122 break;
4123 }
4124
4125 case POPEN_4:
4126 {
4127 if (dup2(1, 2) != 2)
4128 {
4129 pipe_err = -1;
4130 }
4131 break;
4132 }
4133 }
4134
4135 /* spawn the child process */
4136 if (pipe_err == 0)
4137 {
4138 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4139 if (pipe_pid == -1)
4140 {
4141 pipe_err = -1;
4142 }
4143 else
4144 {
4145 /* save the PID into the FILE structure
4146 * NOTE: this implementation doesn't actually
4147 * take advantage of this, but do it for
4148 * completeness - AIM Apr01
4149 */
4150 for (i = 0; i < file_count; i++)
4151 p_s[i]->_pid = pipe_pid;
4152 }
4153 }
4154
4155 /* reset standard IO to normal */
4156 for (i = 0; i < 3; i++)
4157 {
4158 dup2(stdio[i].handle, i);
4159 fcntl(i, F_SETFD, stdio[i].flags);
4160 close(stdio[i].handle);
4161 }
4162
4163 /* if any remnant problems, clean up and bail out */
4164 if (pipe_err < 0)
4165 {
4166 for (i = 0; i < 3; i++)
4167 {
4168 close(p_fd[i].rd);
4169 close(p_fd[i].wr);
4170 }
4171 errno = EPIPE;
4172 return posix_error_with_filename(cmdstring);
4173 }
4174
4175 /* build tuple of file objects to return */
4176 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4177 PyFile_SetBufSize(p_f[0], bufsize);
4178 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4179 PyFile_SetBufSize(p_f[1], bufsize);
4180 if (n == POPEN_3)
4181 {
4182 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4183 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004184 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004185 }
4186 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004187 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004188
4189 /*
4190 * Insert the files we've created into the process dictionary
4191 * all referencing the list with the process handle and the
4192 * initial number of files (see description below in _PyPclose).
4193 * Since if _PyPclose later tried to wait on a process when all
4194 * handles weren't closed, it could create a deadlock with the
4195 * child, we spend some energy here to try to ensure that we
4196 * either insert all file handles into the dictionary or none
4197 * at all. It's a little clumsy with the various popen modes
4198 * and variable number of files involved.
4199 */
4200 if (!_PyPopenProcs)
4201 {
4202 _PyPopenProcs = PyDict_New();
4203 }
4204
4205 if (_PyPopenProcs)
4206 {
4207 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4208 int ins_rc[3];
4209
4210 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4211 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4212
4213 procObj = PyList_New(2);
4214 pidObj = PyInt_FromLong((long) pipe_pid);
4215 intObj = PyInt_FromLong((long) file_count);
4216
4217 if (procObj && pidObj && intObj)
4218 {
4219 PyList_SetItem(procObj, 0, pidObj);
4220 PyList_SetItem(procObj, 1, intObj);
4221
4222 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4223 if (fileObj[0])
4224 {
4225 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4226 fileObj[0],
4227 procObj);
4228 }
4229 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4230 if (fileObj[1])
4231 {
4232 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4233 fileObj[1],
4234 procObj);
4235 }
4236 if (file_count >= 3)
4237 {
4238 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4239 if (fileObj[2])
4240 {
4241 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4242 fileObj[2],
4243 procObj);
4244 }
4245 }
4246
4247 if (ins_rc[0] < 0 || !fileObj[0] ||
4248 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4249 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4250 {
4251 /* Something failed - remove any dictionary
4252 * entries that did make it.
4253 */
4254 if (!ins_rc[0] && fileObj[0])
4255 {
4256 PyDict_DelItem(_PyPopenProcs,
4257 fileObj[0]);
4258 }
4259 if (!ins_rc[1] && fileObj[1])
4260 {
4261 PyDict_DelItem(_PyPopenProcs,
4262 fileObj[1]);
4263 }
4264 if (!ins_rc[2] && fileObj[2])
4265 {
4266 PyDict_DelItem(_PyPopenProcs,
4267 fileObj[2]);
4268 }
4269 }
4270 }
Tim Peters11b23062003-04-23 02:39:17 +00004271
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004272 /*
4273 * Clean up our localized references for the dictionary keys
4274 * and value since PyDict_SetItem will Py_INCREF any copies
4275 * that got placed in the dictionary.
4276 */
4277 Py_XDECREF(procObj);
4278 Py_XDECREF(fileObj[0]);
4279 Py_XDECREF(fileObj[1]);
4280 Py_XDECREF(fileObj[2]);
4281 }
4282
4283 /* Child is launched. */
4284 return f;
4285}
4286
4287/*
4288 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4289 * exit code for the child process and return as a result of the close.
4290 *
4291 * This function uses the _PyPopenProcs dictionary in order to map the
4292 * input file pointer to information about the process that was
4293 * originally created by the popen* call that created the file pointer.
4294 * The dictionary uses the file pointer as a key (with one entry
4295 * inserted for each file returned by the original popen* call) and a
4296 * single list object as the value for all files from a single call.
4297 * The list object contains the Win32 process handle at [0], and a file
4298 * count at [1], which is initialized to the total number of file
4299 * handles using that list.
4300 *
4301 * This function closes whichever handle it is passed, and decrements
4302 * the file count in the dictionary for the process handle pointed to
4303 * by this file. On the last close (when the file count reaches zero),
4304 * this function will wait for the child process and then return its
4305 * exit code as the result of the close() operation. This permits the
4306 * files to be closed in any order - it is always the close() of the
4307 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004308 *
4309 * NOTE: This function is currently called with the GIL released.
4310 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004311 */
4312
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004313static int _PyPclose(FILE *file)
4314{
4315 int result;
4316 int exit_code;
4317 int pipe_pid;
4318 PyObject *procObj, *pidObj, *intObj, *fileObj;
4319 int file_count;
4320#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004321 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004322#endif
4323
4324 /* Close the file handle first, to ensure it can't block the
4325 * child from exiting if it's the last handle.
4326 */
4327 result = fclose(file);
4328
4329#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004330 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004331#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004332 if (_PyPopenProcs)
4333 {
4334 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4335 (procObj = PyDict_GetItem(_PyPopenProcs,
4336 fileObj)) != NULL &&
4337 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4338 (intObj = PyList_GetItem(procObj,1)) != NULL)
4339 {
4340 pipe_pid = (int) PyInt_AsLong(pidObj);
4341 file_count = (int) PyInt_AsLong(intObj);
4342
4343 if (file_count > 1)
4344 {
4345 /* Still other files referencing process */
4346 file_count--;
4347 PyList_SetItem(procObj,1,
4348 PyInt_FromLong((long) file_count));
4349 }
4350 else
4351 {
4352 /* Last file for this process */
4353 if (result != EOF &&
4354 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4355 {
4356 /* extract exit status */
4357 if (WIFEXITED(exit_code))
4358 {
4359 result = WEXITSTATUS(exit_code);
4360 }
4361 else
4362 {
4363 errno = EPIPE;
4364 result = -1;
4365 }
4366 }
4367 else
4368 {
4369 /* Indicate failure - this will cause the file object
4370 * to raise an I/O error and translate the last
4371 * error code from errno. We do have a problem with
4372 * last errors that overlap the normal errno table,
4373 * but that's a consistent problem with the file object.
4374 */
4375 result = -1;
4376 }
4377 }
4378
4379 /* Remove this file pointer from dictionary */
4380 PyDict_DelItem(_PyPopenProcs, fileObj);
4381
4382 if (PyDict_Size(_PyPopenProcs) == 0)
4383 {
4384 Py_DECREF(_PyPopenProcs);
4385 _PyPopenProcs = NULL;
4386 }
4387
4388 } /* if object retrieval ok */
4389
4390 Py_XDECREF(fileObj);
4391 } /* if _PyPopenProcs */
4392
4393#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004394 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004395#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004396 return result;
4397}
4398
4399#endif /* PYCC_??? */
4400
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004401#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004402
4403/*
4404 * Portable 'popen' replacement for Win32.
4405 *
4406 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4407 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004408 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004409 */
4410
4411#include <malloc.h>
4412#include <io.h>
4413#include <fcntl.h>
4414
4415/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4416#define POPEN_1 1
4417#define POPEN_2 2
4418#define POPEN_3 3
4419#define POPEN_4 4
4420
4421static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004422static int _PyPclose(FILE *file);
4423
4424/*
4425 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004426 * for use when retrieving the process exit code. See _PyPclose() below
4427 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004428 */
4429static PyObject *_PyPopenProcs = NULL;
4430
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004431
4432/* popen that works from a GUI.
4433 *
4434 * The result of this function is a pipe (file) connected to the
4435 * processes stdin or stdout, depending on the requested mode.
4436 */
4437
4438static PyObject *
4439posix_popen(PyObject *self, PyObject *args)
4440{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004441 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004442 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004443
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004444 char *cmdstring;
4445 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004446 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004447 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004448 return NULL;
4449
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004450 if (*mode == 'r')
4451 tm = _O_RDONLY;
4452 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004453 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004454 return NULL;
4455 } else
4456 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004457
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004458 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004459 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004460 return NULL;
4461 }
4462
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004463 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004464 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004465 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004466 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004467 else
4468 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4469
4470 return f;
4471}
4472
4473/* Variation on win32pipe.popen
4474 *
4475 * The result of this function is a pipe (file) connected to the
4476 * process's stdin, and a pipe connected to the process's stdout.
4477 */
4478
4479static PyObject *
4480win32_popen2(PyObject *self, PyObject *args)
4481{
4482 PyObject *f;
4483 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004484
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004485 char *cmdstring;
4486 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004487 int bufsize = -1;
4488 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004489 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004490
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004491 if (*mode == 't')
4492 tm = _O_TEXT;
4493 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004494 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004495 return NULL;
4496 } else
4497 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004498
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004499 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004500 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004501 return NULL;
4502 }
4503
4504 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004505
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004506 return f;
4507}
4508
4509/*
4510 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004511 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004512 * The result of this function is 3 pipes - the process's stdin,
4513 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004514 */
4515
4516static PyObject *
4517win32_popen3(PyObject *self, PyObject *args)
4518{
4519 PyObject *f;
4520 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004521
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004522 char *cmdstring;
4523 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004524 int bufsize = -1;
4525 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004526 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004527
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004528 if (*mode == 't')
4529 tm = _O_TEXT;
4530 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004531 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004532 return NULL;
4533 } else
4534 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004535
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004536 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004537 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004538 return NULL;
4539 }
4540
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004541 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004542
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004543 return f;
4544}
4545
4546/*
4547 * Variation on win32pipe.popen
4548 *
Tim Peters5aa91602002-01-30 05:46:57 +00004549 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004550 * and stdout+stderr combined as a single pipe.
4551 */
4552
4553static PyObject *
4554win32_popen4(PyObject *self, PyObject *args)
4555{
4556 PyObject *f;
4557 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004558
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004559 char *cmdstring;
4560 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004561 int bufsize = -1;
4562 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004563 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004564
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004565 if (*mode == 't')
4566 tm = _O_TEXT;
4567 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004568 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004569 return NULL;
4570 } else
4571 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004572
4573 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004574 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004575 return NULL;
4576 }
4577
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004578 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004579
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004580 return f;
4581}
4582
Mark Hammond08501372001-01-31 07:30:29 +00004583static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004584_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004585 HANDLE hStdin,
4586 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004587 HANDLE hStderr,
4588 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004589{
4590 PROCESS_INFORMATION piProcInfo;
4591 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004592 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004593 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004594 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004595 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004596 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004597
4598 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004599 char *comshell;
4600
Tim Peters92e4dd82002-10-05 01:47:34 +00004601 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004602 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004603 /* x < i, so x fits into an integer */
4604 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004605
4606 /* Explicitly check if we are using COMMAND.COM. If we are
4607 * then use the w9xpopen hack.
4608 */
4609 comshell = s1 + x;
4610 while (comshell >= s1 && *comshell != '\\')
4611 --comshell;
4612 ++comshell;
4613
4614 if (GetVersion() < 0x80000000 &&
4615 _stricmp(comshell, "command.com") != 0) {
4616 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004617 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004618 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004619 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004620 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004621 }
4622 else {
4623 /*
Tim Peters402d5982001-08-27 06:37:48 +00004624 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4625 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004626 */
Mark Hammond08501372001-01-31 07:30:29 +00004627 char modulepath[_MAX_PATH];
4628 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004629 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Martin v. Löwis26fd9602006-04-22 11:15:41 +00004630 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004631 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004632 x = i+1;
4633 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004634 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004635 strncat(modulepath,
4636 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004637 (sizeof(modulepath)/sizeof(modulepath[0]))
4638 -strlen(modulepath));
4639 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004640 /* Eeek - file-not-found - possibly an embedding
4641 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004642 */
Tim Peters5aa91602002-01-30 05:46:57 +00004643 strncpy(modulepath,
4644 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004645 sizeof(modulepath)/sizeof(modulepath[0]));
4646 if (modulepath[strlen(modulepath)-1] != '\\')
4647 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004648 strncat(modulepath,
4649 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004650 (sizeof(modulepath)/sizeof(modulepath[0]))
4651 -strlen(modulepath));
4652 /* No where else to look - raise an easily identifiable
4653 error, rather than leaving Windows to report
4654 "file not found" - as the user is probably blissfully
4655 unaware this shim EXE is used, and it will confuse them.
4656 (well, it confused me for a while ;-)
4657 */
4658 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004659 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004660 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004661 "for popen to work with your shell "
4662 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004663 szConsoleSpawn);
4664 return FALSE;
4665 }
4666 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004667 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004668 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004669 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004670
Tim Peters92e4dd82002-10-05 01:47:34 +00004671 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004672 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004673 /* To maintain correct argument passing semantics,
4674 we pass the command-line as it stands, and allow
4675 quoting to be applied. w9xpopen.exe will then
4676 use its argv vector, and re-quote the necessary
4677 args for the ultimate child process.
4678 */
Tim Peters75cdad52001-11-28 22:07:30 +00004679 PyOS_snprintf(
4680 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004681 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004682 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004683 s1,
4684 s3,
4685 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004686 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004687 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004688 dialog:
4689 "Your program accessed mem currently in use at xxx"
4690 and a hopeful warning about the stability of your
4691 system.
4692 Cost is Ctrl+C wont kill children, but anyone
4693 who cares can have a go!
4694 */
4695 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004696 }
4697 }
4698
4699 /* Could be an else here to try cmd.exe / command.com in the path
4700 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004701 else {
Tim Peters402d5982001-08-27 06:37:48 +00004702 PyErr_SetString(PyExc_RuntimeError,
4703 "Cannot locate a COMSPEC environment variable to "
4704 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004705 return FALSE;
4706 }
Tim Peters5aa91602002-01-30 05:46:57 +00004707
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004708 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4709 siStartInfo.cb = sizeof(STARTUPINFO);
4710 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4711 siStartInfo.hStdInput = hStdin;
4712 siStartInfo.hStdOutput = hStdout;
4713 siStartInfo.hStdError = hStderr;
4714 siStartInfo.wShowWindow = SW_HIDE;
4715
4716 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004717 s2,
4718 NULL,
4719 NULL,
4720 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004721 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004722 NULL,
4723 NULL,
4724 &siStartInfo,
4725 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004726 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004727 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004728
Mark Hammondb37a3732000-08-14 04:47:33 +00004729 /* Return process handle */
4730 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004731 return TRUE;
4732 }
Tim Peters402d5982001-08-27 06:37:48 +00004733 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004734 return FALSE;
4735}
4736
4737/* The following code is based off of KB: Q190351 */
4738
4739static PyObject *
4740_PyPopen(char *cmdstring, int mode, int n)
4741{
4742 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4743 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004744 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004745
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004746 SECURITY_ATTRIBUTES saAttr;
4747 BOOL fSuccess;
4748 int fd1, fd2, fd3;
4749 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004750 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004751 PyObject *f;
4752
4753 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4754 saAttr.bInheritHandle = TRUE;
4755 saAttr.lpSecurityDescriptor = NULL;
4756
4757 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4758 return win32_error("CreatePipe", NULL);
4759
4760 /* Create new output read handle and the input write handle. Set
4761 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004762 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004763 * being created. */
4764 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004765 GetCurrentProcess(), &hChildStdinWrDup, 0,
4766 FALSE,
4767 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004768 if (!fSuccess)
4769 return win32_error("DuplicateHandle", NULL);
4770
4771 /* Close the inheritable version of ChildStdin
4772 that we're using. */
4773 CloseHandle(hChildStdinWr);
4774
4775 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4776 return win32_error("CreatePipe", NULL);
4777
4778 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004779 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4780 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004781 if (!fSuccess)
4782 return win32_error("DuplicateHandle", NULL);
4783
4784 /* Close the inheritable version of ChildStdout
4785 that we're using. */
4786 CloseHandle(hChildStdoutRd);
4787
4788 if (n != POPEN_4) {
4789 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4790 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004791 fSuccess = DuplicateHandle(GetCurrentProcess(),
4792 hChildStderrRd,
4793 GetCurrentProcess(),
4794 &hChildStderrRdDup, 0,
4795 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004796 if (!fSuccess)
4797 return win32_error("DuplicateHandle", NULL);
4798 /* Close the inheritable version of ChildStdErr that we're using. */
4799 CloseHandle(hChildStderrRd);
4800 }
Tim Peters5aa91602002-01-30 05:46:57 +00004801
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004802 switch (n) {
4803 case POPEN_1:
4804 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4805 case _O_WRONLY | _O_TEXT:
4806 /* Case for writing to child Stdin in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004807 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004808 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004809 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004810 PyFile_SetBufSize(f, 0);
4811 /* We don't care about these pipes anymore, so close them. */
4812 CloseHandle(hChildStdoutRdDup);
4813 CloseHandle(hChildStderrRdDup);
4814 break;
4815
4816 case _O_RDONLY | _O_TEXT:
4817 /* Case for reading from child Stdout in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004818 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004819 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004820 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004821 PyFile_SetBufSize(f, 0);
4822 /* We don't care about these pipes anymore, so close them. */
4823 CloseHandle(hChildStdinWrDup);
4824 CloseHandle(hChildStderrRdDup);
4825 break;
4826
4827 case _O_RDONLY | _O_BINARY:
4828 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004829 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004830 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004831 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004832 PyFile_SetBufSize(f, 0);
4833 /* We don't care about these pipes anymore, so close them. */
4834 CloseHandle(hChildStdinWrDup);
4835 CloseHandle(hChildStderrRdDup);
4836 break;
4837
4838 case _O_WRONLY | _O_BINARY:
4839 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004840 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004841 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004842 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004843 PyFile_SetBufSize(f, 0);
4844 /* We don't care about these pipes anymore, so close them. */
4845 CloseHandle(hChildStdoutRdDup);
4846 CloseHandle(hChildStderrRdDup);
4847 break;
4848 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004849 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004850 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004851
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004852 case POPEN_2:
4853 case POPEN_4:
4854 {
4855 char *m1, *m2;
4856 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004857
Tim Peters7dca21e2002-08-19 00:42:29 +00004858 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004859 m1 = "r";
4860 m2 = "w";
4861 } else {
4862 m1 = "rb";
4863 m2 = "wb";
4864 }
4865
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004866 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004867 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004868 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004869 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004870 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004871 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004872 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004873 PyFile_SetBufSize(p2, 0);
4874
4875 if (n != 4)
4876 CloseHandle(hChildStderrRdDup);
4877
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004878 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004879 Py_XDECREF(p1);
4880 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004881 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004882 break;
4883 }
Tim Peters5aa91602002-01-30 05:46:57 +00004884
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004885 case POPEN_3:
4886 {
4887 char *m1, *m2;
4888 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004889
Tim Peters7dca21e2002-08-19 00:42:29 +00004890 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004891 m1 = "r";
4892 m2 = "w";
4893 } else {
4894 m1 = "rb";
4895 m2 = "wb";
4896 }
4897
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004898 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004899 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004900 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004901 f2 = _fdopen(fd2, m1);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004902 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004903 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004904 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004905 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4906 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004907 PyFile_SetBufSize(p1, 0);
4908 PyFile_SetBufSize(p2, 0);
4909 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004910 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004911 Py_XDECREF(p1);
4912 Py_XDECREF(p2);
4913 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004914 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004915 break;
4916 }
4917 }
4918
4919 if (n == POPEN_4) {
4920 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004921 hChildStdinRd,
4922 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004923 hChildStdoutWr,
4924 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004925 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004926 }
4927 else {
4928 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004929 hChildStdinRd,
4930 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004931 hChildStderrWr,
4932 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004933 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004934 }
4935
Mark Hammondb37a3732000-08-14 04:47:33 +00004936 /*
4937 * Insert the files we've created into the process dictionary
4938 * all referencing the list with the process handle and the
4939 * initial number of files (see description below in _PyPclose).
4940 * Since if _PyPclose later tried to wait on a process when all
4941 * handles weren't closed, it could create a deadlock with the
4942 * child, we spend some energy here to try to ensure that we
4943 * either insert all file handles into the dictionary or none
4944 * at all. It's a little clumsy with the various popen modes
4945 * and variable number of files involved.
4946 */
4947 if (!_PyPopenProcs) {
4948 _PyPopenProcs = PyDict_New();
4949 }
4950
4951 if (_PyPopenProcs) {
4952 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4953 int ins_rc[3];
4954
4955 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4956 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4957
4958 procObj = PyList_New(2);
4959 hProcessObj = PyLong_FromVoidPtr(hProcess);
4960 intObj = PyInt_FromLong(file_count);
4961
4962 if (procObj && hProcessObj && intObj) {
4963 PyList_SetItem(procObj,0,hProcessObj);
4964 PyList_SetItem(procObj,1,intObj);
4965
4966 fileObj[0] = PyLong_FromVoidPtr(f1);
4967 if (fileObj[0]) {
4968 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4969 fileObj[0],
4970 procObj);
4971 }
4972 if (file_count >= 2) {
4973 fileObj[1] = PyLong_FromVoidPtr(f2);
4974 if (fileObj[1]) {
4975 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4976 fileObj[1],
4977 procObj);
4978 }
4979 }
4980 if (file_count >= 3) {
4981 fileObj[2] = PyLong_FromVoidPtr(f3);
4982 if (fileObj[2]) {
4983 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4984 fileObj[2],
4985 procObj);
4986 }
4987 }
4988
4989 if (ins_rc[0] < 0 || !fileObj[0] ||
4990 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4991 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4992 /* Something failed - remove any dictionary
4993 * entries that did make it.
4994 */
4995 if (!ins_rc[0] && fileObj[0]) {
4996 PyDict_DelItem(_PyPopenProcs,
4997 fileObj[0]);
4998 }
4999 if (!ins_rc[1] && fileObj[1]) {
5000 PyDict_DelItem(_PyPopenProcs,
5001 fileObj[1]);
5002 }
5003 if (!ins_rc[2] && fileObj[2]) {
5004 PyDict_DelItem(_PyPopenProcs,
5005 fileObj[2]);
5006 }
5007 }
5008 }
Tim Peters5aa91602002-01-30 05:46:57 +00005009
Mark Hammondb37a3732000-08-14 04:47:33 +00005010 /*
5011 * Clean up our localized references for the dictionary keys
5012 * and value since PyDict_SetItem will Py_INCREF any copies
5013 * that got placed in the dictionary.
5014 */
5015 Py_XDECREF(procObj);
5016 Py_XDECREF(fileObj[0]);
5017 Py_XDECREF(fileObj[1]);
5018 Py_XDECREF(fileObj[2]);
5019 }
5020
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005021 /* Child is launched. Close the parents copy of those pipe
5022 * handles that only the child should have open. You need to
5023 * make sure that no handles to the write end of the output pipe
5024 * are maintained in this process or else the pipe will not close
5025 * when the child process exits and the ReadFile will hang. */
5026
5027 if (!CloseHandle(hChildStdinRd))
5028 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005029
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005030 if (!CloseHandle(hChildStdoutWr))
5031 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005032
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005033 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5034 return win32_error("CloseHandle", NULL);
5035
5036 return f;
5037}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005038
5039/*
5040 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5041 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005042 *
5043 * This function uses the _PyPopenProcs dictionary in order to map the
5044 * input file pointer to information about the process that was
5045 * originally created by the popen* call that created the file pointer.
5046 * The dictionary uses the file pointer as a key (with one entry
5047 * inserted for each file returned by the original popen* call) and a
5048 * single list object as the value for all files from a single call.
5049 * The list object contains the Win32 process handle at [0], and a file
5050 * count at [1], which is initialized to the total number of file
5051 * handles using that list.
5052 *
5053 * This function closes whichever handle it is passed, and decrements
5054 * the file count in the dictionary for the process handle pointed to
5055 * by this file. On the last close (when the file count reaches zero),
5056 * this function will wait for the child process and then return its
5057 * exit code as the result of the close() operation. This permits the
5058 * files to be closed in any order - it is always the close() of the
5059 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005060 *
5061 * NOTE: This function is currently called with the GIL released.
5062 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005063 */
Tim Peters736aa322000-09-01 06:51:24 +00005064
Fredrik Lundh56055a42000-07-23 19:47:12 +00005065static int _PyPclose(FILE *file)
5066{
Fredrik Lundh20318932000-07-26 17:29:12 +00005067 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005068 DWORD exit_code;
5069 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00005070 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5071 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005072#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005073 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005074#endif
5075
Fredrik Lundh20318932000-07-26 17:29:12 +00005076 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00005077 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00005078 */
5079 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005080#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005081 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005082#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005083 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005084 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5085 (procObj = PyDict_GetItem(_PyPopenProcs,
5086 fileObj)) != NULL &&
5087 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5088 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5089
5090 hProcess = PyLong_AsVoidPtr(hProcessObj);
5091 file_count = PyInt_AsLong(intObj);
5092
5093 if (file_count > 1) {
5094 /* Still other files referencing process */
5095 file_count--;
5096 PyList_SetItem(procObj,1,
5097 PyInt_FromLong(file_count));
5098 } else {
5099 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00005100 if (result != EOF &&
5101 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5102 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00005103 /* Possible truncation here in 16-bit environments, but
5104 * real exit codes are just the lower byte in any event.
5105 */
5106 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005107 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00005108 /* Indicate failure - this will cause the file object
5109 * to raise an I/O error and translate the last Win32
5110 * error code from errno. We do have a problem with
5111 * last errors that overlap the normal errno table,
5112 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005113 */
Fredrik Lundh20318932000-07-26 17:29:12 +00005114 if (result != EOF) {
5115 /* If the error wasn't from the fclose(), then
5116 * set errno for the file object error handling.
5117 */
5118 errno = GetLastError();
5119 }
5120 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005121 }
5122
5123 /* Free up the native handle at this point */
5124 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00005125 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005126
Mark Hammondb37a3732000-08-14 04:47:33 +00005127 /* Remove this file pointer from dictionary */
5128 PyDict_DelItem(_PyPopenProcs, fileObj);
5129
5130 if (PyDict_Size(_PyPopenProcs) == 0) {
5131 Py_DECREF(_PyPopenProcs);
5132 _PyPopenProcs = NULL;
5133 }
5134
5135 } /* if object retrieval ok */
5136
5137 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005138 } /* if _PyPopenProcs */
5139
Tim Peters736aa322000-09-01 06:51:24 +00005140#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005141 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005142#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005143 return result;
5144}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005145
5146#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005147static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005148posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005149{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005150 char *name;
5151 char *mode = "r";
5152 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00005153 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005154 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005155 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00005156 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00005157 /* Strip mode of binary or text modifiers */
5158 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5159 mode = "r";
5160 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5161 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00005162 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005163 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005164 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00005165 if (fp == NULL)
5166 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005167 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005168 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005169 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005170 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005171}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005172
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005173#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005174#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005175
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005176
Guido van Rossumb6775db1994-08-01 11:34:53 +00005177#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005178PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005179"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005180Set the current process's user id.");
5181
Barry Warsaw53699e91996-12-10 23:23:01 +00005182static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005183posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005184{
5185 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005186 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005187 return NULL;
5188 if (setuid(uid) < 0)
5189 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005190 Py_INCREF(Py_None);
5191 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005192}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005193#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005194
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005195
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005196#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005197PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005198"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005199Set the current process's effective user id.");
5200
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005201static PyObject *
5202posix_seteuid (PyObject *self, PyObject *args)
5203{
5204 int euid;
5205 if (!PyArg_ParseTuple(args, "i", &euid)) {
5206 return NULL;
5207 } else if (seteuid(euid) < 0) {
5208 return posix_error();
5209 } else {
5210 Py_INCREF(Py_None);
5211 return Py_None;
5212 }
5213}
5214#endif /* HAVE_SETEUID */
5215
5216#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005217PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005218"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005219Set the current process's effective group id.");
5220
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005221static PyObject *
5222posix_setegid (PyObject *self, PyObject *args)
5223{
5224 int egid;
5225 if (!PyArg_ParseTuple(args, "i", &egid)) {
5226 return NULL;
5227 } else if (setegid(egid) < 0) {
5228 return posix_error();
5229 } else {
5230 Py_INCREF(Py_None);
5231 return Py_None;
5232 }
5233}
5234#endif /* HAVE_SETEGID */
5235
5236#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005237PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005238"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005239Set the current process's real and effective user ids.");
5240
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005241static PyObject *
5242posix_setreuid (PyObject *self, PyObject *args)
5243{
5244 int ruid, euid;
5245 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
5246 return NULL;
5247 } else if (setreuid(ruid, euid) < 0) {
5248 return posix_error();
5249 } else {
5250 Py_INCREF(Py_None);
5251 return Py_None;
5252 }
5253}
5254#endif /* HAVE_SETREUID */
5255
5256#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005257PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005258"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005259Set the current process's real and effective group ids.");
5260
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005261static PyObject *
5262posix_setregid (PyObject *self, PyObject *args)
5263{
5264 int rgid, egid;
5265 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
5266 return NULL;
5267 } else if (setregid(rgid, egid) < 0) {
5268 return posix_error();
5269 } else {
5270 Py_INCREF(Py_None);
5271 return Py_None;
5272 }
5273}
5274#endif /* HAVE_SETREGID */
5275
Guido van Rossumb6775db1994-08-01 11:34:53 +00005276#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005277PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005278"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005279Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005280
Barry Warsaw53699e91996-12-10 23:23:01 +00005281static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005282posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005283{
5284 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005285 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005286 return NULL;
5287 if (setgid(gid) < 0)
5288 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005289 Py_INCREF(Py_None);
5290 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005291}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005292#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005293
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005294#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005295PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005296"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005297Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005298
5299static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005300posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005301{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005302 int i, len;
5303 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005304
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005305 if (!PySequence_Check(groups)) {
5306 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5307 return NULL;
5308 }
5309 len = PySequence_Size(groups);
5310 if (len > MAX_GROUPS) {
5311 PyErr_SetString(PyExc_ValueError, "too many groups");
5312 return NULL;
5313 }
5314 for(i = 0; i < len; i++) {
5315 PyObject *elem;
5316 elem = PySequence_GetItem(groups, i);
5317 if (!elem)
5318 return NULL;
5319 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005320 if (!PyLong_Check(elem)) {
5321 PyErr_SetString(PyExc_TypeError,
5322 "groups must be integers");
5323 Py_DECREF(elem);
5324 return NULL;
5325 } else {
5326 unsigned long x = PyLong_AsUnsignedLong(elem);
5327 if (PyErr_Occurred()) {
5328 PyErr_SetString(PyExc_TypeError,
5329 "group id too big");
5330 Py_DECREF(elem);
5331 return NULL;
5332 }
5333 grouplist[i] = x;
5334 /* read back the value to see if it fitted in gid_t */
5335 if (grouplist[i] != x) {
5336 PyErr_SetString(PyExc_TypeError,
5337 "group id too big");
5338 Py_DECREF(elem);
5339 return NULL;
5340 }
5341 }
5342 } else {
5343 long x = PyInt_AsLong(elem);
5344 grouplist[i] = x;
5345 if (grouplist[i] != x) {
5346 PyErr_SetString(PyExc_TypeError,
5347 "group id too big");
5348 Py_DECREF(elem);
5349 return NULL;
5350 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005351 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005352 Py_DECREF(elem);
5353 }
5354
5355 if (setgroups(len, grouplist) < 0)
5356 return posix_error();
5357 Py_INCREF(Py_None);
5358 return Py_None;
5359}
5360#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005361
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005362#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005363static PyObject *
5364wait_helper(int pid, int status, struct rusage *ru)
5365{
5366 PyObject *result;
5367 static PyObject *struct_rusage;
5368
5369 if (pid == -1)
5370 return posix_error();
5371
5372 if (struct_rusage == NULL) {
5373 PyObject *m = PyImport_ImportModule("resource");
5374 if (m == NULL)
5375 return NULL;
5376 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5377 Py_DECREF(m);
5378 if (struct_rusage == NULL)
5379 return NULL;
5380 }
5381
5382 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5383 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5384 if (!result)
5385 return NULL;
5386
5387#ifndef doubletime
5388#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5389#endif
5390
5391 PyStructSequence_SET_ITEM(result, 0,
5392 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5393 PyStructSequence_SET_ITEM(result, 1,
5394 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5395#define SET_INT(result, index, value)\
5396 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5397 SET_INT(result, 2, ru->ru_maxrss);
5398 SET_INT(result, 3, ru->ru_ixrss);
5399 SET_INT(result, 4, ru->ru_idrss);
5400 SET_INT(result, 5, ru->ru_isrss);
5401 SET_INT(result, 6, ru->ru_minflt);
5402 SET_INT(result, 7, ru->ru_majflt);
5403 SET_INT(result, 8, ru->ru_nswap);
5404 SET_INT(result, 9, ru->ru_inblock);
5405 SET_INT(result, 10, ru->ru_oublock);
5406 SET_INT(result, 11, ru->ru_msgsnd);
5407 SET_INT(result, 12, ru->ru_msgrcv);
5408 SET_INT(result, 13, ru->ru_nsignals);
5409 SET_INT(result, 14, ru->ru_nvcsw);
5410 SET_INT(result, 15, ru->ru_nivcsw);
5411#undef SET_INT
5412
5413 if (PyErr_Occurred()) {
5414 Py_DECREF(result);
5415 return NULL;
5416 }
5417
Neal Norwitz9b00a562006-03-20 08:47:12 +00005418 return Py_BuildValue("iiN", pid, status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005419}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005420#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005421
5422#ifdef HAVE_WAIT3
5423PyDoc_STRVAR(posix_wait3__doc__,
5424"wait3(options) -> (pid, status, rusage)\n\n\
5425Wait for completion of a child process.");
5426
5427static PyObject *
5428posix_wait3(PyObject *self, PyObject *args)
5429{
5430 int pid, options;
5431 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005432 WAIT_TYPE status;
5433 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005434
5435 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5436 return NULL;
5437
5438 Py_BEGIN_ALLOW_THREADS
5439 pid = wait3(&status, options, &ru);
5440 Py_END_ALLOW_THREADS
5441
Neal Norwitzd5a37542006-03-20 06:48:34 +00005442 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005443}
5444#endif /* HAVE_WAIT3 */
5445
5446#ifdef HAVE_WAIT4
5447PyDoc_STRVAR(posix_wait4__doc__,
5448"wait4(pid, options) -> (pid, status, rusage)\n\n\
5449Wait for completion of a given child process.");
5450
5451static PyObject *
5452posix_wait4(PyObject *self, PyObject *args)
5453{
5454 int pid, options;
5455 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005456 WAIT_TYPE status;
5457 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005458
5459 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5460 return NULL;
5461
5462 Py_BEGIN_ALLOW_THREADS
5463 pid = wait4(pid, &status, options, &ru);
5464 Py_END_ALLOW_THREADS
5465
Neal Norwitzd5a37542006-03-20 06:48:34 +00005466 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005467}
5468#endif /* HAVE_WAIT4 */
5469
Guido van Rossumb6775db1994-08-01 11:34:53 +00005470#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005471PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005472"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005473Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005474
Barry Warsaw53699e91996-12-10 23:23:01 +00005475static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005476posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005477{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005478 int pid, options;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005479 WAIT_TYPE status;
5480 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005481
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005482 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005483 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005484 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005485 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005486 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005487 if (pid == -1)
5488 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005489
5490 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005491}
5492
Tim Petersab034fa2002-02-01 11:27:43 +00005493#elif defined(HAVE_CWAIT)
5494
5495/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005496PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005497"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005498"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005499
5500static PyObject *
5501posix_waitpid(PyObject *self, PyObject *args)
5502{
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005503 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005504 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005505
5506 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5507 return NULL;
5508 Py_BEGIN_ALLOW_THREADS
5509 pid = _cwait(&status, pid, options);
5510 Py_END_ALLOW_THREADS
5511 if (pid == -1)
5512 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005513
5514 /* shift the status left a byte so this is more like the POSIX waitpid */
5515 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005516}
5517#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005518
Guido van Rossumad0ee831995-03-01 10:34:45 +00005519#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005520PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005521"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005522Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005523
Barry Warsaw53699e91996-12-10 23:23:01 +00005524static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005525posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005526{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005527 int pid;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005528 WAIT_TYPE status;
5529 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005530
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005531 Py_BEGIN_ALLOW_THREADS
5532 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005533 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005534 if (pid == -1)
5535 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005536
5537 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005538}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005539#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005540
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005541
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005542PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005543"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005544Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005545
Barry Warsaw53699e91996-12-10 23:23:01 +00005546static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005547posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005548{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005549#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005550 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005551#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005552#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005553 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005554#else
5555 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5556#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005557#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005558}
5559
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005560
Guido van Rossumb6775db1994-08-01 11:34:53 +00005561#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005562PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005563"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005564Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005565
Barry Warsaw53699e91996-12-10 23:23:01 +00005566static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005567posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005568{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005569 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005570 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005571 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005572 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005573 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005574 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005575 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005576 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005577 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005578 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00005579 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005580}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005581#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005582
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005583
Guido van Rossumb6775db1994-08-01 11:34:53 +00005584#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005585PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005586"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005587Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005588
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005589static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005590posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005591{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00005592 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005593}
5594#endif /* HAVE_SYMLINK */
5595
5596
5597#ifdef HAVE_TIMES
5598#ifndef HZ
5599#define HZ 60 /* Universal constant :-) */
5600#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005601
Guido van Rossumd48f2521997-12-05 22:19:34 +00005602#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5603static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005604system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005605{
5606 ULONG value = 0;
5607
5608 Py_BEGIN_ALLOW_THREADS
5609 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5610 Py_END_ALLOW_THREADS
5611
5612 return value;
5613}
5614
5615static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005616posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005617{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005618 /* Currently Only Uptime is Provided -- Others Later */
5619 return Py_BuildValue("ddddd",
5620 (double)0 /* t.tms_utime / HZ */,
5621 (double)0 /* t.tms_stime / HZ */,
5622 (double)0 /* t.tms_cutime / HZ */,
5623 (double)0 /* t.tms_cstime / HZ */,
5624 (double)system_uptime() / 1000);
5625}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005626#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005627static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005628posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005629{
5630 struct tms t;
5631 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005632 errno = 0;
5633 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005634 if (c == (clock_t) -1)
5635 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005636 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005637 (double)t.tms_utime / HZ,
5638 (double)t.tms_stime / HZ,
5639 (double)t.tms_cutime / HZ,
5640 (double)t.tms_cstime / HZ,
5641 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005642}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005643#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005644#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005645
5646
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005647#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005648#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005649static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005650posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005651{
5652 FILETIME create, exit, kernel, user;
5653 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005654 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005655 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5656 /* The fields of a FILETIME structure are the hi and lo part
5657 of a 64-bit value expressed in 100 nanosecond units.
5658 1e7 is one second in such units; 1e-7 the inverse.
5659 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5660 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005661 return Py_BuildValue(
5662 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005663 (double)(kernel.dwHighDateTime*429.4967296 +
5664 kernel.dwLowDateTime*1e-7),
5665 (double)(user.dwHighDateTime*429.4967296 +
5666 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005667 (double)0,
5668 (double)0,
5669 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005670}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005671#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005672
5673#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005674PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005675"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005676Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005677#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005678
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005679
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005680#ifdef HAVE_GETSID
5681PyDoc_STRVAR(posix_getsid__doc__,
5682"getsid(pid) -> sid\n\n\
5683Call the system call getsid().");
5684
5685static PyObject *
5686posix_getsid(PyObject *self, PyObject *args)
5687{
5688 int pid, sid;
5689 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5690 return NULL;
5691 sid = getsid(pid);
5692 if (sid < 0)
5693 return posix_error();
5694 return PyInt_FromLong((long)sid);
5695}
5696#endif /* HAVE_GETSID */
5697
5698
Guido van Rossumb6775db1994-08-01 11:34:53 +00005699#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005700PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005701"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005702Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005703
Barry Warsaw53699e91996-12-10 23:23:01 +00005704static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005705posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005706{
Guido van Rossum687dd131993-05-17 08:34:16 +00005707 if (setsid() < 0)
5708 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005709 Py_INCREF(Py_None);
5710 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005711}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005712#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005713
Guido van Rossumb6775db1994-08-01 11:34:53 +00005714#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005715PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005716"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005717Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005718
Barry Warsaw53699e91996-12-10 23:23:01 +00005719static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005720posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005721{
5722 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005723 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005724 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005725 if (setpgid(pid, pgrp) < 0)
5726 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005727 Py_INCREF(Py_None);
5728 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005729}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005730#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005731
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005732
Guido van Rossumb6775db1994-08-01 11:34:53 +00005733#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005734PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005735"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005736Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005737
Barry Warsaw53699e91996-12-10 23:23:01 +00005738static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005739posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005740{
5741 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005742 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005743 return NULL;
5744 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005745 if (pgid < 0)
5746 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005747 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005748}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005749#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005750
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005751
Guido van Rossumb6775db1994-08-01 11:34:53 +00005752#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005753PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005754"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005755Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005756
Barry Warsaw53699e91996-12-10 23:23:01 +00005757static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005758posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005759{
5760 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005761 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005762 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005763 if (tcsetpgrp(fd, pgid) < 0)
5764 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005765 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005766 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005767}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005768#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005769
Guido van Rossum687dd131993-05-17 08:34:16 +00005770/* Functions acting on file descriptors */
5771
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005772PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005773"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005774Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005775
Barry Warsaw53699e91996-12-10 23:23:01 +00005776static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005777posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005778{
Mark Hammondef8b6542001-05-13 08:04:26 +00005779 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005780 int flag;
5781 int mode = 0777;
5782 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005783
5784#ifdef MS_WINDOWS
5785 if (unicode_file_names()) {
5786 PyUnicodeObject *po;
5787 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5788 Py_BEGIN_ALLOW_THREADS
5789 /* PyUnicode_AS_UNICODE OK without thread
5790 lock as it is a simple dereference. */
5791 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5792 Py_END_ALLOW_THREADS
5793 if (fd < 0)
5794 return posix_error();
5795 return PyInt_FromLong((long)fd);
5796 }
5797 /* Drop the argument parsing error as narrow strings
5798 are also valid. */
5799 PyErr_Clear();
5800 }
5801#endif
5802
Tim Peters5aa91602002-01-30 05:46:57 +00005803 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005804 Py_FileSystemDefaultEncoding, &file,
5805 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005806 return NULL;
5807
Barry Warsaw53699e91996-12-10 23:23:01 +00005808 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005809 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005810 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005811 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005812 return posix_error_with_allocated_filename(file);
5813 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005814 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005815}
5816
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005817
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005818PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005819"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005820Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005821
Barry Warsaw53699e91996-12-10 23:23:01 +00005822static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005823posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005824{
5825 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005826 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005827 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005828 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005829 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005830 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005831 if (res < 0)
5832 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005833 Py_INCREF(Py_None);
5834 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005835}
5836
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005837
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005838PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005839"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005840Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005841
Barry Warsaw53699e91996-12-10 23:23:01 +00005842static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005843posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005844{
5845 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005846 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005847 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005848 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005849 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005850 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005851 if (fd < 0)
5852 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005853 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005854}
5855
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005856
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005857PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005858"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005859Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005860
Barry Warsaw53699e91996-12-10 23:23:01 +00005861static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005862posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005863{
5864 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005865 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005866 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005867 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005868 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005869 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005870 if (res < 0)
5871 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005872 Py_INCREF(Py_None);
5873 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005874}
5875
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005876
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005877PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005878"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005879Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005880
Barry Warsaw53699e91996-12-10 23:23:01 +00005881static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005882posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005883{
5884 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005885#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005886 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005887#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005888 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005889#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005890 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005891 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005892 return NULL;
5893#ifdef SEEK_SET
5894 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5895 switch (how) {
5896 case 0: how = SEEK_SET; break;
5897 case 1: how = SEEK_CUR; break;
5898 case 2: how = SEEK_END; break;
5899 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005900#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005901
5902#if !defined(HAVE_LARGEFILE_SUPPORT)
5903 pos = PyInt_AsLong(posobj);
5904#else
5905 pos = PyLong_Check(posobj) ?
5906 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5907#endif
5908 if (PyErr_Occurred())
5909 return NULL;
5910
Barry Warsaw53699e91996-12-10 23:23:01 +00005911 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005912#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005913 res = _lseeki64(fd, pos, how);
5914#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005915 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005916#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005917 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005918 if (res < 0)
5919 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005920
5921#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005922 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005923#else
5924 return PyLong_FromLongLong(res);
5925#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005926}
5927
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005928
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005929PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005930"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005931Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005932
Barry Warsaw53699e91996-12-10 23:23:01 +00005933static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005934posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005935{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005936 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005937 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005938 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005939 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005940 if (size < 0) {
5941 errno = EINVAL;
5942 return posix_error();
5943 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005944 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005945 if (buffer == NULL)
5946 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005947 Py_BEGIN_ALLOW_THREADS
5948 n = read(fd, PyString_AsString(buffer), size);
5949 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005950 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005951 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005952 return posix_error();
5953 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005954 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005955 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005956 return buffer;
5957}
5958
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005959
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005960PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005961"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005962Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005963
Barry Warsaw53699e91996-12-10 23:23:01 +00005964static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005965posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005966{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005967 int fd;
5968 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00005969 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005970
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005971 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005972 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005973 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005974 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005975 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005976 if (size < 0)
5977 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005978 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005979}
5980
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005981
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005982PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005983"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005984Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005985
Barry Warsaw53699e91996-12-10 23:23:01 +00005986static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005987posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005988{
5989 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005990 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005991 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005992 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005993 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005994#ifdef __VMS
5995 /* on OpenVMS we must ensure that all bytes are written to the file */
5996 fsync(fd);
5997#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005998 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005999 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00006000 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00006001 if (res != 0) {
6002#ifdef MS_WINDOWS
6003 return win32_error("fstat", NULL);
6004#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006005 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006006#endif
6007 }
Tim Peters5aa91602002-01-30 05:46:57 +00006008
Martin v. Löwis14694662006-02-03 12:54:16 +00006009 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006010}
6011
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006012
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006013PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006014"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006015Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006016
Barry Warsaw53699e91996-12-10 23:23:01 +00006017static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006018posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006019{
Guido van Rossum687dd131993-05-17 08:34:16 +00006020 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006021 char *mode = "r";
6022 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00006023 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00006024 PyObject *f;
6025 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00006026 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006027
Thomas Heller1f043e22002-11-07 16:00:59 +00006028 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
6029 PyErr_Format(PyExc_ValueError,
6030 "invalid file mode '%s'", mode);
6031 return NULL;
6032 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006033 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006034#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Georg Brandl54a188a2006-03-31 20:00:11 +00006035 if (mode[0] == 'a') {
6036 /* try to make sure the O_APPEND flag is set */
6037 int flags;
6038 flags = fcntl(fd, F_GETFL);
6039 if (flags != -1)
6040 fcntl(fd, F_SETFL, flags | O_APPEND);
6041 fp = fdopen(fd, mode);
Thomas Wouters2a9a6b02006-03-31 22:38:19 +00006042 if (fp == NULL && flags != -1)
Georg Brandl54a188a2006-03-31 20:00:11 +00006043 /* restore old mode if fdopen failed */
6044 fcntl(fd, F_SETFL, flags);
6045 } else {
6046 fp = fdopen(fd, mode);
6047 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006048#else
6049 fp = fdopen(fd, mode);
6050#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006051 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006052 if (fp == NULL)
6053 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00006054 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006055 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00006056 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006057 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006058}
6059
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006060PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006061"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006062Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006063connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006064
6065static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006066posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006067{
6068 int fd;
6069 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6070 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006071 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006072}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006073
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006074#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006075PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006076"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006077Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006078
Barry Warsaw53699e91996-12-10 23:23:01 +00006079static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006080posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006081{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006082#if defined(PYOS_OS2)
6083 HFILE read, write;
6084 APIRET rc;
6085
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006086 Py_BEGIN_ALLOW_THREADS
6087 rc = DosCreatePipe( &read, &write, 4096);
6088 Py_END_ALLOW_THREADS
6089 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006090 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006091
6092 return Py_BuildValue("(ii)", read, write);
6093#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006094#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00006095 int fds[2];
6096 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00006097 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006098 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00006099 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006100 if (res != 0)
6101 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006102 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006103#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00006104 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006105 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00006106 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00006107 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006108 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00006109 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00006110 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006111 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00006112 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6113 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006114 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006115#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006116#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006117}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006118#endif /* HAVE_PIPE */
6119
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006120
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006121#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006122PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006123"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006124Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006125
Barry Warsaw53699e91996-12-10 23:23:01 +00006126static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006127posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006128{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006129 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006130 int mode = 0666;
6131 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006132 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006133 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006134 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006135 res = mkfifo(filename, mode);
6136 Py_END_ALLOW_THREADS
6137 if (res < 0)
6138 return posix_error();
6139 Py_INCREF(Py_None);
6140 return Py_None;
6141}
6142#endif
6143
6144
Neal Norwitz11690112002-07-30 01:08:28 +00006145#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006146PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006147"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006148Create a filesystem node (file, device special file or named pipe)\n\
6149named filename. mode specifies both the permissions to use and the\n\
6150type of node to be created, being combined (bitwise OR) with one of\n\
6151S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006152device defines the newly created device special file (probably using\n\
6153os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006154
6155
6156static PyObject *
6157posix_mknod(PyObject *self, PyObject *args)
6158{
6159 char *filename;
6160 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006161 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006162 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00006163 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006164 return NULL;
6165 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006166 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00006167 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006168 if (res < 0)
6169 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006170 Py_INCREF(Py_None);
6171 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006172}
6173#endif
6174
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006175#ifdef HAVE_DEVICE_MACROS
6176PyDoc_STRVAR(posix_major__doc__,
6177"major(device) -> major number\n\
6178Extracts a device major number from a raw device number.");
6179
6180static PyObject *
6181posix_major(PyObject *self, PyObject *args)
6182{
6183 int device;
6184 if (!PyArg_ParseTuple(args, "i:major", &device))
6185 return NULL;
6186 return PyInt_FromLong((long)major(device));
6187}
6188
6189PyDoc_STRVAR(posix_minor__doc__,
6190"minor(device) -> minor number\n\
6191Extracts a device minor number from a raw device number.");
6192
6193static PyObject *
6194posix_minor(PyObject *self, PyObject *args)
6195{
6196 int device;
6197 if (!PyArg_ParseTuple(args, "i:minor", &device))
6198 return NULL;
6199 return PyInt_FromLong((long)minor(device));
6200}
6201
6202PyDoc_STRVAR(posix_makedev__doc__,
6203"makedev(major, minor) -> device number\n\
6204Composes a raw device number from the major and minor device numbers.");
6205
6206static PyObject *
6207posix_makedev(PyObject *self, PyObject *args)
6208{
6209 int major, minor;
6210 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6211 return NULL;
6212 return PyInt_FromLong((long)makedev(major, minor));
6213}
6214#endif /* device macros */
6215
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006216
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006217#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006218PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006219"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006220Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006221
Barry Warsaw53699e91996-12-10 23:23:01 +00006222static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006223posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006224{
6225 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006226 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006227 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006228 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006229
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006230 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006231 return NULL;
6232
6233#if !defined(HAVE_LARGEFILE_SUPPORT)
6234 length = PyInt_AsLong(lenobj);
6235#else
6236 length = PyLong_Check(lenobj) ?
6237 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6238#endif
6239 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006240 return NULL;
6241
Barry Warsaw53699e91996-12-10 23:23:01 +00006242 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006243 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006244 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006245 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006246 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006247 return NULL;
6248 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006249 Py_INCREF(Py_None);
6250 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006251}
6252#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006253
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006254#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006255PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006256"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006257Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006258
Fred Drake762e2061999-08-26 17:23:54 +00006259/* Save putenv() parameters as values here, so we can collect them when they
6260 * get re-set with another call for the same key. */
6261static PyObject *posix_putenv_garbage;
6262
Tim Peters5aa91602002-01-30 05:46:57 +00006263static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006264posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006265{
6266 char *s1, *s2;
Anthony Baxter64182fe2006-04-11 12:14:09 +00006267 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006268 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006269 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006270
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006271 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006272 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006273
6274#if defined(PYOS_OS2)
6275 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6276 APIRET rc;
6277
Guido van Rossumd48f2521997-12-05 22:19:34 +00006278 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6279 if (rc != NO_ERROR)
6280 return os2_error(rc);
6281
6282 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6283 APIRET rc;
6284
Guido van Rossumd48f2521997-12-05 22:19:34 +00006285 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6286 if (rc != NO_ERROR)
6287 return os2_error(rc);
6288 } else {
6289#endif
6290
Fred Drake762e2061999-08-26 17:23:54 +00006291 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006292 len = strlen(s1) + strlen(s2) + 2;
6293 /* len includes space for a trailing \0; the size arg to
6294 PyString_FromStringAndSize does not count that */
6295 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006296 if (newstr == NULL)
6297 return PyErr_NoMemory();
Anthony Baxter64182fe2006-04-11 12:14:09 +00006298 newenv = PyString_AS_STRING(newstr);
6299 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6300 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006301 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006302 posix_error();
6303 return NULL;
6304 }
Fred Drake762e2061999-08-26 17:23:54 +00006305 /* Install the first arg and newstr in posix_putenv_garbage;
6306 * this will cause previous value to be collected. This has to
6307 * happen after the real putenv() call because the old value
6308 * was still accessible until then. */
6309 if (PyDict_SetItem(posix_putenv_garbage,
6310 PyTuple_GET_ITEM(args, 0), newstr)) {
6311 /* really not much we can do; just leak */
6312 PyErr_Clear();
6313 }
6314 else {
6315 Py_DECREF(newstr);
6316 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006317
6318#if defined(PYOS_OS2)
6319 }
6320#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006321 Py_INCREF(Py_None);
6322 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006323}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006324#endif /* putenv */
6325
Guido van Rossumc524d952001-10-19 01:31:59 +00006326#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006327PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006328"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006329Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006330
6331static PyObject *
6332posix_unsetenv(PyObject *self, PyObject *args)
6333{
6334 char *s1;
6335
6336 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6337 return NULL;
6338
6339 unsetenv(s1);
6340
6341 /* Remove the key from posix_putenv_garbage;
6342 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006343 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006344 * old value was still accessible until then.
6345 */
6346 if (PyDict_DelItem(posix_putenv_garbage,
6347 PyTuple_GET_ITEM(args, 0))) {
6348 /* really not much we can do; just leak */
6349 PyErr_Clear();
6350 }
6351
6352 Py_INCREF(Py_None);
6353 return Py_None;
6354}
6355#endif /* unsetenv */
6356
Guido van Rossumb6a47161997-09-15 22:54:34 +00006357#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006358PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006359"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006360Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006361
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006362static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006363posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006364{
6365 int code;
6366 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006367 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006368 return NULL;
6369 message = strerror(code);
6370 if (message == NULL) {
6371 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006372 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006373 return NULL;
6374 }
6375 return PyString_FromString(message);
6376}
6377#endif /* strerror */
6378
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006379
Guido van Rossumc9641791998-08-04 15:26:23 +00006380#ifdef HAVE_SYS_WAIT_H
6381
Fred Drake106c1a02002-04-23 15:58:02 +00006382#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006383PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006384"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006385Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006386
6387static PyObject *
6388posix_WCOREDUMP(PyObject *self, PyObject *args)
6389{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006390 WAIT_TYPE status;
6391 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006392
Neal Norwitzd5a37542006-03-20 06:48:34 +00006393 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006394 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006395
6396 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006397}
6398#endif /* WCOREDUMP */
6399
6400#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006401PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006402"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006403Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006404job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006405
6406static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006407posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006408{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006409 WAIT_TYPE status;
6410 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006411
Neal Norwitzd5a37542006-03-20 06:48:34 +00006412 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006413 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006414
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006415 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006416}
6417#endif /* WIFCONTINUED */
6418
Guido van Rossumc9641791998-08-04 15:26:23 +00006419#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006420PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006421"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006422Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006423
6424static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006425posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006426{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006427 WAIT_TYPE status;
6428 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006429
Neal Norwitzd5a37542006-03-20 06:48:34 +00006430 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006431 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006432
Fred Drake106c1a02002-04-23 15:58:02 +00006433 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006434}
6435#endif /* WIFSTOPPED */
6436
6437#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006438PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006439"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006440Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006441
6442static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006443posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006444{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006445 WAIT_TYPE status;
6446 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006447
Neal Norwitzd5a37542006-03-20 06:48:34 +00006448 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006449 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006450
Fred Drake106c1a02002-04-23 15:58:02 +00006451 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006452}
6453#endif /* WIFSIGNALED */
6454
6455#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006456PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006457"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006458Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006459system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006460
6461static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006462posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006463{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006464 WAIT_TYPE status;
6465 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006466
Neal Norwitzd5a37542006-03-20 06:48:34 +00006467 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006468 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006469
Fred Drake106c1a02002-04-23 15:58:02 +00006470 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006471}
6472#endif /* WIFEXITED */
6473
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006474#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006475PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006476"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006477Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006478
6479static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006480posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006481{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006482 WAIT_TYPE status;
6483 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006484
Neal Norwitzd5a37542006-03-20 06:48:34 +00006485 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006486 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006487
Guido van Rossumc9641791998-08-04 15:26:23 +00006488 return Py_BuildValue("i", WEXITSTATUS(status));
6489}
6490#endif /* WEXITSTATUS */
6491
6492#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006493PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006494"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006495Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006496value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006497
6498static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006499posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006500{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006501 WAIT_TYPE status;
6502 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006503
Neal Norwitzd5a37542006-03-20 06:48:34 +00006504 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006505 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006506
Guido van Rossumc9641791998-08-04 15:26:23 +00006507 return Py_BuildValue("i", WTERMSIG(status));
6508}
6509#endif /* WTERMSIG */
6510
6511#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006512PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006513"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006514Return the signal that stopped the process that provided\n\
6515the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006516
6517static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006518posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006519{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006520 WAIT_TYPE status;
6521 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006522
Neal Norwitzd5a37542006-03-20 06:48:34 +00006523 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006524 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006525
Guido van Rossumc9641791998-08-04 15:26:23 +00006526 return Py_BuildValue("i", WSTOPSIG(status));
6527}
6528#endif /* WSTOPSIG */
6529
6530#endif /* HAVE_SYS_WAIT_H */
6531
6532
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006533#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006534#ifdef _SCO_DS
6535/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6536 needed definitions in sys/statvfs.h */
6537#define _SVID3
6538#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006539#include <sys/statvfs.h>
6540
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006541static PyObject*
6542_pystatvfs_fromstructstatvfs(struct statvfs st) {
6543 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6544 if (v == NULL)
6545 return NULL;
6546
6547#if !defined(HAVE_LARGEFILE_SUPPORT)
6548 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6549 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6550 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6551 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6552 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6553 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6554 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6555 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6556 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6557 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6558#else
6559 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6560 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006561 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006562 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006563 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006564 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006565 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006566 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006567 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006568 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006569 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006570 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006571 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006572 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006573 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6574 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6575#endif
6576
6577 return v;
6578}
6579
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006580PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006581"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006582Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006583
6584static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006585posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006586{
6587 int fd, res;
6588 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006589
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006590 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006591 return NULL;
6592 Py_BEGIN_ALLOW_THREADS
6593 res = fstatvfs(fd, &st);
6594 Py_END_ALLOW_THREADS
6595 if (res != 0)
6596 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006597
6598 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006599}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006600#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006601
6602
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006603#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006604#include <sys/statvfs.h>
6605
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006606PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006607"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006608Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006609
6610static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006611posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006612{
6613 char *path;
6614 int res;
6615 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006616 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006617 return NULL;
6618 Py_BEGIN_ALLOW_THREADS
6619 res = statvfs(path, &st);
6620 Py_END_ALLOW_THREADS
6621 if (res != 0)
6622 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006623
6624 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006625}
6626#endif /* HAVE_STATVFS */
6627
6628
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006629#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006630PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006631"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006632Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006633The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006634or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006635
6636static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006637posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006638{
6639 PyObject *result = NULL;
6640 char *dir = NULL;
6641 char *pfx = NULL;
6642 char *name;
6643
6644 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6645 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006646
6647 if (PyErr_Warn(PyExc_RuntimeWarning,
6648 "tempnam is a potential security risk to your program") < 0)
6649 return NULL;
6650
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006651#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006652 name = _tempnam(dir, pfx);
6653#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006654 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006655#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006656 if (name == NULL)
6657 return PyErr_NoMemory();
6658 result = PyString_FromString(name);
6659 free(name);
6660 return result;
6661}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006662#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006663
6664
6665#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006666PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006667"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006668Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006669
6670static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006671posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006672{
6673 FILE *fp;
6674
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006675 fp = tmpfile();
6676 if (fp == NULL)
6677 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006678 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006679}
6680#endif
6681
6682
6683#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006684PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006685"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006686Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006687
6688static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006689posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006690{
6691 char buffer[L_tmpnam];
6692 char *name;
6693
Skip Montanaro95618b52001-08-18 18:52:10 +00006694 if (PyErr_Warn(PyExc_RuntimeWarning,
6695 "tmpnam is a potential security risk to your program") < 0)
6696 return NULL;
6697
Greg Wardb48bc172000-03-01 21:51:56 +00006698#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006699 name = tmpnam_r(buffer);
6700#else
6701 name = tmpnam(buffer);
6702#endif
6703 if (name == NULL) {
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00006704 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006705#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006706 "unexpected NULL from tmpnam_r"
6707#else
6708 "unexpected NULL from tmpnam"
6709#endif
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00006710 );
6711 PyErr_SetObject(PyExc_OSError, err);
6712 Py_XDECREF(err);
6713 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006714 }
6715 return PyString_FromString(buffer);
6716}
6717#endif
6718
6719
Fred Drakec9680921999-12-13 16:37:25 +00006720/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6721 * It maps strings representing configuration variable names to
6722 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006723 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006724 * rarely-used constants. There are three separate tables that use
6725 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006726 *
6727 * This code is always included, even if none of the interfaces that
6728 * need it are included. The #if hackery needed to avoid it would be
6729 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006730 */
6731struct constdef {
6732 char *name;
6733 long value;
6734};
6735
Fred Drake12c6e2d1999-12-14 21:25:03 +00006736static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006737conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6738 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006739{
6740 if (PyInt_Check(arg)) {
6741 *valuep = PyInt_AS_LONG(arg);
6742 return 1;
6743 }
6744 if (PyString_Check(arg)) {
6745 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006746 size_t lo = 0;
6747 size_t mid;
6748 size_t hi = tablesize;
6749 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006750 char *confname = PyString_AS_STRING(arg);
6751 while (lo < hi) {
6752 mid = (lo + hi) / 2;
6753 cmp = strcmp(confname, table[mid].name);
6754 if (cmp < 0)
6755 hi = mid;
6756 else if (cmp > 0)
6757 lo = mid + 1;
6758 else {
6759 *valuep = table[mid].value;
6760 return 1;
6761 }
6762 }
6763 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6764 }
6765 else
6766 PyErr_SetString(PyExc_TypeError,
6767 "configuration names must be strings or integers");
6768 return 0;
6769}
6770
6771
6772#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6773static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006774#ifdef _PC_ABI_AIO_XFER_MAX
6775 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6776#endif
6777#ifdef _PC_ABI_ASYNC_IO
6778 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6779#endif
Fred Drakec9680921999-12-13 16:37:25 +00006780#ifdef _PC_ASYNC_IO
6781 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6782#endif
6783#ifdef _PC_CHOWN_RESTRICTED
6784 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6785#endif
6786#ifdef _PC_FILESIZEBITS
6787 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6788#endif
6789#ifdef _PC_LAST
6790 {"PC_LAST", _PC_LAST},
6791#endif
6792#ifdef _PC_LINK_MAX
6793 {"PC_LINK_MAX", _PC_LINK_MAX},
6794#endif
6795#ifdef _PC_MAX_CANON
6796 {"PC_MAX_CANON", _PC_MAX_CANON},
6797#endif
6798#ifdef _PC_MAX_INPUT
6799 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6800#endif
6801#ifdef _PC_NAME_MAX
6802 {"PC_NAME_MAX", _PC_NAME_MAX},
6803#endif
6804#ifdef _PC_NO_TRUNC
6805 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6806#endif
6807#ifdef _PC_PATH_MAX
6808 {"PC_PATH_MAX", _PC_PATH_MAX},
6809#endif
6810#ifdef _PC_PIPE_BUF
6811 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6812#endif
6813#ifdef _PC_PRIO_IO
6814 {"PC_PRIO_IO", _PC_PRIO_IO},
6815#endif
6816#ifdef _PC_SOCK_MAXBUF
6817 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6818#endif
6819#ifdef _PC_SYNC_IO
6820 {"PC_SYNC_IO", _PC_SYNC_IO},
6821#endif
6822#ifdef _PC_VDISABLE
6823 {"PC_VDISABLE", _PC_VDISABLE},
6824#endif
6825};
6826
Fred Drakec9680921999-12-13 16:37:25 +00006827static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006828conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006829{
6830 return conv_confname(arg, valuep, posix_constants_pathconf,
6831 sizeof(posix_constants_pathconf)
6832 / sizeof(struct constdef));
6833}
6834#endif
6835
6836#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006837PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006838"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006839Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006840If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006841
6842static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006843posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006844{
6845 PyObject *result = NULL;
6846 int name, fd;
6847
Fred Drake12c6e2d1999-12-14 21:25:03 +00006848 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6849 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006850 long limit;
6851
6852 errno = 0;
6853 limit = fpathconf(fd, name);
6854 if (limit == -1 && errno != 0)
6855 posix_error();
6856 else
6857 result = PyInt_FromLong(limit);
6858 }
6859 return result;
6860}
6861#endif
6862
6863
6864#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006865PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006866"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006867Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006868If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006869
6870static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006871posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006872{
6873 PyObject *result = NULL;
6874 int name;
6875 char *path;
6876
6877 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6878 conv_path_confname, &name)) {
6879 long limit;
6880
6881 errno = 0;
6882 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006883 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006884 if (errno == EINVAL)
6885 /* could be a path or name problem */
6886 posix_error();
6887 else
6888 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006889 }
Fred Drakec9680921999-12-13 16:37:25 +00006890 else
6891 result = PyInt_FromLong(limit);
6892 }
6893 return result;
6894}
6895#endif
6896
6897#ifdef HAVE_CONFSTR
6898static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006899#ifdef _CS_ARCHITECTURE
6900 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6901#endif
6902#ifdef _CS_HOSTNAME
6903 {"CS_HOSTNAME", _CS_HOSTNAME},
6904#endif
6905#ifdef _CS_HW_PROVIDER
6906 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6907#endif
6908#ifdef _CS_HW_SERIAL
6909 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6910#endif
6911#ifdef _CS_INITTAB_NAME
6912 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6913#endif
Fred Drakec9680921999-12-13 16:37:25 +00006914#ifdef _CS_LFS64_CFLAGS
6915 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6916#endif
6917#ifdef _CS_LFS64_LDFLAGS
6918 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6919#endif
6920#ifdef _CS_LFS64_LIBS
6921 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6922#endif
6923#ifdef _CS_LFS64_LINTFLAGS
6924 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6925#endif
6926#ifdef _CS_LFS_CFLAGS
6927 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6928#endif
6929#ifdef _CS_LFS_LDFLAGS
6930 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6931#endif
6932#ifdef _CS_LFS_LIBS
6933 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6934#endif
6935#ifdef _CS_LFS_LINTFLAGS
6936 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6937#endif
Fred Draked86ed291999-12-15 15:34:33 +00006938#ifdef _CS_MACHINE
6939 {"CS_MACHINE", _CS_MACHINE},
6940#endif
Fred Drakec9680921999-12-13 16:37:25 +00006941#ifdef _CS_PATH
6942 {"CS_PATH", _CS_PATH},
6943#endif
Fred Draked86ed291999-12-15 15:34:33 +00006944#ifdef _CS_RELEASE
6945 {"CS_RELEASE", _CS_RELEASE},
6946#endif
6947#ifdef _CS_SRPC_DOMAIN
6948 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6949#endif
6950#ifdef _CS_SYSNAME
6951 {"CS_SYSNAME", _CS_SYSNAME},
6952#endif
6953#ifdef _CS_VERSION
6954 {"CS_VERSION", _CS_VERSION},
6955#endif
Fred Drakec9680921999-12-13 16:37:25 +00006956#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6957 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6958#endif
6959#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6960 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6961#endif
6962#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6963 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6964#endif
6965#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6966 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6967#endif
6968#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6969 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6970#endif
6971#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6972 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6973#endif
6974#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6975 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6976#endif
6977#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6978 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6979#endif
6980#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6981 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6982#endif
6983#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6984 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6985#endif
6986#ifdef _CS_XBS5_LP64_OFF64_LIBS
6987 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6988#endif
6989#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6990 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6991#endif
6992#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6993 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6994#endif
6995#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6996 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6997#endif
6998#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6999 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7000#endif
7001#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7002 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7003#endif
Fred Draked86ed291999-12-15 15:34:33 +00007004#ifdef _MIPS_CS_AVAIL_PROCESSORS
7005 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7006#endif
7007#ifdef _MIPS_CS_BASE
7008 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7009#endif
7010#ifdef _MIPS_CS_HOSTID
7011 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7012#endif
7013#ifdef _MIPS_CS_HW_NAME
7014 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7015#endif
7016#ifdef _MIPS_CS_NUM_PROCESSORS
7017 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7018#endif
7019#ifdef _MIPS_CS_OSREL_MAJ
7020 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7021#endif
7022#ifdef _MIPS_CS_OSREL_MIN
7023 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7024#endif
7025#ifdef _MIPS_CS_OSREL_PATCH
7026 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7027#endif
7028#ifdef _MIPS_CS_OS_NAME
7029 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7030#endif
7031#ifdef _MIPS_CS_OS_PROVIDER
7032 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7033#endif
7034#ifdef _MIPS_CS_PROCESSORS
7035 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7036#endif
7037#ifdef _MIPS_CS_SERIAL
7038 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7039#endif
7040#ifdef _MIPS_CS_VENDOR
7041 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7042#endif
Fred Drakec9680921999-12-13 16:37:25 +00007043};
7044
7045static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007046conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007047{
7048 return conv_confname(arg, valuep, posix_constants_confstr,
7049 sizeof(posix_constants_confstr)
7050 / sizeof(struct constdef));
7051}
7052
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007053PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007054"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007055Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007056
7057static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007058posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007059{
7060 PyObject *result = NULL;
7061 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007062 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007063
7064 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Skip Montanarodd527fc2006-04-18 00:49:49 +00007065 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007066
Fred Drakec9680921999-12-13 16:37:25 +00007067 errno = 0;
Skip Montanarodd527fc2006-04-18 00:49:49 +00007068 len = confstr(name, buffer, sizeof(buffer));
Skip Montanaro94785ef2006-04-20 01:29:48 +00007069 if (len == 0) {
7070 if (errno) {
7071 posix_error();
7072 }
7073 else {
7074 result = Py_None;
7075 Py_INCREF(Py_None);
7076 }
Fred Drakec9680921999-12-13 16:37:25 +00007077 }
7078 else {
Neal Norwitz0d21b1e2006-04-20 06:44:42 +00007079 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz449b24e2006-04-20 06:56:05 +00007080 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007081 if (result != NULL)
Neal Norwitz449b24e2006-04-20 06:56:05 +00007082 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00007083 }
7084 else
Neal Norwitz449b24e2006-04-20 06:56:05 +00007085 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007086 }
7087 }
7088 return result;
7089}
7090#endif
7091
7092
7093#ifdef HAVE_SYSCONF
7094static struct constdef posix_constants_sysconf[] = {
7095#ifdef _SC_2_CHAR_TERM
7096 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7097#endif
7098#ifdef _SC_2_C_BIND
7099 {"SC_2_C_BIND", _SC_2_C_BIND},
7100#endif
7101#ifdef _SC_2_C_DEV
7102 {"SC_2_C_DEV", _SC_2_C_DEV},
7103#endif
7104#ifdef _SC_2_C_VERSION
7105 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7106#endif
7107#ifdef _SC_2_FORT_DEV
7108 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7109#endif
7110#ifdef _SC_2_FORT_RUN
7111 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7112#endif
7113#ifdef _SC_2_LOCALEDEF
7114 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7115#endif
7116#ifdef _SC_2_SW_DEV
7117 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7118#endif
7119#ifdef _SC_2_UPE
7120 {"SC_2_UPE", _SC_2_UPE},
7121#endif
7122#ifdef _SC_2_VERSION
7123 {"SC_2_VERSION", _SC_2_VERSION},
7124#endif
Fred Draked86ed291999-12-15 15:34:33 +00007125#ifdef _SC_ABI_ASYNCHRONOUS_IO
7126 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7127#endif
7128#ifdef _SC_ACL
7129 {"SC_ACL", _SC_ACL},
7130#endif
Fred Drakec9680921999-12-13 16:37:25 +00007131#ifdef _SC_AIO_LISTIO_MAX
7132 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7133#endif
Fred Drakec9680921999-12-13 16:37:25 +00007134#ifdef _SC_AIO_MAX
7135 {"SC_AIO_MAX", _SC_AIO_MAX},
7136#endif
7137#ifdef _SC_AIO_PRIO_DELTA_MAX
7138 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7139#endif
7140#ifdef _SC_ARG_MAX
7141 {"SC_ARG_MAX", _SC_ARG_MAX},
7142#endif
7143#ifdef _SC_ASYNCHRONOUS_IO
7144 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7145#endif
7146#ifdef _SC_ATEXIT_MAX
7147 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7148#endif
Fred Draked86ed291999-12-15 15:34:33 +00007149#ifdef _SC_AUDIT
7150 {"SC_AUDIT", _SC_AUDIT},
7151#endif
Fred Drakec9680921999-12-13 16:37:25 +00007152#ifdef _SC_AVPHYS_PAGES
7153 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7154#endif
7155#ifdef _SC_BC_BASE_MAX
7156 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7157#endif
7158#ifdef _SC_BC_DIM_MAX
7159 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7160#endif
7161#ifdef _SC_BC_SCALE_MAX
7162 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7163#endif
7164#ifdef _SC_BC_STRING_MAX
7165 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7166#endif
Fred Draked86ed291999-12-15 15:34:33 +00007167#ifdef _SC_CAP
7168 {"SC_CAP", _SC_CAP},
7169#endif
Fred Drakec9680921999-12-13 16:37:25 +00007170#ifdef _SC_CHARCLASS_NAME_MAX
7171 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7172#endif
7173#ifdef _SC_CHAR_BIT
7174 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7175#endif
7176#ifdef _SC_CHAR_MAX
7177 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7178#endif
7179#ifdef _SC_CHAR_MIN
7180 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7181#endif
7182#ifdef _SC_CHILD_MAX
7183 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7184#endif
7185#ifdef _SC_CLK_TCK
7186 {"SC_CLK_TCK", _SC_CLK_TCK},
7187#endif
7188#ifdef _SC_COHER_BLKSZ
7189 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7190#endif
7191#ifdef _SC_COLL_WEIGHTS_MAX
7192 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7193#endif
7194#ifdef _SC_DCACHE_ASSOC
7195 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7196#endif
7197#ifdef _SC_DCACHE_BLKSZ
7198 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7199#endif
7200#ifdef _SC_DCACHE_LINESZ
7201 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7202#endif
7203#ifdef _SC_DCACHE_SZ
7204 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7205#endif
7206#ifdef _SC_DCACHE_TBLKSZ
7207 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7208#endif
7209#ifdef _SC_DELAYTIMER_MAX
7210 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7211#endif
7212#ifdef _SC_EQUIV_CLASS_MAX
7213 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7214#endif
7215#ifdef _SC_EXPR_NEST_MAX
7216 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7217#endif
7218#ifdef _SC_FSYNC
7219 {"SC_FSYNC", _SC_FSYNC},
7220#endif
7221#ifdef _SC_GETGR_R_SIZE_MAX
7222 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7223#endif
7224#ifdef _SC_GETPW_R_SIZE_MAX
7225 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7226#endif
7227#ifdef _SC_ICACHE_ASSOC
7228 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7229#endif
7230#ifdef _SC_ICACHE_BLKSZ
7231 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7232#endif
7233#ifdef _SC_ICACHE_LINESZ
7234 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7235#endif
7236#ifdef _SC_ICACHE_SZ
7237 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7238#endif
Fred Draked86ed291999-12-15 15:34:33 +00007239#ifdef _SC_INF
7240 {"SC_INF", _SC_INF},
7241#endif
Fred Drakec9680921999-12-13 16:37:25 +00007242#ifdef _SC_INT_MAX
7243 {"SC_INT_MAX", _SC_INT_MAX},
7244#endif
7245#ifdef _SC_INT_MIN
7246 {"SC_INT_MIN", _SC_INT_MIN},
7247#endif
7248#ifdef _SC_IOV_MAX
7249 {"SC_IOV_MAX", _SC_IOV_MAX},
7250#endif
Fred Draked86ed291999-12-15 15:34:33 +00007251#ifdef _SC_IP_SECOPTS
7252 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7253#endif
Fred Drakec9680921999-12-13 16:37:25 +00007254#ifdef _SC_JOB_CONTROL
7255 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7256#endif
Fred Draked86ed291999-12-15 15:34:33 +00007257#ifdef _SC_KERN_POINTERS
7258 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7259#endif
7260#ifdef _SC_KERN_SIM
7261 {"SC_KERN_SIM", _SC_KERN_SIM},
7262#endif
Fred Drakec9680921999-12-13 16:37:25 +00007263#ifdef _SC_LINE_MAX
7264 {"SC_LINE_MAX", _SC_LINE_MAX},
7265#endif
7266#ifdef _SC_LOGIN_NAME_MAX
7267 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7268#endif
7269#ifdef _SC_LOGNAME_MAX
7270 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7271#endif
7272#ifdef _SC_LONG_BIT
7273 {"SC_LONG_BIT", _SC_LONG_BIT},
7274#endif
Fred Draked86ed291999-12-15 15:34:33 +00007275#ifdef _SC_MAC
7276 {"SC_MAC", _SC_MAC},
7277#endif
Fred Drakec9680921999-12-13 16:37:25 +00007278#ifdef _SC_MAPPED_FILES
7279 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7280#endif
7281#ifdef _SC_MAXPID
7282 {"SC_MAXPID", _SC_MAXPID},
7283#endif
7284#ifdef _SC_MB_LEN_MAX
7285 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7286#endif
7287#ifdef _SC_MEMLOCK
7288 {"SC_MEMLOCK", _SC_MEMLOCK},
7289#endif
7290#ifdef _SC_MEMLOCK_RANGE
7291 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7292#endif
7293#ifdef _SC_MEMORY_PROTECTION
7294 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7295#endif
7296#ifdef _SC_MESSAGE_PASSING
7297 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7298#endif
Fred Draked86ed291999-12-15 15:34:33 +00007299#ifdef _SC_MMAP_FIXED_ALIGNMENT
7300 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7301#endif
Fred Drakec9680921999-12-13 16:37:25 +00007302#ifdef _SC_MQ_OPEN_MAX
7303 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7304#endif
7305#ifdef _SC_MQ_PRIO_MAX
7306 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7307#endif
Fred Draked86ed291999-12-15 15:34:33 +00007308#ifdef _SC_NACLS_MAX
7309 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7310#endif
Fred Drakec9680921999-12-13 16:37:25 +00007311#ifdef _SC_NGROUPS_MAX
7312 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7313#endif
7314#ifdef _SC_NL_ARGMAX
7315 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7316#endif
7317#ifdef _SC_NL_LANGMAX
7318 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7319#endif
7320#ifdef _SC_NL_MSGMAX
7321 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7322#endif
7323#ifdef _SC_NL_NMAX
7324 {"SC_NL_NMAX", _SC_NL_NMAX},
7325#endif
7326#ifdef _SC_NL_SETMAX
7327 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7328#endif
7329#ifdef _SC_NL_TEXTMAX
7330 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7331#endif
7332#ifdef _SC_NPROCESSORS_CONF
7333 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7334#endif
7335#ifdef _SC_NPROCESSORS_ONLN
7336 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7337#endif
Fred Draked86ed291999-12-15 15:34:33 +00007338#ifdef _SC_NPROC_CONF
7339 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7340#endif
7341#ifdef _SC_NPROC_ONLN
7342 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7343#endif
Fred Drakec9680921999-12-13 16:37:25 +00007344#ifdef _SC_NZERO
7345 {"SC_NZERO", _SC_NZERO},
7346#endif
7347#ifdef _SC_OPEN_MAX
7348 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7349#endif
7350#ifdef _SC_PAGESIZE
7351 {"SC_PAGESIZE", _SC_PAGESIZE},
7352#endif
7353#ifdef _SC_PAGE_SIZE
7354 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7355#endif
7356#ifdef _SC_PASS_MAX
7357 {"SC_PASS_MAX", _SC_PASS_MAX},
7358#endif
7359#ifdef _SC_PHYS_PAGES
7360 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7361#endif
7362#ifdef _SC_PII
7363 {"SC_PII", _SC_PII},
7364#endif
7365#ifdef _SC_PII_INTERNET
7366 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7367#endif
7368#ifdef _SC_PII_INTERNET_DGRAM
7369 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7370#endif
7371#ifdef _SC_PII_INTERNET_STREAM
7372 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7373#endif
7374#ifdef _SC_PII_OSI
7375 {"SC_PII_OSI", _SC_PII_OSI},
7376#endif
7377#ifdef _SC_PII_OSI_CLTS
7378 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7379#endif
7380#ifdef _SC_PII_OSI_COTS
7381 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7382#endif
7383#ifdef _SC_PII_OSI_M
7384 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7385#endif
7386#ifdef _SC_PII_SOCKET
7387 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7388#endif
7389#ifdef _SC_PII_XTI
7390 {"SC_PII_XTI", _SC_PII_XTI},
7391#endif
7392#ifdef _SC_POLL
7393 {"SC_POLL", _SC_POLL},
7394#endif
7395#ifdef _SC_PRIORITIZED_IO
7396 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7397#endif
7398#ifdef _SC_PRIORITY_SCHEDULING
7399 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7400#endif
7401#ifdef _SC_REALTIME_SIGNALS
7402 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7403#endif
7404#ifdef _SC_RE_DUP_MAX
7405 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7406#endif
7407#ifdef _SC_RTSIG_MAX
7408 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7409#endif
7410#ifdef _SC_SAVED_IDS
7411 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7412#endif
7413#ifdef _SC_SCHAR_MAX
7414 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7415#endif
7416#ifdef _SC_SCHAR_MIN
7417 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7418#endif
7419#ifdef _SC_SELECT
7420 {"SC_SELECT", _SC_SELECT},
7421#endif
7422#ifdef _SC_SEMAPHORES
7423 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7424#endif
7425#ifdef _SC_SEM_NSEMS_MAX
7426 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7427#endif
7428#ifdef _SC_SEM_VALUE_MAX
7429 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7430#endif
7431#ifdef _SC_SHARED_MEMORY_OBJECTS
7432 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7433#endif
7434#ifdef _SC_SHRT_MAX
7435 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7436#endif
7437#ifdef _SC_SHRT_MIN
7438 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7439#endif
7440#ifdef _SC_SIGQUEUE_MAX
7441 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7442#endif
7443#ifdef _SC_SIGRT_MAX
7444 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7445#endif
7446#ifdef _SC_SIGRT_MIN
7447 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7448#endif
Fred Draked86ed291999-12-15 15:34:33 +00007449#ifdef _SC_SOFTPOWER
7450 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7451#endif
Fred Drakec9680921999-12-13 16:37:25 +00007452#ifdef _SC_SPLIT_CACHE
7453 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7454#endif
7455#ifdef _SC_SSIZE_MAX
7456 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7457#endif
7458#ifdef _SC_STACK_PROT
7459 {"SC_STACK_PROT", _SC_STACK_PROT},
7460#endif
7461#ifdef _SC_STREAM_MAX
7462 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7463#endif
7464#ifdef _SC_SYNCHRONIZED_IO
7465 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7466#endif
7467#ifdef _SC_THREADS
7468 {"SC_THREADS", _SC_THREADS},
7469#endif
7470#ifdef _SC_THREAD_ATTR_STACKADDR
7471 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7472#endif
7473#ifdef _SC_THREAD_ATTR_STACKSIZE
7474 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7475#endif
7476#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7477 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7478#endif
7479#ifdef _SC_THREAD_KEYS_MAX
7480 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7481#endif
7482#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7483 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7484#endif
7485#ifdef _SC_THREAD_PRIO_INHERIT
7486 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7487#endif
7488#ifdef _SC_THREAD_PRIO_PROTECT
7489 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7490#endif
7491#ifdef _SC_THREAD_PROCESS_SHARED
7492 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7493#endif
7494#ifdef _SC_THREAD_SAFE_FUNCTIONS
7495 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7496#endif
7497#ifdef _SC_THREAD_STACK_MIN
7498 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7499#endif
7500#ifdef _SC_THREAD_THREADS_MAX
7501 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7502#endif
7503#ifdef _SC_TIMERS
7504 {"SC_TIMERS", _SC_TIMERS},
7505#endif
7506#ifdef _SC_TIMER_MAX
7507 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7508#endif
7509#ifdef _SC_TTY_NAME_MAX
7510 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7511#endif
7512#ifdef _SC_TZNAME_MAX
7513 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7514#endif
7515#ifdef _SC_T_IOV_MAX
7516 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7517#endif
7518#ifdef _SC_UCHAR_MAX
7519 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7520#endif
7521#ifdef _SC_UINT_MAX
7522 {"SC_UINT_MAX", _SC_UINT_MAX},
7523#endif
7524#ifdef _SC_UIO_MAXIOV
7525 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7526#endif
7527#ifdef _SC_ULONG_MAX
7528 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7529#endif
7530#ifdef _SC_USHRT_MAX
7531 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7532#endif
7533#ifdef _SC_VERSION
7534 {"SC_VERSION", _SC_VERSION},
7535#endif
7536#ifdef _SC_WORD_BIT
7537 {"SC_WORD_BIT", _SC_WORD_BIT},
7538#endif
7539#ifdef _SC_XBS5_ILP32_OFF32
7540 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7541#endif
7542#ifdef _SC_XBS5_ILP32_OFFBIG
7543 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7544#endif
7545#ifdef _SC_XBS5_LP64_OFF64
7546 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7547#endif
7548#ifdef _SC_XBS5_LPBIG_OFFBIG
7549 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7550#endif
7551#ifdef _SC_XOPEN_CRYPT
7552 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7553#endif
7554#ifdef _SC_XOPEN_ENH_I18N
7555 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7556#endif
7557#ifdef _SC_XOPEN_LEGACY
7558 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7559#endif
7560#ifdef _SC_XOPEN_REALTIME
7561 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7562#endif
7563#ifdef _SC_XOPEN_REALTIME_THREADS
7564 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7565#endif
7566#ifdef _SC_XOPEN_SHM
7567 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7568#endif
7569#ifdef _SC_XOPEN_UNIX
7570 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7571#endif
7572#ifdef _SC_XOPEN_VERSION
7573 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7574#endif
7575#ifdef _SC_XOPEN_XCU_VERSION
7576 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7577#endif
7578#ifdef _SC_XOPEN_XPG2
7579 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7580#endif
7581#ifdef _SC_XOPEN_XPG3
7582 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7583#endif
7584#ifdef _SC_XOPEN_XPG4
7585 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7586#endif
7587};
7588
7589static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007590conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007591{
7592 return conv_confname(arg, valuep, posix_constants_sysconf,
7593 sizeof(posix_constants_sysconf)
7594 / sizeof(struct constdef));
7595}
7596
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007597PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007598"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007599Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007600
7601static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007602posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007603{
7604 PyObject *result = NULL;
7605 int name;
7606
7607 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7608 int value;
7609
7610 errno = 0;
7611 value = sysconf(name);
7612 if (value == -1 && errno != 0)
7613 posix_error();
7614 else
7615 result = PyInt_FromLong(value);
7616 }
7617 return result;
7618}
7619#endif
7620
7621
Fred Drakebec628d1999-12-15 18:31:10 +00007622/* This code is used to ensure that the tables of configuration value names
7623 * are in sorted order as required by conv_confname(), and also to build the
7624 * the exported dictionaries that are used to publish information about the
7625 * names available on the host platform.
7626 *
7627 * Sorting the table at runtime ensures that the table is properly ordered
7628 * when used, even for platforms we're not able to test on. It also makes
7629 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007630 */
Fred Drakebec628d1999-12-15 18:31:10 +00007631
7632static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007633cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007634{
7635 const struct constdef *c1 =
7636 (const struct constdef *) v1;
7637 const struct constdef *c2 =
7638 (const struct constdef *) v2;
7639
7640 return strcmp(c1->name, c2->name);
7641}
7642
7643static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007644setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007645 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007646{
Fred Drakebec628d1999-12-15 18:31:10 +00007647 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007648 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007649
7650 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7651 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007652 if (d == NULL)
7653 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007654
Barry Warsaw3155db32000-04-13 15:20:40 +00007655 for (i=0; i < tablesize; ++i) {
7656 PyObject *o = PyInt_FromLong(table[i].value);
7657 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7658 Py_XDECREF(o);
7659 Py_DECREF(d);
7660 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007661 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007662 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007663 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007664 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007665}
7666
Fred Drakebec628d1999-12-15 18:31:10 +00007667/* Return -1 on failure, 0 on success. */
7668static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007669setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007670{
7671#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007672 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007673 sizeof(posix_constants_pathconf)
7674 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007675 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007676 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007677#endif
7678#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007679 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007680 sizeof(posix_constants_confstr)
7681 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007682 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007683 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007684#endif
7685#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007686 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007687 sizeof(posix_constants_sysconf)
7688 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007689 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007690 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007691#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007692 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007693}
Fred Draked86ed291999-12-15 15:34:33 +00007694
7695
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007696PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007697"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007698Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007699in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007700
7701static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007702posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007703{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007704 abort();
7705 /*NOTREACHED*/
7706 Py_FatalError("abort() called from Python code didn't abort!");
7707 return NULL;
7708}
Fred Drakebec628d1999-12-15 18:31:10 +00007709
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007710#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007711PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007712"startfile(filepath [, operation]) - Start a file with its associated\n\
7713application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007714\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007715When \"operation\" is not specified or \"open\", this acts like\n\
7716double-clicking the file in Explorer, or giving the file name as an\n\
7717argument to the DOS \"start\" command: the file is opened with whatever\n\
7718application (if any) its extension is associated.\n\
7719When another \"operation\" is given, it specifies what should be done with\n\
7720the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007721\n\
7722startfile returns as soon as the associated application is launched.\n\
7723There is no option to wait for the application to close, and no way\n\
7724to retrieve the application's exit status.\n\
7725\n\
7726The filepath is relative to the current directory. If you want to use\n\
7727an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007728the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007729
7730static PyObject *
7731win32_startfile(PyObject *self, PyObject *args)
7732{
7733 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00007734 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007735 HINSTANCE rc;
Georg Brandlad89dc82006-04-03 12:26:26 +00007736#ifdef Py_WIN_WIDE_FILENAMES
7737 if (unicode_file_names()) {
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007738 PyObject *unipath, *woperation = NULL;
Georg Brandlad89dc82006-04-03 12:26:26 +00007739 if (!PyArg_ParseTuple(args, "U|s:startfile",
7740 &unipath, &operation)) {
7741 PyErr_Clear();
7742 goto normal;
7743 }
7744
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007745
7746 if (operation) {
7747 woperation = PyUnicode_DecodeASCII(operation,
7748 strlen(operation), NULL);
7749 if (!woperation) {
7750 PyErr_Clear();
7751 operation = NULL;
7752 goto normal;
7753 }
Georg Brandlad89dc82006-04-03 12:26:26 +00007754 }
7755
7756 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007757 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Georg Brandlad89dc82006-04-03 12:26:26 +00007758 PyUnicode_AS_UNICODE(unipath),
Georg Brandlad89dc82006-04-03 12:26:26 +00007759 NULL, NULL, SW_SHOWNORMAL);
7760 Py_END_ALLOW_THREADS
7761
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007762 Py_XDECREF(woperation);
Georg Brandlad89dc82006-04-03 12:26:26 +00007763 if (rc <= (HINSTANCE)32) {
7764 PyObject *errval = win32_error_unicode("startfile",
7765 PyUnicode_AS_UNICODE(unipath));
7766 return errval;
7767 }
7768 Py_INCREF(Py_None);
7769 return Py_None;
7770 }
7771#endif
7772
7773normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00007774 if (!PyArg_ParseTuple(args, "et|s:startfile",
7775 Py_FileSystemDefaultEncoding, &filepath,
7776 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00007777 return NULL;
7778 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00007779 rc = ShellExecute((HWND)0, operation, filepath,
7780 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007781 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00007782 if (rc <= (HINSTANCE)32) {
7783 PyObject *errval = win32_error("startfile", filepath);
7784 PyMem_Free(filepath);
7785 return errval;
7786 }
7787 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007788 Py_INCREF(Py_None);
7789 return Py_None;
7790}
7791#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007792
Martin v. Löwis438b5342002-12-27 10:16:42 +00007793#ifdef HAVE_GETLOADAVG
7794PyDoc_STRVAR(posix_getloadavg__doc__,
7795"getloadavg() -> (float, float, float)\n\n\
7796Return the number of processes in the system run queue averaged over\n\
7797the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7798was unobtainable");
7799
7800static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007801posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007802{
7803 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007804 if (getloadavg(loadavg, 3)!=3) {
7805 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7806 return NULL;
7807 } else
7808 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7809}
7810#endif
7811
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007812#ifdef MS_WINDOWS
7813
7814PyDoc_STRVAR(win32_urandom__doc__,
7815"urandom(n) -> str\n\n\
7816Return a string of n random bytes suitable for cryptographic use.");
7817
7818typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7819 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7820 DWORD dwFlags );
7821typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7822 BYTE *pbBuffer );
7823
7824static CRYPTGENRANDOM pCryptGenRandom = NULL;
7825static HCRYPTPROV hCryptProv = 0;
7826
Tim Peters4ad82172004-08-30 17:02:04 +00007827static PyObject*
7828win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007829{
Tim Petersd3115382004-08-30 17:36:46 +00007830 int howMany;
7831 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007832
Tim Peters4ad82172004-08-30 17:02:04 +00007833 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00007834 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00007835 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00007836 if (howMany < 0)
7837 return PyErr_Format(PyExc_ValueError,
7838 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007839
Tim Peters4ad82172004-08-30 17:02:04 +00007840 if (hCryptProv == 0) {
7841 HINSTANCE hAdvAPI32 = NULL;
7842 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007843
Tim Peters4ad82172004-08-30 17:02:04 +00007844 /* Obtain handle to the DLL containing CryptoAPI
7845 This should not fail */
7846 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7847 if(hAdvAPI32 == NULL)
7848 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007849
Tim Peters4ad82172004-08-30 17:02:04 +00007850 /* Obtain pointers to the CryptoAPI functions
7851 This will fail on some early versions of Win95 */
7852 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7853 hAdvAPI32,
7854 "CryptAcquireContextA");
7855 if (pCryptAcquireContext == NULL)
7856 return PyErr_Format(PyExc_NotImplementedError,
7857 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007858
Tim Peters4ad82172004-08-30 17:02:04 +00007859 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7860 hAdvAPI32, "CryptGenRandom");
7861 if (pCryptAcquireContext == NULL)
7862 return PyErr_Format(PyExc_NotImplementedError,
7863 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007864
Tim Peters4ad82172004-08-30 17:02:04 +00007865 /* Acquire context */
7866 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7867 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7868 return win32_error("CryptAcquireContext", NULL);
7869 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007870
Tim Peters4ad82172004-08-30 17:02:04 +00007871 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00007872 result = PyString_FromStringAndSize(NULL, howMany);
7873 if (result != NULL) {
7874 /* Get random data */
7875 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7876 PyString_AS_STRING(result))) {
7877 Py_DECREF(result);
7878 return win32_error("CryptGenRandom", NULL);
7879 }
Tim Peters4ad82172004-08-30 17:02:04 +00007880 }
Tim Petersd3115382004-08-30 17:36:46 +00007881 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007882}
7883#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007884
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007885static PyMethodDef posix_methods[] = {
7886 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7887#ifdef HAVE_TTYNAME
7888 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7889#endif
7890 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7891 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007892#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007893 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007894#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007895#ifdef HAVE_LCHOWN
7896 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7897#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007898#ifdef HAVE_CHROOT
7899 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7900#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007901#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007902 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007903#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007904#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007905 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007906#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007907 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007908#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007909#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007910#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007911 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007912#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007913 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7914 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7915 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007916#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007917 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007918#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007919#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007920 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007921#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007922 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7923 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7924 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007925 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007926#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007927 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007928#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007929#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007930 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007931#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007932 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007933#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007934 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007935#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007936 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7937 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7938 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007939#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007940 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007941#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007942 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007943#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007944 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7945 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007946#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007947#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007948 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7949 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007950#if defined(PYOS_OS2)
7951 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7952 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7953#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007954#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007955#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007956 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007957#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007958#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007959 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007960#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007961#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007962 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007963#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007964#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007965 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007966#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007967#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007968 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007969#endif /* HAVE_GETEGID */
7970#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007971 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007972#endif /* HAVE_GETEUID */
7973#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007974 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007975#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007976#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007977 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007978#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007979 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007980#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007981 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007982#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007983#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007984 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007985#endif /* HAVE_GETPPID */
7986#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007987 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007988#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007989#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007990 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007991#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007992#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007993 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007994#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007995#ifdef HAVE_KILLPG
7996 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7997#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007998#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007999 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008000#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008001#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008002 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008003#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008004 {"popen2", win32_popen2, METH_VARARGS},
8005 {"popen3", win32_popen3, METH_VARARGS},
8006 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00008007 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008008#else
8009#if defined(PYOS_OS2) && defined(PYCC_GCC)
8010 {"popen2", os2emx_popen2, METH_VARARGS},
8011 {"popen3", os2emx_popen3, METH_VARARGS},
8012 {"popen4", os2emx_popen4, METH_VARARGS},
8013#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008014#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008015#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008016#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008017 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008018#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008019#ifdef HAVE_SETEUID
8020 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8021#endif /* HAVE_SETEUID */
8022#ifdef HAVE_SETEGID
8023 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8024#endif /* HAVE_SETEGID */
8025#ifdef HAVE_SETREUID
8026 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8027#endif /* HAVE_SETREUID */
8028#ifdef HAVE_SETREGID
8029 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8030#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008031#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008032 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008033#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008034#ifdef HAVE_SETGROUPS
Georg Brandl96a8c392006-05-29 21:04:52 +00008035 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008036#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008037#ifdef HAVE_GETPGID
8038 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8039#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008040#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008041 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008042#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008043#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00008044 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008045#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008046#ifdef HAVE_WAIT3
8047 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8048#endif /* HAVE_WAIT3 */
8049#ifdef HAVE_WAIT4
8050 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8051#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008052#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008053 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008054#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008055#ifdef HAVE_GETSID
8056 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8057#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008058#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00008059 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008060#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008061#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008062 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008063#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008064#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008065 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008066#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008067#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008068 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008069#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008070 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8071 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8072 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8073 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8074 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8075 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8076 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8077 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8078 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00008079 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008080#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00008081 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008082#endif
8083#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008084 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008085#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008086#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008087 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8088#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008089#ifdef HAVE_DEVICE_MACROS
8090 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8091 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8092 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8093#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008094#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008095 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008096#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008097#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008098 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008099#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008100#ifdef HAVE_UNSETENV
8101 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8102#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00008103#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008104 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00008105#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00008106#ifdef HAVE_FCHDIR
8107 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8108#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008109#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008110 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008111#endif
8112#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008113 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008114#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008115#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008116#ifdef WCOREDUMP
8117 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8118#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008119#ifdef WIFCONTINUED
8120 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8121#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008122#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008123 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008124#endif /* WIFSTOPPED */
8125#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008126 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008127#endif /* WIFSIGNALED */
8128#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008129 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008130#endif /* WIFEXITED */
8131#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008132 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008133#endif /* WEXITSTATUS */
8134#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008135 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008136#endif /* WTERMSIG */
8137#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008138 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008139#endif /* WSTOPSIG */
8140#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008141#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008142 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008143#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008144#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008145 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008146#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008147#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00008148 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008149#endif
8150#ifdef HAVE_TEMPNAM
8151 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8152#endif
8153#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00008154 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008155#endif
Fred Drakec9680921999-12-13 16:37:25 +00008156#ifdef HAVE_CONFSTR
8157 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8158#endif
8159#ifdef HAVE_SYSCONF
8160 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8161#endif
8162#ifdef HAVE_FPATHCONF
8163 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8164#endif
8165#ifdef HAVE_PATHCONF
8166 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8167#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008168 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008169#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00008170 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8171#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008172#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00008173 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008174#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008175 #ifdef MS_WINDOWS
8176 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8177 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008178 {NULL, NULL} /* Sentinel */
8179};
8180
8181
Barry Warsaw4a342091996-12-19 23:50:02 +00008182static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008183ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008184{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008185 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008186}
8187
Guido van Rossumd48f2521997-12-05 22:19:34 +00008188#if defined(PYOS_OS2)
8189/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008190static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008191{
8192 APIRET rc;
8193 ULONG values[QSV_MAX+1];
8194 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008195 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008196
8197 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008198 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008199 Py_END_ALLOW_THREADS
8200
8201 if (rc != NO_ERROR) {
8202 os2_error(rc);
8203 return -1;
8204 }
8205
Fred Drake4d1e64b2002-04-15 19:40:07 +00008206 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8207 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8208 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8209 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8210 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8211 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8212 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008213
8214 switch (values[QSV_VERSION_MINOR]) {
8215 case 0: ver = "2.00"; break;
8216 case 10: ver = "2.10"; break;
8217 case 11: ver = "2.11"; break;
8218 case 30: ver = "3.00"; break;
8219 case 40: ver = "4.00"; break;
8220 case 50: ver = "5.00"; break;
8221 default:
Tim Peters885d4572001-11-28 20:27:42 +00008222 PyOS_snprintf(tmp, sizeof(tmp),
8223 "%d-%d", values[QSV_VERSION_MAJOR],
8224 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008225 ver = &tmp[0];
8226 }
8227
8228 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008229 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008230 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008231
8232 /* Add Indicator of Which Drive was Used to Boot the System */
8233 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8234 tmp[1] = ':';
8235 tmp[2] = '\0';
8236
Fred Drake4d1e64b2002-04-15 19:40:07 +00008237 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008238}
8239#endif
8240
Barry Warsaw4a342091996-12-19 23:50:02 +00008241static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008242all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008243{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008244#ifdef F_OK
8245 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008246#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008247#ifdef R_OK
8248 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008249#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008250#ifdef W_OK
8251 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008252#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008253#ifdef X_OK
8254 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008255#endif
Fred Drakec9680921999-12-13 16:37:25 +00008256#ifdef NGROUPS_MAX
8257 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8258#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008259#ifdef TMP_MAX
8260 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8261#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008262#ifdef WCONTINUED
8263 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8264#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008265#ifdef WNOHANG
8266 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008267#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008268#ifdef WUNTRACED
8269 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8270#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008271#ifdef O_RDONLY
8272 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8273#endif
8274#ifdef O_WRONLY
8275 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8276#endif
8277#ifdef O_RDWR
8278 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8279#endif
8280#ifdef O_NDELAY
8281 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8282#endif
8283#ifdef O_NONBLOCK
8284 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8285#endif
8286#ifdef O_APPEND
8287 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8288#endif
8289#ifdef O_DSYNC
8290 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8291#endif
8292#ifdef O_RSYNC
8293 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8294#endif
8295#ifdef O_SYNC
8296 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8297#endif
8298#ifdef O_NOCTTY
8299 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8300#endif
8301#ifdef O_CREAT
8302 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8303#endif
8304#ifdef O_EXCL
8305 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8306#endif
8307#ifdef O_TRUNC
8308 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8309#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008310#ifdef O_BINARY
8311 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8312#endif
8313#ifdef O_TEXT
8314 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8315#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008316#ifdef O_LARGEFILE
8317 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8318#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008319#ifdef O_SHLOCK
8320 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8321#endif
8322#ifdef O_EXLOCK
8323 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8324#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008325
Tim Peters5aa91602002-01-30 05:46:57 +00008326/* MS Windows */
8327#ifdef O_NOINHERIT
8328 /* Don't inherit in child processes. */
8329 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8330#endif
8331#ifdef _O_SHORT_LIVED
8332 /* Optimize for short life (keep in memory). */
8333 /* MS forgot to define this one with a non-underscore form too. */
8334 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8335#endif
8336#ifdef O_TEMPORARY
8337 /* Automatically delete when last handle is closed. */
8338 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8339#endif
8340#ifdef O_RANDOM
8341 /* Optimize for random access. */
8342 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8343#endif
8344#ifdef O_SEQUENTIAL
8345 /* Optimize for sequential access. */
8346 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8347#endif
8348
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008349/* GNU extensions. */
8350#ifdef O_DIRECT
8351 /* Direct disk access. */
8352 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8353#endif
8354#ifdef O_DIRECTORY
8355 /* Must be a directory. */
8356 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8357#endif
8358#ifdef O_NOFOLLOW
8359 /* Do not follow links. */
8360 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8361#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008362
Barry Warsaw5676bd12003-01-07 20:57:09 +00008363 /* These come from sysexits.h */
8364#ifdef EX_OK
8365 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008366#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008367#ifdef EX_USAGE
8368 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008369#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008370#ifdef EX_DATAERR
8371 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008372#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008373#ifdef EX_NOINPUT
8374 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008375#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008376#ifdef EX_NOUSER
8377 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008378#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008379#ifdef EX_NOHOST
8380 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008381#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008382#ifdef EX_UNAVAILABLE
8383 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008384#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008385#ifdef EX_SOFTWARE
8386 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008387#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008388#ifdef EX_OSERR
8389 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008390#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008391#ifdef EX_OSFILE
8392 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008393#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008394#ifdef EX_CANTCREAT
8395 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008396#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008397#ifdef EX_IOERR
8398 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008399#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008400#ifdef EX_TEMPFAIL
8401 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008402#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008403#ifdef EX_PROTOCOL
8404 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008405#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008406#ifdef EX_NOPERM
8407 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008408#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008409#ifdef EX_CONFIG
8410 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008411#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008412#ifdef EX_NOTFOUND
8413 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008414#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008415
Guido van Rossum246bc171999-02-01 23:54:31 +00008416#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008417#if defined(PYOS_OS2) && defined(PYCC_GCC)
8418 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8419 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8420 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8421 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8422 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8423 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8424 if (ins(d, "P_PM", (long)P_PM)) return -1;
8425 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8426 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8427 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8428 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8429 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8430 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8431 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8432 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8433 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8434 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8435 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8436 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8437 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8438#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008439 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8440 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8441 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8442 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8443 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008444#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008445#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008446
Guido van Rossumd48f2521997-12-05 22:19:34 +00008447#if defined(PYOS_OS2)
8448 if (insertvalues(d)) return -1;
8449#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008450 return 0;
8451}
8452
8453
Tim Peters5aa91602002-01-30 05:46:57 +00008454#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008455#define INITFUNC initnt
8456#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008457
8458#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008459#define INITFUNC initos2
8460#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008461
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008462#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008463#define INITFUNC initposix
8464#define MODNAME "posix"
8465#endif
8466
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008467PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008468INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008469{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008470 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008471
Fred Drake4d1e64b2002-04-15 19:40:07 +00008472 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008473 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008474 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008475 if (m == NULL)
8476 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008477
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008478 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008479 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008480 Py_XINCREF(v);
8481 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008482 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008483 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008484
Fred Drake4d1e64b2002-04-15 19:40:07 +00008485 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008486 return;
8487
Fred Drake4d1e64b2002-04-15 19:40:07 +00008488 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008489 return;
8490
Fred Drake4d1e64b2002-04-15 19:40:07 +00008491 Py_INCREF(PyExc_OSError);
8492 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008493
Guido van Rossumb3d39562000-01-31 18:41:26 +00008494#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008495 if (posix_putenv_garbage == NULL)
8496 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008497#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008498
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00008499 if (!initialized) {
8500 stat_result_desc.name = MODNAME ".stat_result";
8501 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8502 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8503 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8504 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8505 structseq_new = StatResultType.tp_new;
8506 StatResultType.tp_new = statresult_new;
8507
8508 statvfs_result_desc.name = MODNAME ".statvfs_result";
8509 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
8510 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008511 Py_INCREF((PyObject*) &StatResultType);
8512 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008513 Py_INCREF((PyObject*) &StatVFSResultType);
8514 PyModule_AddObject(m, "statvfs_result",
8515 (PyObject*) &StatVFSResultType);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00008516 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00008517
8518#ifdef __APPLE__
8519 /*
8520 * Step 2 of weak-linking support on Mac OS X.
8521 *
8522 * The code below removes functions that are not available on the
8523 * currently active platform.
8524 *
8525 * This block allow one to use a python binary that was build on
8526 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8527 * OSX 10.4.
8528 */
8529#ifdef HAVE_FSTATVFS
8530 if (fstatvfs == NULL) {
8531 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8532 return;
8533 }
8534 }
8535#endif /* HAVE_FSTATVFS */
8536
8537#ifdef HAVE_STATVFS
8538 if (statvfs == NULL) {
8539 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8540 return;
8541 }
8542 }
8543#endif /* HAVE_STATVFS */
8544
8545# ifdef HAVE_LCHOWN
8546 if (lchown == NULL) {
8547 if (PyObject_DelAttrString(m, "lchown") == -1) {
8548 return;
8549 }
8550 }
8551#endif /* HAVE_LCHOWN */
8552
8553
8554#endif /* __APPLE__ */
8555
Guido van Rossumb6775db1994-08-01 11:34:53 +00008556}
Anthony Baxterac6bd462006-04-13 02:06:09 +00008557
8558#ifdef __cplusplus
8559}
8560#endif
8561