blob: 5c67be6dc08e4df0e308ad8b9a4769b0badb2ae0 [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
Thomas Wouters477c8d52006-05-27 19:21:47 +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
Thomas Wouters49fd7fa2006-04-21 10:40:58 +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
Thomas Wouters0e3f5912006-08-11 14:57:12 +000067#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000068#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +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>
Thomas Wouters0e3f5912006-08-11 14:57:12 +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
Thomas Wouters0e3f5912006-08-11 14:57:12 +000079#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000080#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +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
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000256#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000258#endif
259#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000261#endif
262#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +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 Wouters477c8d52006-05-27 19:21:47 +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 Wouters477c8d52006-05-27 19:21:47 +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
Thomas Wouters49fd7fa2006-04-21 10:40:58 +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{
Thomas Wouters477c8d52006-05-27 19:21:47 +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. */
Thomas Wouters477c8d52006-05-27 19:21:47 +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 }
Thomas Wouters477c8d52006-05-27 19:21:47 +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 *
Thomas Wouters477c8d52006-05-27 19:21:47 +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,
Thomas Wouters477c8d52006-05-27 19:21:47 +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
Thomas Wouters477c8d52006-05-27 19:21:47 +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{
Thomas Wouters477c8d52006-05-27 19:21:47 +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
Thomas Wouters477c8d52006-05-27 19:21:47 +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;
796 memcpy(out_ptr, &out, sizeof(out));
797}
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
Thomas Wouters49fd7fa2006-04-21 10:40:58 +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
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001124 if (!ival)
1125 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001126 if (_stat_float_times) {
1127 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1128 } else {
1129 fval = ival;
1130 Py_INCREF(fval);
1131 }
1132 PyStructSequence_SET_ITEM(v, index, ival);
1133 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001134}
1135
Tim Peters5aa91602002-01-30 05:46:57 +00001136/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001137 (used by posix_stat() and posix_fstat()) */
1138static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001139_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001140{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001141 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001142 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001143 if (v == NULL)
1144 return NULL;
1145
Martin v. Löwis14694662006-02-03 12:54:16 +00001146 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001147#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001148 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001149 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001150#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001151 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001152#endif
1153#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001154 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001155 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001156#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001157 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001158#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001159 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1160 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1161 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001162#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001163 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001164 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001165#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001166 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001167#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001168
Martin v. Löwis14694662006-02-03 12:54:16 +00001169#if defined(HAVE_STAT_TV_NSEC)
1170 ansec = st->st_atim.tv_nsec;
1171 mnsec = st->st_mtim.tv_nsec;
1172 cnsec = st->st_ctim.tv_nsec;
1173#elif defined(HAVE_STAT_TV_NSEC2)
1174 ansec = st->st_atimespec.tv_nsec;
1175 mnsec = st->st_mtimespec.tv_nsec;
1176 cnsec = st->st_ctimespec.tv_nsec;
1177#elif defined(HAVE_STAT_NSEC)
1178 ansec = st->st_atime_nsec;
1179 mnsec = st->st_mtime_nsec;
1180 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001181#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001182 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001183#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001184 fill_time(v, 7, st->st_atime, ansec);
1185 fill_time(v, 8, st->st_mtime, mnsec);
1186 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001187
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001188#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001189 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001190 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001191#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001192#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001193 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001194 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001195#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001196#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001197 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001198 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001199#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001200#ifdef HAVE_STRUCT_STAT_ST_GEN
1201 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001202 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001203#endif
1204#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1205 {
1206 PyObject *val;
1207 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001208 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001209#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001210 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001211#else
1212 bnsec = 0;
1213#endif
1214 if (_stat_float_times) {
1215 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1216 } else {
1217 val = PyInt_FromLong((long)bsec);
1218 }
1219 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1220 val);
1221 }
1222#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001223#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1224 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001225 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001226#endif
Fred Drake699f3522000-06-29 21:12:41 +00001227
1228 if (PyErr_Occurred()) {
1229 Py_DECREF(v);
1230 return NULL;
1231 }
1232
1233 return v;
1234}
1235
Martin v. Löwisd8948722004-06-02 09:57:56 +00001236#ifdef MS_WINDOWS
1237
1238/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1239 where / can be used in place of \ and the trailing slash is optional.
1240 Both SERVER and SHARE must have at least one character.
1241*/
1242
1243#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1244#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001245#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001246#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001247#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001248
Tim Peters4ad82172004-08-30 17:02:04 +00001249static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001250IsUNCRootA(char *path, int pathlen)
1251{
1252 #define ISSLASH ISSLASHA
1253
1254 int i, share;
1255
1256 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1257 /* minimum UNCRoot is \\x\y */
1258 return FALSE;
1259 for (i = 2; i < pathlen ; i++)
1260 if (ISSLASH(path[i])) break;
1261 if (i == 2 || i == pathlen)
1262 /* do not allow \\\SHARE or \\SERVER */
1263 return FALSE;
1264 share = i+1;
1265 for (i = share; i < pathlen; i++)
1266 if (ISSLASH(path[i])) break;
1267 return (i != share && (i == pathlen || i == pathlen-1));
1268
1269 #undef ISSLASH
1270}
1271
1272#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001273static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001274IsUNCRootW(Py_UNICODE *path, int pathlen)
1275{
1276 #define ISSLASH ISSLASHW
1277
1278 int i, share;
1279
1280 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1281 /* minimum UNCRoot is \\x\y */
1282 return FALSE;
1283 for (i = 2; i < pathlen ; i++)
1284 if (ISSLASH(path[i])) break;
1285 if (i == 2 || i == pathlen)
1286 /* do not allow \\\SHARE or \\SERVER */
1287 return FALSE;
1288 share = i+1;
1289 for (i = share; i < pathlen; i++)
1290 if (ISSLASH(path[i])) break;
1291 return (i != share && (i == pathlen || i == pathlen-1));
1292
1293 #undef ISSLASH
1294}
1295#endif /* Py_WIN_WIDE_FILENAMES */
1296#endif /* MS_WINDOWS */
1297
Barry Warsaw53699e91996-12-10 23:23:01 +00001298static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001299posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001300 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001301#ifdef __VMS
1302 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1303#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001304 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001305#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001306 char *wformat,
1307 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001308{
Fred Drake699f3522000-06-29 21:12:41 +00001309 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001310 char *path = NULL; /* pass this to stat; do not free() it */
1311 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001312 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001313 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001314
1315#ifdef Py_WIN_WIDE_FILENAMES
1316 /* If on wide-character-capable OS see if argument
1317 is Unicode and if so use wide API. */
1318 if (unicode_file_names()) {
1319 PyUnicodeObject *po;
1320 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001321 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1322
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001323 Py_BEGIN_ALLOW_THREADS
1324 /* PyUnicode_AS_UNICODE result OK without
1325 thread lock as it is a simple dereference. */
1326 res = wstatfunc(wpath, &st);
1327 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001328
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001329 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001330 return win32_error_unicode("stat", wpath);
1331 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001332 }
1333 /* Drop the argument parsing error as narrow strings
1334 are also valid. */
1335 PyErr_Clear();
1336 }
1337#endif
1338
Tim Peters5aa91602002-01-30 05:46:57 +00001339 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001340 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001341 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001342 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001343
Barry Warsaw53699e91996-12-10 23:23:01 +00001344 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001345 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001346 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001347
1348 if (res != 0) {
1349#ifdef MS_WINDOWS
1350 result = win32_error("stat", pathfree);
1351#else
1352 result = posix_error_with_filename(pathfree);
1353#endif
1354 }
1355 else
1356 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001357
Tim Peters500bd032001-12-19 19:05:01 +00001358 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001359 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001360}
1361
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001362/* POSIX methods */
1363
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001364PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001365"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001366Use the real uid/gid to test for access to a path. Note that most\n\
1367operations will use the effective uid/gid, therefore this routine can\n\
1368be used in a suid/sgid environment to test if the invoking user has the\n\
1369specified access to the path. The mode argument can be F_OK to test\n\
1370existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001371
1372static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001373posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001374{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001375 char *path;
1376 int mode;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001377
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001378#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001379 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001380 if (unicode_file_names()) {
1381 PyUnicodeObject *po;
1382 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1383 Py_BEGIN_ALLOW_THREADS
1384 /* PyUnicode_AS_UNICODE OK without thread lock as
1385 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001386 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001387 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001388 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001389 }
1390 /* Drop the argument parsing error as narrow strings
1391 are also valid. */
1392 PyErr_Clear();
1393 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001394 if (!PyArg_ParseTuple(args, "eti:access",
1395 Py_FileSystemDefaultEncoding, &path, &mode))
1396 return 0;
1397 Py_BEGIN_ALLOW_THREADS
1398 attr = GetFileAttributesA(path);
1399 Py_END_ALLOW_THREADS
1400 PyMem_Free(path);
1401finish:
1402 if (attr == 0xFFFFFFFF)
1403 /* File does not exist, or cannot read attributes */
1404 return PyBool_FromLong(0);
1405 /* Access is possible if either write access wasn't requested, or
1406 the file isn't read-only. */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001407 return PyBool_FromLong(!(mode & 2) || !(attr & FILE_ATTRIBUTE_READONLY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001408#else
1409 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001410 if (!PyArg_ParseTuple(args, "eti:access",
1411 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001412 return NULL;
1413 Py_BEGIN_ALLOW_THREADS
1414 res = access(path, mode);
1415 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001416 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001417 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001418#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001419}
1420
Guido van Rossumd371ff11999-01-25 16:12:23 +00001421#ifndef F_OK
1422#define F_OK 0
1423#endif
1424#ifndef R_OK
1425#define R_OK 4
1426#endif
1427#ifndef W_OK
1428#define W_OK 2
1429#endif
1430#ifndef X_OK
1431#define X_OK 1
1432#endif
1433
1434#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001435PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001436"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001437Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001438
1439static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001440posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001441{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001442 int id;
1443 char *ret;
1444
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001445 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001446 return NULL;
1447
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001448#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001449 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001450 if (id == 0) {
1451 ret = ttyname();
1452 }
1453 else {
1454 ret = NULL;
1455 }
1456#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001457 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001458#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001459 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001460 return posix_error();
1461 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001462}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001463#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001464
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001465#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001466PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001467"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001468Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001469
1470static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001471posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001472{
1473 char *ret;
1474 char buffer[L_ctermid];
1475
Greg Wardb48bc172000-03-01 21:51:56 +00001476#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001477 ret = ctermid_r(buffer);
1478#else
1479 ret = ctermid(buffer);
1480#endif
1481 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001482 return posix_error();
1483 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001484}
1485#endif
1486
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001487PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001488"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001489Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001490
Barry Warsaw53699e91996-12-10 23:23:01 +00001491static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001492posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001493{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001494#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001495 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001496#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001497 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001498#elif defined(__VMS)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001499 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001500#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001501 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001502#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001503}
1504
Fred Drake4d1e64b2002-04-15 19:40:07 +00001505#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001506PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001507"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001508Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001509opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001510
1511static PyObject *
1512posix_fchdir(PyObject *self, PyObject *fdobj)
1513{
1514 return posix_fildes(fdobj, fchdir);
1515}
1516#endif /* HAVE_FCHDIR */
1517
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001518
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001519PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001520"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001521Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001522
Barry Warsaw53699e91996-12-10 23:23:01 +00001523static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001524posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001525{
Mark Hammondef8b6542001-05-13 08:04:26 +00001526 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001527 int i;
1528 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001529#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001530 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001531 if (unicode_file_names()) {
1532 PyUnicodeObject *po;
1533 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1534 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001535 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1536 if (attr != 0xFFFFFFFF) {
1537 if (i & _S_IWRITE)
1538 attr &= ~FILE_ATTRIBUTE_READONLY;
1539 else
1540 attr |= FILE_ATTRIBUTE_READONLY;
1541 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1542 }
1543 else
1544 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001545 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001546 if (!res)
1547 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001548 PyUnicode_AS_UNICODE(po));
1549 Py_INCREF(Py_None);
1550 return Py_None;
1551 }
1552 /* Drop the argument parsing error as narrow strings
1553 are also valid. */
1554 PyErr_Clear();
1555 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001556 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1557 &path, &i))
1558 return NULL;
1559 Py_BEGIN_ALLOW_THREADS
1560 attr = GetFileAttributesA(path);
1561 if (attr != 0xFFFFFFFF) {
1562 if (i & _S_IWRITE)
1563 attr &= ~FILE_ATTRIBUTE_READONLY;
1564 else
1565 attr |= FILE_ATTRIBUTE_READONLY;
1566 res = SetFileAttributesA(path, attr);
1567 }
1568 else
1569 res = 0;
1570 Py_END_ALLOW_THREADS
1571 if (!res) {
1572 win32_error("chmod", path);
1573 PyMem_Free(path);
1574 return NULL;
1575 }
1576 PyMem_Free(path);
1577 Py_INCREF(Py_None);
1578 return Py_None;
1579#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001580 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001581 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001582 return NULL;
1583 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001584 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001585 Py_END_ALLOW_THREADS
1586 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001587 return posix_error_with_allocated_filename(path);
1588 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001589 Py_INCREF(Py_None);
1590 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001591#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001592}
1593
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001594
Martin v. Löwis244edc82001-10-04 22:44:26 +00001595#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001596PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001597"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001598Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001599
1600static PyObject *
1601posix_chroot(PyObject *self, PyObject *args)
1602{
Thomas Wouters477c8d52006-05-27 19:21:47 +00001603 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001604}
1605#endif
1606
Guido van Rossum21142a01999-01-08 21:05:37 +00001607#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001608PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001609"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001610force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001611
1612static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001613posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001614{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001615 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001616}
1617#endif /* HAVE_FSYNC */
1618
1619#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001620
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001621#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001622extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1623#endif
1624
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001625PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001626"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001627force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001628 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001629
1630static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001631posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001632{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001633 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001634}
1635#endif /* HAVE_FDATASYNC */
1636
1637
Fredrik Lundh10723342000-07-10 16:38:09 +00001638#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001639PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001640"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001641Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001642
Barry Warsaw53699e91996-12-10 23:23:01 +00001643static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001644posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001645{
Mark Hammondef8b6542001-05-13 08:04:26 +00001646 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001647 int uid, gid;
1648 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001649 if (!PyArg_ParseTuple(args, "etii:chown",
1650 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001651 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001652 return NULL;
1653 Py_BEGIN_ALLOW_THREADS
1654 res = chown(path, (uid_t) uid, (gid_t) gid);
1655 Py_END_ALLOW_THREADS
1656 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001657 return posix_error_with_allocated_filename(path);
1658 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001659 Py_INCREF(Py_None);
1660 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001661}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001662#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001663
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001664#ifdef HAVE_LCHOWN
1665PyDoc_STRVAR(posix_lchown__doc__,
1666"lchown(path, uid, gid)\n\n\
1667Change the owner and group id of path to the numeric uid and gid.\n\
1668This function will not follow symbolic links.");
1669
1670static PyObject *
1671posix_lchown(PyObject *self, PyObject *args)
1672{
1673 char *path = NULL;
1674 int uid, gid;
1675 int res;
1676 if (!PyArg_ParseTuple(args, "etii:lchown",
1677 Py_FileSystemDefaultEncoding, &path,
1678 &uid, &gid))
1679 return NULL;
1680 Py_BEGIN_ALLOW_THREADS
1681 res = lchown(path, (uid_t) uid, (gid_t) gid);
1682 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001683 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001684 return posix_error_with_allocated_filename(path);
1685 PyMem_Free(path);
1686 Py_INCREF(Py_None);
1687 return Py_None;
1688}
1689#endif /* HAVE_LCHOWN */
1690
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001691
Guido van Rossum36bc6801995-06-14 22:54:23 +00001692#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001693PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001694"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001695Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001696
Barry Warsaw53699e91996-12-10 23:23:01 +00001697static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001698posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001699{
1700 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001701 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001702
Barry Warsaw53699e91996-12-10 23:23:01 +00001703 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001704#if defined(PYOS_OS2) && defined(PYCC_GCC)
1705 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001706#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001707 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001708#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001709 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001710 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001711 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001712 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001713}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001714
Walter Dörwald3b918c32002-11-21 20:18:46 +00001715#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001716PyDoc_STRVAR(posix_getcwdu__doc__,
1717"getcwdu() -> path\n\n\
1718Return a unicode string representing the current working directory.");
1719
1720static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001721posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001722{
1723 char buf[1026];
1724 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001725
1726#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001727 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001728 if (unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001729 wchar_t wbuf[1026];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001730 wchar_t *wbuf2 = wbuf;
1731 PyObject *resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001732 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001733 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
1734 /* If the buffer is large enough, len does not include the
1735 terminating \0. If the buffer is too small, len includes
1736 the space needed for the terminator. */
1737 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
1738 wbuf2 = malloc(len * sizeof(wchar_t));
1739 if (wbuf2)
1740 len = GetCurrentDirectoryW(len, wbuf2);
1741 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001742 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001743 if (!wbuf2) {
1744 PyErr_NoMemory();
1745 return NULL;
1746 }
1747 if (!len) {
1748 if (wbuf2 != wbuf) free(wbuf2);
1749 return win32_error("getcwdu", NULL);
1750 }
1751 resobj = PyUnicode_FromWideChar(wbuf2, len);
1752 if (wbuf2 != wbuf) free(wbuf2);
1753 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001754 }
1755#endif
1756
1757 Py_BEGIN_ALLOW_THREADS
1758#if defined(PYOS_OS2) && defined(PYCC_GCC)
1759 res = _getcwd2(buf, sizeof buf);
1760#else
1761 res = getcwd(buf, sizeof buf);
1762#endif
1763 Py_END_ALLOW_THREADS
1764 if (res == NULL)
1765 return posix_error();
1766 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1767}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001768#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001769#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001770
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001771
Guido van Rossumb6775db1994-08-01 11:34:53 +00001772#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001773PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001774"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001775Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001776
Barry Warsaw53699e91996-12-10 23:23:01 +00001777static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001778posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001779{
Thomas Wouters477c8d52006-05-27 19:21:47 +00001780 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001781}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001782#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001783
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001784
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001785PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001786"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001787Return a list containing the names of the entries in the directory.\n\
1788\n\
1789 path: path of directory to list\n\
1790\n\
1791The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001792entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001793
Barry Warsaw53699e91996-12-10 23:23:01 +00001794static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001795posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001796{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001797 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001798 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001799#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001800
Barry Warsaw53699e91996-12-10 23:23:01 +00001801 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001802 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001803 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001804 WIN32_FIND_DATA FileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001805 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00001806 char *bufptr = namebuf;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001807 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001808
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001809#ifdef Py_WIN_WIDE_FILENAMES
1810 /* If on wide-character-capable OS see if argument
1811 is Unicode and if so use wide API. */
1812 if (unicode_file_names()) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001813 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001814 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1815 WIN32_FIND_DATAW wFileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001816 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001817 Py_UNICODE wch;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001818 /* Overallocate for \\*.*\0 */
1819 len = PyUnicode_GET_SIZE(po);
1820 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
1821 if (!wnamebuf) {
1822 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001823 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001824 }
1825 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
1826 wch = len > 0 ? wnamebuf[len-1] : '\0';
1827 if (wch != L'/' && wch != L'\\' && wch != L':')
1828 wnamebuf[len++] = L'\\';
1829 wcscpy(wnamebuf + len, L"*.*");
1830 if ((d = PyList_New(0)) == NULL) {
1831 free(wnamebuf);
1832 return NULL;
1833 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001834 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1835 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001836 int error = GetLastError();
1837 if (error == ERROR_FILE_NOT_FOUND) {
1838 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001839 return d;
1840 }
1841 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001842 win32_error_unicode("FindFirstFileW", wnamebuf);
1843 free(wnamebuf);
1844 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001845 }
1846 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001847 /* Skip over . and .. */
1848 if (wcscmp(wFileData.cFileName, L".") != 0 &&
1849 wcscmp(wFileData.cFileName, L"..") != 0) {
1850 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1851 if (v == NULL) {
1852 Py_DECREF(d);
1853 d = NULL;
1854 break;
1855 }
1856 if (PyList_Append(d, v) != 0) {
1857 Py_DECREF(v);
1858 Py_DECREF(d);
1859 d = NULL;
1860 break;
1861 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001862 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001863 }
Georg Brandl622927b2006-03-07 12:48:03 +00001864 Py_BEGIN_ALLOW_THREADS
1865 result = FindNextFileW(hFindFile, &wFileData);
1866 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001867 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
1868 it got to the end of the directory. */
1869 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
1870 Py_DECREF(d);
1871 win32_error_unicode("FindNextFileW", wnamebuf);
1872 FindClose(hFindFile);
1873 free(wnamebuf);
1874 return NULL;
1875 }
Georg Brandl622927b2006-03-07 12:48:03 +00001876 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001877
1878 if (FindClose(hFindFile) == FALSE) {
1879 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001880 win32_error_unicode("FindClose", wnamebuf);
1881 free(wnamebuf);
1882 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001883 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001884 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001885 return d;
1886 }
1887 /* Drop the argument parsing error as narrow strings
1888 are also valid. */
1889 PyErr_Clear();
1890 }
1891#endif
1892
Tim Peters5aa91602002-01-30 05:46:57 +00001893 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001894 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001895 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001896 if (len > 0) {
1897 char ch = namebuf[len-1];
1898 if (ch != SEP && ch != ALTSEP && ch != ':')
1899 namebuf[len++] = '/';
1900 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001901 strcpy(namebuf + len, "*.*");
1902
Barry Warsaw53699e91996-12-10 23:23:01 +00001903 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001904 return NULL;
1905
1906 hFindFile = FindFirstFile(namebuf, &FileData);
1907 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001908 int error = GetLastError();
1909 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001910 return d;
1911 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001912 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001913 }
1914 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001915 /* Skip over . and .. */
1916 if (strcmp(FileData.cFileName, ".") != 0 &&
1917 strcmp(FileData.cFileName, "..") != 0) {
1918 v = PyString_FromString(FileData.cFileName);
1919 if (v == NULL) {
1920 Py_DECREF(d);
1921 d = NULL;
1922 break;
1923 }
1924 if (PyList_Append(d, v) != 0) {
1925 Py_DECREF(v);
1926 Py_DECREF(d);
1927 d = NULL;
1928 break;
1929 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001930 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001931 }
Georg Brandl622927b2006-03-07 12:48:03 +00001932 Py_BEGIN_ALLOW_THREADS
1933 result = FindNextFile(hFindFile, &FileData);
1934 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001935 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
1936 it got to the end of the directory. */
1937 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
1938 Py_DECREF(d);
1939 win32_error("FindNextFile", namebuf);
1940 FindClose(hFindFile);
1941 return NULL;
1942 }
Georg Brandl622927b2006-03-07 12:48:03 +00001943 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001944
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001945 if (FindClose(hFindFile) == FALSE) {
1946 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001947 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001948 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001949
1950 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001951
Tim Peters0bb44a42000-09-15 07:44:49 +00001952#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001953
1954#ifndef MAX_PATH
1955#define MAX_PATH CCHMAXPATH
1956#endif
1957 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00001958 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001959 PyObject *d, *v;
1960 char namebuf[MAX_PATH+5];
1961 HDIR hdir = 1;
1962 ULONG srchcnt = 1;
1963 FILEFINDBUF3 ep;
1964 APIRET rc;
1965
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001966 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001967 return NULL;
1968 if (len >= MAX_PATH) {
1969 PyErr_SetString(PyExc_ValueError, "path too long");
1970 return NULL;
1971 }
1972 strcpy(namebuf, name);
1973 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001974 if (*pt == ALTSEP)
1975 *pt = SEP;
1976 if (namebuf[len-1] != SEP)
1977 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001978 strcpy(namebuf + len, "*.*");
1979
1980 if ((d = PyList_New(0)) == NULL)
1981 return NULL;
1982
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001983 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1984 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001985 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001986 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1987 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1988 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001989
1990 if (rc != NO_ERROR) {
1991 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001992 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001993 }
1994
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001995 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001996 do {
1997 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001998 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001999 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002000
2001 strcpy(namebuf, ep.achName);
2002
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002003 /* Leave Case of Name Alone -- In Native Form */
2004 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002005
2006 v = PyString_FromString(namebuf);
2007 if (v == NULL) {
2008 Py_DECREF(d);
2009 d = NULL;
2010 break;
2011 }
2012 if (PyList_Append(d, v) != 0) {
2013 Py_DECREF(v);
2014 Py_DECREF(d);
2015 d = NULL;
2016 break;
2017 }
2018 Py_DECREF(v);
2019 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2020 }
2021
2022 return d;
2023#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002024
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002025 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002026 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002027 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002028 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002029 int arg_is_unicode = 1;
2030
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002031 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002032 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2033 arg_is_unicode = 0;
2034 PyErr_Clear();
2035 }
2036 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002037 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002038 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002039 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002040 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002041 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002042 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002043 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002044 return NULL;
2045 }
Georg Brandl622927b2006-03-07 12:48:03 +00002046 for (;;) {
2047 Py_BEGIN_ALLOW_THREADS
2048 ep = readdir(dirp);
2049 Py_END_ALLOW_THREADS
2050 if (ep == NULL)
2051 break;
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002052 if (ep->d_name[0] == '.' &&
2053 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002054 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002055 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00002056 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002057 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002058 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002059 d = NULL;
2060 break;
2061 }
Just van Rossum46c97842003-02-25 21:42:15 +00002062#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00002063 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002064 PyObject *w;
2065
2066 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002067 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002068 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002069 if (w != NULL) {
2070 Py_DECREF(v);
2071 v = w;
2072 }
2073 else {
2074 /* fall back to the original byte string, as
2075 discussed in patch #683592 */
2076 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002077 }
Just van Rossum46c97842003-02-25 21:42:15 +00002078 }
2079#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002080 if (PyList_Append(d, v) != 0) {
2081 Py_DECREF(v);
2082 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002083 d = NULL;
2084 break;
2085 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002086 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002087 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002088 if (errno != 0 && d != NULL) {
2089 /* readdir() returned NULL and set errno */
2090 closedir(dirp);
2091 Py_DECREF(d);
2092 return posix_error_with_allocated_filename(name);
2093 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002094 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002095 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002096
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002097 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002098
Tim Peters0bb44a42000-09-15 07:44:49 +00002099#endif /* which OS */
2100} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002101
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002102#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002103/* A helper function for abspath on win32 */
2104static PyObject *
2105posix__getfullpathname(PyObject *self, PyObject *args)
2106{
2107 /* assume encoded strings wont more than double no of chars */
2108 char inbuf[MAX_PATH*2];
2109 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002110 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002111 char outbuf[MAX_PATH*2];
2112 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002113#ifdef Py_WIN_WIDE_FILENAMES
2114 if (unicode_file_names()) {
2115 PyUnicodeObject *po;
2116 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2117 Py_UNICODE woutbuf[MAX_PATH*2];
2118 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00002119 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002120 sizeof(woutbuf)/sizeof(woutbuf[0]),
2121 woutbuf, &wtemp))
2122 return win32_error("GetFullPathName", "");
2123 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
2124 }
2125 /* Drop the argument parsing error as narrow strings
2126 are also valid. */
2127 PyErr_Clear();
2128 }
2129#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002130 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2131 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002132 &insize))
2133 return NULL;
2134 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2135 outbuf, &temp))
2136 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002137 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2138 return PyUnicode_Decode(outbuf, strlen(outbuf),
2139 Py_FileSystemDefaultEncoding, NULL);
2140 }
Mark Hammondef8b6542001-05-13 08:04:26 +00002141 return PyString_FromString(outbuf);
2142} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002143#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002144
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002145PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002146"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002147Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002148
Barry Warsaw53699e91996-12-10 23:23:01 +00002149static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002150posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002151{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002152 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002153 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002154 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002155
2156#ifdef Py_WIN_WIDE_FILENAMES
2157 if (unicode_file_names()) {
2158 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002159 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002160 Py_BEGIN_ALLOW_THREADS
2161 /* PyUnicode_AS_UNICODE OK without thread lock as
2162 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002163 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002164 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002165 if (!res)
2166 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002167 Py_INCREF(Py_None);
2168 return Py_None;
2169 }
2170 /* Drop the argument parsing error as narrow strings
2171 are also valid. */
2172 PyErr_Clear();
2173 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002174 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2175 Py_FileSystemDefaultEncoding, &path, &mode))
2176 return NULL;
2177 Py_BEGIN_ALLOW_THREADS
2178 /* PyUnicode_AS_UNICODE OK without thread lock as
2179 it is a simple dereference. */
2180 res = CreateDirectoryA(path, NULL);
2181 Py_END_ALLOW_THREADS
2182 if (!res) {
2183 win32_error("mkdir", path);
2184 PyMem_Free(path);
2185 return NULL;
2186 }
2187 PyMem_Free(path);
2188 Py_INCREF(Py_None);
2189 return Py_None;
2190#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002191
Tim Peters5aa91602002-01-30 05:46:57 +00002192 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002193 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002194 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002195 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002196#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002197 res = mkdir(path);
2198#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002199 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002200#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002201 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002202 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002203 return posix_error_with_allocated_filename(path);
2204 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002205 Py_INCREF(Py_None);
2206 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002207#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002208}
2209
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002210
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002211/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2212#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002213#include <sys/resource.h>
2214#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002215
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002216
2217#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002218PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002219"nice(inc) -> new_priority\n\n\
2220Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002221
Barry Warsaw53699e91996-12-10 23:23:01 +00002222static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002223posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002224{
2225 int increment, value;
2226
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002227 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002228 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002229
2230 /* There are two flavours of 'nice': one that returns the new
2231 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002232 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2233 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002234
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002235 If we are of the nice family that returns the new priority, we
2236 need to clear errno before the call, and check if errno is filled
2237 before calling posix_error() on a returnvalue of -1, because the
2238 -1 may be the actual new priority! */
2239
2240 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002241 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002242#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002243 if (value == 0)
2244 value = getpriority(PRIO_PROCESS, 0);
2245#endif
2246 if (value == -1 && errno != 0)
2247 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002248 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002249 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002250}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002251#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002252
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002253PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002254"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002255Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002256
Barry Warsaw53699e91996-12-10 23:23:01 +00002257static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002258posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002259{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002260#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002261 PyObject *o1, *o2;
2262 char *p1, *p2;
2263 BOOL result;
2264 if (unicode_file_names()) {
2265 if (!PyArg_ParseTuple(args, "O&O&:rename",
2266 convert_to_unicode, &o1,
2267 convert_to_unicode, &o2))
2268 PyErr_Clear();
2269 else {
2270 Py_BEGIN_ALLOW_THREADS
2271 result = MoveFileW(PyUnicode_AsUnicode(o1),
2272 PyUnicode_AsUnicode(o2));
2273 Py_END_ALLOW_THREADS
2274 Py_DECREF(o1);
2275 Py_DECREF(o2);
2276 if (!result)
2277 return win32_error("rename", NULL);
2278 Py_INCREF(Py_None);
2279 return Py_None;
2280 }
2281 }
2282 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2283 return NULL;
2284 Py_BEGIN_ALLOW_THREADS
2285 result = MoveFileA(p1, p2);
2286 Py_END_ALLOW_THREADS
2287 if (!result)
2288 return win32_error("rename", NULL);
2289 Py_INCREF(Py_None);
2290 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002291#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002292 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002293#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002294}
2295
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002296
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002297PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002298"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002299Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002300
Barry Warsaw53699e91996-12-10 23:23:01 +00002301static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002302posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002303{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002304#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002305 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002306#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002307 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002308#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002309}
2310
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002311
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002312PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002313"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002314Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002315
Barry Warsaw53699e91996-12-10 23:23:01 +00002316static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002317posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002318{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002319#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002320 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002321#else
2322 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2323#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002324}
2325
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002326
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002327#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002328PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002329"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002330Execute the command (a string) in a subshell.");
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_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002334{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002335 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002336 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002337 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002338 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002339 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002340 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002341 Py_END_ALLOW_THREADS
2342 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002343}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002344#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002345
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002346
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002347PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002348"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002349Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002350
Barry Warsaw53699e91996-12-10 23:23:01 +00002351static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002352posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002353{
2354 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002355 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002356 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002357 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002358 if (i < 0)
2359 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002360 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002361}
2362
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002363
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002364PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002365"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002366Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002367
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002368PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002369"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002370Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002371
Barry Warsaw53699e91996-12-10 23:23:01 +00002372static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002373posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002374{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002375#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002376 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002377#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002378 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002379#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002380}
2381
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002382
Guido van Rossumb6775db1994-08-01 11:34:53 +00002383#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002384PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002385"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002386Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002387
Barry Warsaw53699e91996-12-10 23:23:01 +00002388static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002389posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002390{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002391 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002392 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002393
Barry Warsaw53699e91996-12-10 23:23:01 +00002394 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002395 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002396 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002397 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002398 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002399 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002400 u.sysname,
2401 u.nodename,
2402 u.release,
2403 u.version,
2404 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002405}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002406#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002407
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002408static int
2409extract_time(PyObject *t, long* sec, long* usec)
2410{
2411 long intval;
2412 if (PyFloat_Check(t)) {
2413 double tval = PyFloat_AsDouble(t);
2414 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2415 if (!intobj)
2416 return -1;
2417 intval = PyInt_AsLong(intobj);
2418 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002419 if (intval == -1 && PyErr_Occurred())
2420 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002421 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002422 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002423 if (*usec < 0)
2424 /* If rounding gave us a negative number,
2425 truncate. */
2426 *usec = 0;
2427 return 0;
2428 }
2429 intval = PyInt_AsLong(t);
2430 if (intval == -1 && PyErr_Occurred())
2431 return -1;
2432 *sec = intval;
2433 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002434 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002435}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002436
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002437PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002438"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002439utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002440Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002441second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002442
Barry Warsaw53699e91996-12-10 23:23:01 +00002443static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002444posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002445{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002446#ifdef Py_WIN_WIDE_FILENAMES
2447 PyObject *arg;
2448 PyUnicodeObject *obwpath;
2449 wchar_t *wpath = NULL;
2450 char *apath = NULL;
2451 HANDLE hFile;
2452 long atimesec, mtimesec, ausec, musec;
2453 FILETIME atime, mtime;
2454 PyObject *result = NULL;
2455
2456 if (unicode_file_names()) {
2457 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2458 wpath = PyUnicode_AS_UNICODE(obwpath);
2459 Py_BEGIN_ALLOW_THREADS
2460 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2461 NULL, OPEN_EXISTING, 0, NULL);
2462 Py_END_ALLOW_THREADS
2463 if (hFile == INVALID_HANDLE_VALUE)
2464 return win32_error_unicode("utime", wpath);
2465 } else
2466 /* Drop the argument parsing error as narrow strings
2467 are also valid. */
2468 PyErr_Clear();
2469 }
2470 if (!wpath) {
2471 if (!PyArg_ParseTuple(args, "etO:utime",
2472 Py_FileSystemDefaultEncoding, &apath, &arg))
2473 return NULL;
2474 Py_BEGIN_ALLOW_THREADS
2475 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2476 NULL, OPEN_EXISTING, 0, NULL);
2477 Py_END_ALLOW_THREADS
2478 if (hFile == INVALID_HANDLE_VALUE) {
2479 win32_error("utime", apath);
2480 PyMem_Free(apath);
2481 return NULL;
2482 }
2483 PyMem_Free(apath);
2484 }
2485
2486 if (arg == Py_None) {
2487 SYSTEMTIME now;
2488 GetSystemTime(&now);
2489 if (!SystemTimeToFileTime(&now, &mtime) ||
2490 !SystemTimeToFileTime(&now, &atime)) {
2491 win32_error("utime", NULL);
2492 goto done;
2493 }
2494 }
2495 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2496 PyErr_SetString(PyExc_TypeError,
2497 "utime() arg 2 must be a tuple (atime, mtime)");
2498 goto done;
2499 }
2500 else {
2501 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2502 &atimesec, &ausec) == -1)
2503 goto done;
2504 time_t_to_FILE_TIME(atimesec, ausec, &atime);
2505 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2506 &mtimesec, &musec) == -1)
2507 goto done;
2508 time_t_to_FILE_TIME(mtimesec, musec, &mtime);
2509 }
2510 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2511 /* Avoid putting the file name into the error here,
2512 as that may confuse the user into believing that
2513 something is wrong with the file, when it also
2514 could be the time stamp that gives a problem. */
2515 win32_error("utime", NULL);
2516 }
2517 Py_INCREF(Py_None);
2518 result = Py_None;
2519done:
2520 CloseHandle(hFile);
2521 return result;
2522#else /* Py_WIN_WIDE_FILENAMES */
2523
Neal Norwitz2adf2102004-06-09 01:46:02 +00002524 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002525 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002526 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002527 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002528
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002529#if defined(HAVE_UTIMES)
2530 struct timeval buf[2];
2531#define ATIME buf[0].tv_sec
2532#define MTIME buf[1].tv_sec
2533#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002534/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002535 struct utimbuf buf;
2536#define ATIME buf.actime
2537#define MTIME buf.modtime
2538#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002539#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002540 time_t buf[2];
2541#define ATIME buf[0]
2542#define MTIME buf[1]
2543#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002544#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002545
Mark Hammond817c9292003-12-03 01:22:38 +00002546
Thomas Wouters477c8d52006-05-27 19:21:47 +00002547 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002548 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002549 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002550 if (arg == Py_None) {
2551 /* optional time values not given */
2552 Py_BEGIN_ALLOW_THREADS
2553 res = utime(path, NULL);
2554 Py_END_ALLOW_THREADS
2555 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002556 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002557 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002558 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002559 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002560 return NULL;
2561 }
2562 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002563 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002564 &atime, &ausec) == -1) {
2565 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002566 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002567 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002568 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002569 &mtime, &musec) == -1) {
2570 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002571 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002572 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002573 ATIME = atime;
2574 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002575#ifdef HAVE_UTIMES
2576 buf[0].tv_usec = ausec;
2577 buf[1].tv_usec = musec;
2578 Py_BEGIN_ALLOW_THREADS
2579 res = utimes(path, buf);
2580 Py_END_ALLOW_THREADS
2581#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002582 Py_BEGIN_ALLOW_THREADS
2583 res = utime(path, UTIME_ARG);
2584 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002585#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002586 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002587 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002588 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002589 }
Neal Norwitz96652712004-06-06 20:40:27 +00002590 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002591 Py_INCREF(Py_None);
2592 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002593#undef UTIME_ARG
2594#undef ATIME
2595#undef MTIME
Thomas Wouters477c8d52006-05-27 19:21:47 +00002596#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002597}
2598
Guido van Rossum85e3b011991-06-03 12:42:10 +00002599
Guido van Rossum3b066191991-06-04 19:40:25 +00002600/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002601
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002602PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002603"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002604Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002605
Barry Warsaw53699e91996-12-10 23:23:01 +00002606static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002607posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002608{
2609 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002610 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002611 return NULL;
2612 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002613 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002614}
2615
Martin v. Löwis114619e2002-10-07 06:44:21 +00002616#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2617static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002618free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002619{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002620 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002621 for (i = 0; i < count; i++)
2622 PyMem_Free(array[i]);
2623 PyMem_DEL(array);
2624}
2625#endif
2626
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002627
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002628#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002629PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002630"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002631Execute an executable path with arguments, replacing current process.\n\
2632\n\
2633 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002634 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002635
Barry Warsaw53699e91996-12-10 23:23:01 +00002636static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002637posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002638{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002639 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002640 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002641 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002642 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002643 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002644
Guido van Rossum89b33251993-10-22 14:26:06 +00002645 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002646 argv is a list or tuple of strings. */
2647
Martin v. Löwis114619e2002-10-07 06:44:21 +00002648 if (!PyArg_ParseTuple(args, "etO:execv",
2649 Py_FileSystemDefaultEncoding,
2650 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002651 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002652 if (PyList_Check(argv)) {
2653 argc = PyList_Size(argv);
2654 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002655 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002656 else if (PyTuple_Check(argv)) {
2657 argc = PyTuple_Size(argv);
2658 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002659 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002660 else {
Fred Drake661ea262000-10-24 19:57:45 +00002661 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002662 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002663 return NULL;
2664 }
2665
Barry Warsaw53699e91996-12-10 23:23:01 +00002666 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002667 if (argvlist == NULL) {
2668 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002669 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002670 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002671 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002672 if (!PyArg_Parse((*getitem)(argv, i), "et",
2673 Py_FileSystemDefaultEncoding,
2674 &argvlist[i])) {
2675 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002676 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002677 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002678 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002679 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002680
Guido van Rossum85e3b011991-06-03 12:42:10 +00002681 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002682 }
2683 argvlist[argc] = NULL;
2684
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002685 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002686
Guido van Rossum85e3b011991-06-03 12:42:10 +00002687 /* If we get here it's definitely an error */
2688
Martin v. Löwis114619e2002-10-07 06:44:21 +00002689 free_string_array(argvlist, argc);
2690 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002691 return posix_error();
2692}
2693
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002694
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002695PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002696"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002697Execute a path with arguments and environment, replacing current process.\n\
2698\n\
2699 path: path of executable file\n\
2700 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002701 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002702
Barry Warsaw53699e91996-12-10 23:23:01 +00002703static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002704posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002705{
2706 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002707 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002708 char **argvlist;
2709 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002710 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002711 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002712 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002713 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002714
2715 /* execve has three arguments: (path, argv, env), where
2716 argv is a list or tuple of strings and env is a dictionary
2717 like posix.environ. */
2718
Martin v. Löwis114619e2002-10-07 06:44:21 +00002719 if (!PyArg_ParseTuple(args, "etOO:execve",
2720 Py_FileSystemDefaultEncoding,
2721 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002722 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002723 if (PyList_Check(argv)) {
2724 argc = PyList_Size(argv);
2725 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002726 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002727 else if (PyTuple_Check(argv)) {
2728 argc = PyTuple_Size(argv);
2729 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002730 }
2731 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002732 PyErr_SetString(PyExc_TypeError,
2733 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002734 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002735 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002736 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002737 PyErr_SetString(PyExc_TypeError,
2738 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002739 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002740 }
2741
Barry Warsaw53699e91996-12-10 23:23:01 +00002742 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002743 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002744 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002745 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002746 }
2747 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002748 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002749 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002750 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002751 &argvlist[i]))
2752 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002753 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002754 goto fail_1;
2755 }
2756 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002757 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002758 argvlist[argc] = NULL;
2759
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002760 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002761 if (i < 0)
2762 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002763 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002764 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002765 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002766 goto fail_1;
2767 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002768 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002769 keys = PyMapping_Keys(env);
2770 vals = PyMapping_Values(env);
2771 if (!keys || !vals)
2772 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002773 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2774 PyErr_SetString(PyExc_TypeError,
2775 "execve(): env.keys() or env.values() is not a list");
2776 goto fail_2;
2777 }
Tim Peters5aa91602002-01-30 05:46:57 +00002778
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002779 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002780 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002781 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002782
2783 key = PyList_GetItem(keys, pos);
2784 val = PyList_GetItem(vals, pos);
2785 if (!key || !val)
2786 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002787
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002788 if (!PyArg_Parse(
2789 key,
2790 "s;execve() arg 3 contains a non-string key",
2791 &k) ||
2792 !PyArg_Parse(
2793 val,
2794 "s;execve() arg 3 contains a non-string value",
2795 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002796 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002797 goto fail_2;
2798 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002799
2800#if defined(PYOS_OS2)
2801 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2802 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2803#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002804 len = PyString_Size(key) + PyString_Size(val) + 2;
2805 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002806 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002807 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002808 goto fail_2;
2809 }
Tim Petersc8996f52001-12-03 20:41:00 +00002810 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002811 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002812#if defined(PYOS_OS2)
2813 }
2814#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002815 }
2816 envlist[envc] = 0;
2817
2818 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002819
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002820 /* If we get here it's definitely an error */
2821
2822 (void) posix_error();
2823
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002824 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002825 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002826 PyMem_DEL(envlist[envc]);
2827 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002828 fail_1:
2829 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002830 Py_XDECREF(vals);
2831 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002832 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002833 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002834 return NULL;
2835}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002836#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002837
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002838
Guido van Rossuma1065681999-01-25 23:20:23 +00002839#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002840PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002841"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002842Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002843\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002844 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002845 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002846 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002847
2848static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002849posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002850{
2851 char *path;
2852 PyObject *argv;
2853 char **argvlist;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002854 int mode, i;
2855 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002856 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002857 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00002858
2859 /* spawnv has three arguments: (mode, path, argv), where
2860 argv is a list or tuple of strings. */
2861
Martin v. Löwis114619e2002-10-07 06:44:21 +00002862 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2863 Py_FileSystemDefaultEncoding,
2864 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002865 return NULL;
2866 if (PyList_Check(argv)) {
2867 argc = PyList_Size(argv);
2868 getitem = PyList_GetItem;
2869 }
2870 else if (PyTuple_Check(argv)) {
2871 argc = PyTuple_Size(argv);
2872 getitem = PyTuple_GetItem;
2873 }
2874 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002875 PyErr_SetString(PyExc_TypeError,
2876 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002877 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002878 return NULL;
2879 }
2880
2881 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002882 if (argvlist == NULL) {
2883 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002884 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002885 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002886 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002887 if (!PyArg_Parse((*getitem)(argv, i), "et",
2888 Py_FileSystemDefaultEncoding,
2889 &argvlist[i])) {
2890 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002891 PyErr_SetString(
2892 PyExc_TypeError,
2893 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002894 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002895 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002896 }
2897 }
2898 argvlist[argc] = NULL;
2899
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002900#if defined(PYOS_OS2) && defined(PYCC_GCC)
2901 Py_BEGIN_ALLOW_THREADS
2902 spawnval = spawnv(mode, path, argvlist);
2903 Py_END_ALLOW_THREADS
2904#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002905 if (mode == _OLD_P_OVERLAY)
2906 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002907
Tim Peters25059d32001-12-07 20:35:43 +00002908 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002909 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002910 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002911#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002912
Martin v. Löwis114619e2002-10-07 06:44:21 +00002913 free_string_array(argvlist, argc);
2914 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002915
Fred Drake699f3522000-06-29 21:12:41 +00002916 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002917 return posix_error();
2918 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002919#if SIZEOF_LONG == SIZEOF_VOID_P
2920 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002921#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002922 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002923#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002924}
2925
2926
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002927PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002928"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002929Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002930\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002931 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002932 path: path of executable file\n\
2933 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002934 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002935
2936static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002937posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002938{
2939 char *path;
2940 PyObject *argv, *env;
2941 char **argvlist;
2942 char **envlist;
2943 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002944 int mode, pos, envc;
2945 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00002946 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002947 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002948 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002949
2950 /* spawnve has four arguments: (mode, path, argv, env), where
2951 argv is a list or tuple of strings and env is a dictionary
2952 like posix.environ. */
2953
Martin v. Löwis114619e2002-10-07 06:44:21 +00002954 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2955 Py_FileSystemDefaultEncoding,
2956 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002957 return NULL;
2958 if (PyList_Check(argv)) {
2959 argc = PyList_Size(argv);
2960 getitem = PyList_GetItem;
2961 }
2962 else if (PyTuple_Check(argv)) {
2963 argc = PyTuple_Size(argv);
2964 getitem = PyTuple_GetItem;
2965 }
2966 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002967 PyErr_SetString(PyExc_TypeError,
2968 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002969 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002970 }
2971 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002972 PyErr_SetString(PyExc_TypeError,
2973 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002974 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002975 }
2976
2977 argvlist = PyMem_NEW(char *, argc+1);
2978 if (argvlist == NULL) {
2979 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002980 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002981 }
2982 for (i = 0; i < argc; i++) {
2983 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002984 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002985 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002986 &argvlist[i]))
2987 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002988 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002989 goto fail_1;
2990 }
2991 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002992 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002993 argvlist[argc] = NULL;
2994
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002995 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002996 if (i < 0)
2997 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002998 envlist = PyMem_NEW(char *, i + 1);
2999 if (envlist == NULL) {
3000 PyErr_NoMemory();
3001 goto fail_1;
3002 }
3003 envc = 0;
3004 keys = PyMapping_Keys(env);
3005 vals = PyMapping_Values(env);
3006 if (!keys || !vals)
3007 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003008 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3009 PyErr_SetString(PyExc_TypeError,
3010 "spawnve(): env.keys() or env.values() is not a list");
3011 goto fail_2;
3012 }
Tim Peters5aa91602002-01-30 05:46:57 +00003013
Guido van Rossuma1065681999-01-25 23:20:23 +00003014 for (pos = 0; pos < i; pos++) {
3015 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003016 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003017
3018 key = PyList_GetItem(keys, pos);
3019 val = PyList_GetItem(vals, pos);
3020 if (!key || !val)
3021 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003022
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003023 if (!PyArg_Parse(
3024 key,
3025 "s;spawnve() arg 3 contains a non-string key",
3026 &k) ||
3027 !PyArg_Parse(
3028 val,
3029 "s;spawnve() arg 3 contains a non-string value",
3030 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003031 {
3032 goto fail_2;
3033 }
Tim Petersc8996f52001-12-03 20:41:00 +00003034 len = PyString_Size(key) + PyString_Size(val) + 2;
3035 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003036 if (p == NULL) {
3037 PyErr_NoMemory();
3038 goto fail_2;
3039 }
Tim Petersc8996f52001-12-03 20:41:00 +00003040 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003041 envlist[envc++] = p;
3042 }
3043 envlist[envc] = 0;
3044
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003045#if defined(PYOS_OS2) && defined(PYCC_GCC)
3046 Py_BEGIN_ALLOW_THREADS
3047 spawnval = spawnve(mode, path, argvlist, envlist);
3048 Py_END_ALLOW_THREADS
3049#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003050 if (mode == _OLD_P_OVERLAY)
3051 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003052
3053 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003054 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003055 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003056#endif
Tim Peters25059d32001-12-07 20:35:43 +00003057
Fred Drake699f3522000-06-29 21:12:41 +00003058 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003059 (void) posix_error();
3060 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003061#if SIZEOF_LONG == SIZEOF_VOID_P
3062 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003063#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003064 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003065#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003066
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003067 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003068 while (--envc >= 0)
3069 PyMem_DEL(envlist[envc]);
3070 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003071 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003072 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003073 Py_XDECREF(vals);
3074 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003075 fail_0:
3076 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003077 return res;
3078}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003079
3080/* OS/2 supports spawnvp & spawnvpe natively */
3081#if defined(PYOS_OS2)
3082PyDoc_STRVAR(posix_spawnvp__doc__,
3083"spawnvp(mode, file, args)\n\n\
3084Execute the program 'file' in a new process, using the environment\n\
3085search path to find the file.\n\
3086\n\
3087 mode: mode of process creation\n\
3088 file: executable file name\n\
3089 args: tuple or list of strings");
3090
3091static PyObject *
3092posix_spawnvp(PyObject *self, PyObject *args)
3093{
3094 char *path;
3095 PyObject *argv;
3096 char **argvlist;
3097 int mode, i, argc;
3098 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003099 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003100
3101 /* spawnvp has three arguments: (mode, path, argv), where
3102 argv is a list or tuple of strings. */
3103
3104 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3105 Py_FileSystemDefaultEncoding,
3106 &path, &argv))
3107 return NULL;
3108 if (PyList_Check(argv)) {
3109 argc = PyList_Size(argv);
3110 getitem = PyList_GetItem;
3111 }
3112 else if (PyTuple_Check(argv)) {
3113 argc = PyTuple_Size(argv);
3114 getitem = PyTuple_GetItem;
3115 }
3116 else {
3117 PyErr_SetString(PyExc_TypeError,
3118 "spawnvp() arg 2 must be a tuple or list");
3119 PyMem_Free(path);
3120 return NULL;
3121 }
3122
3123 argvlist = PyMem_NEW(char *, argc+1);
3124 if (argvlist == NULL) {
3125 PyMem_Free(path);
3126 return PyErr_NoMemory();
3127 }
3128 for (i = 0; i < argc; i++) {
3129 if (!PyArg_Parse((*getitem)(argv, i), "et",
3130 Py_FileSystemDefaultEncoding,
3131 &argvlist[i])) {
3132 free_string_array(argvlist, i);
3133 PyErr_SetString(
3134 PyExc_TypeError,
3135 "spawnvp() arg 2 must contain only strings");
3136 PyMem_Free(path);
3137 return NULL;
3138 }
3139 }
3140 argvlist[argc] = NULL;
3141
3142 Py_BEGIN_ALLOW_THREADS
3143#if defined(PYCC_GCC)
3144 spawnval = spawnvp(mode, path, argvlist);
3145#else
3146 spawnval = _spawnvp(mode, path, argvlist);
3147#endif
3148 Py_END_ALLOW_THREADS
3149
3150 free_string_array(argvlist, argc);
3151 PyMem_Free(path);
3152
3153 if (spawnval == -1)
3154 return posix_error();
3155 else
3156 return Py_BuildValue("l", (long) spawnval);
3157}
3158
3159
3160PyDoc_STRVAR(posix_spawnvpe__doc__,
3161"spawnvpe(mode, file, args, env)\n\n\
3162Execute the program 'file' in a new process, using the environment\n\
3163search path to find the file.\n\
3164\n\
3165 mode: mode of process creation\n\
3166 file: executable file name\n\
3167 args: tuple or list of arguments\n\
3168 env: dictionary of strings mapping to strings");
3169
3170static PyObject *
3171posix_spawnvpe(PyObject *self, PyObject *args)
3172{
3173 char *path;
3174 PyObject *argv, *env;
3175 char **argvlist;
3176 char **envlist;
3177 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3178 int mode, i, pos, argc, envc;
3179 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003180 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003181 int lastarg = 0;
3182
3183 /* spawnvpe has four arguments: (mode, path, argv, env), where
3184 argv is a list or tuple of strings and env is a dictionary
3185 like posix.environ. */
3186
3187 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3188 Py_FileSystemDefaultEncoding,
3189 &path, &argv, &env))
3190 return NULL;
3191 if (PyList_Check(argv)) {
3192 argc = PyList_Size(argv);
3193 getitem = PyList_GetItem;
3194 }
3195 else if (PyTuple_Check(argv)) {
3196 argc = PyTuple_Size(argv);
3197 getitem = PyTuple_GetItem;
3198 }
3199 else {
3200 PyErr_SetString(PyExc_TypeError,
3201 "spawnvpe() arg 2 must be a tuple or list");
3202 goto fail_0;
3203 }
3204 if (!PyMapping_Check(env)) {
3205 PyErr_SetString(PyExc_TypeError,
3206 "spawnvpe() arg 3 must be a mapping object");
3207 goto fail_0;
3208 }
3209
3210 argvlist = PyMem_NEW(char *, argc+1);
3211 if (argvlist == NULL) {
3212 PyErr_NoMemory();
3213 goto fail_0;
3214 }
3215 for (i = 0; i < argc; i++) {
3216 if (!PyArg_Parse((*getitem)(argv, i),
3217 "et;spawnvpe() arg 2 must contain only strings",
3218 Py_FileSystemDefaultEncoding,
3219 &argvlist[i]))
3220 {
3221 lastarg = i;
3222 goto fail_1;
3223 }
3224 }
3225 lastarg = argc;
3226 argvlist[argc] = NULL;
3227
3228 i = PyMapping_Size(env);
3229 if (i < 0)
3230 goto fail_1;
3231 envlist = PyMem_NEW(char *, i + 1);
3232 if (envlist == NULL) {
3233 PyErr_NoMemory();
3234 goto fail_1;
3235 }
3236 envc = 0;
3237 keys = PyMapping_Keys(env);
3238 vals = PyMapping_Values(env);
3239 if (!keys || !vals)
3240 goto fail_2;
3241 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3242 PyErr_SetString(PyExc_TypeError,
3243 "spawnvpe(): env.keys() or env.values() is not a list");
3244 goto fail_2;
3245 }
3246
3247 for (pos = 0; pos < i; pos++) {
3248 char *p, *k, *v;
3249 size_t len;
3250
3251 key = PyList_GetItem(keys, pos);
3252 val = PyList_GetItem(vals, pos);
3253 if (!key || !val)
3254 goto fail_2;
3255
3256 if (!PyArg_Parse(
3257 key,
3258 "s;spawnvpe() arg 3 contains a non-string key",
3259 &k) ||
3260 !PyArg_Parse(
3261 val,
3262 "s;spawnvpe() arg 3 contains a non-string value",
3263 &v))
3264 {
3265 goto fail_2;
3266 }
3267 len = PyString_Size(key) + PyString_Size(val) + 2;
3268 p = PyMem_NEW(char, len);
3269 if (p == NULL) {
3270 PyErr_NoMemory();
3271 goto fail_2;
3272 }
3273 PyOS_snprintf(p, len, "%s=%s", k, v);
3274 envlist[envc++] = p;
3275 }
3276 envlist[envc] = 0;
3277
3278 Py_BEGIN_ALLOW_THREADS
3279#if defined(PYCC_GCC)
3280 spawnval = spawnve(mode, path, argvlist, envlist);
3281#else
3282 spawnval = _spawnve(mode, path, argvlist, envlist);
3283#endif
3284 Py_END_ALLOW_THREADS
3285
3286 if (spawnval == -1)
3287 (void) posix_error();
3288 else
3289 res = Py_BuildValue("l", (long) spawnval);
3290
3291 fail_2:
3292 while (--envc >= 0)
3293 PyMem_DEL(envlist[envc]);
3294 PyMem_DEL(envlist);
3295 fail_1:
3296 free_string_array(argvlist, lastarg);
3297 Py_XDECREF(vals);
3298 Py_XDECREF(keys);
3299 fail_0:
3300 PyMem_Free(path);
3301 return res;
3302}
3303#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003304#endif /* HAVE_SPAWNV */
3305
3306
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003307#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003308PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003309"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003310Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3311\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003312Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003313
3314static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003315posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003316{
Neal Norwitze241ce82003-02-17 18:17:05 +00003317 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003318 if (pid == -1)
3319 return posix_error();
3320 PyOS_AfterFork();
3321 return PyInt_FromLong((long)pid);
3322}
3323#endif
3324
3325
Guido van Rossumad0ee831995-03-01 10:34:45 +00003326#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003327PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003328"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003329Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003330Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003331
Barry Warsaw53699e91996-12-10 23:23:01 +00003332static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003333posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003334{
Neal Norwitze241ce82003-02-17 18:17:05 +00003335 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003336 if (pid == -1)
3337 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003338 if (pid == 0)
3339 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003340 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003341}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003342#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003343
Neal Norwitzb59798b2003-03-21 01:43:31 +00003344/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003345/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3346#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003347#define DEV_PTY_FILE "/dev/ptc"
3348#define HAVE_DEV_PTMX
3349#else
3350#define DEV_PTY_FILE "/dev/ptmx"
3351#endif
3352
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003353#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003354#ifdef HAVE_PTY_H
3355#include <pty.h>
3356#else
3357#ifdef HAVE_LIBUTIL_H
3358#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003359#endif /* HAVE_LIBUTIL_H */
3360#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003361#ifdef HAVE_STROPTS_H
3362#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003363#endif
3364#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003365
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003366#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003367PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003368"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003369Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003370
3371static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003372posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003373{
3374 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003375#ifndef HAVE_OPENPTY
3376 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003377#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003378#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003379 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003380#ifdef sun
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003381 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003382#endif
3383#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003384
Thomas Wouters70c21a12000-07-14 14:28:33 +00003385#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003386 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3387 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003388#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003389 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3390 if (slave_name == NULL)
3391 return posix_error();
3392
3393 slave_fd = open(slave_name, O_RDWR);
3394 if (slave_fd < 0)
3395 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003396#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003397 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003398 if (master_fd < 0)
3399 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003400 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003401 /* change permission of slave */
3402 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003403 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003404 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003405 }
3406 /* unlock slave */
3407 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003408 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003409 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003410 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003411 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003412 slave_name = ptsname(master_fd); /* get name of slave */
3413 if (slave_name == NULL)
3414 return posix_error();
3415 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3416 if (slave_fd < 0)
3417 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003418#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003419 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3420 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003421#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003422 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003423#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003424#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003425#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003426
Fred Drake8cef4cf2000-06-28 16:40:38 +00003427 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003428
Fred Drake8cef4cf2000-06-28 16:40:38 +00003429}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003430#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003431
3432#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003433PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003434"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003435Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3436Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003437To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003438
3439static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003440posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003441{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003442 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003443
Fred Drake8cef4cf2000-06-28 16:40:38 +00003444 pid = forkpty(&master_fd, NULL, NULL, NULL);
3445 if (pid == -1)
3446 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003447 if (pid == 0)
3448 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003449 return Py_BuildValue("(ii)", pid, master_fd);
3450}
3451#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003452
Guido van Rossumad0ee831995-03-01 10:34:45 +00003453#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003454PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003455"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003456Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003457
Barry Warsaw53699e91996-12-10 23:23:01 +00003458static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003459posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003460{
Barry Warsaw53699e91996-12-10 23:23:01 +00003461 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003462}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003463#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003464
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003465
Guido van Rossumad0ee831995-03-01 10:34:45 +00003466#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003467PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003468"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003469Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003470
Barry Warsaw53699e91996-12-10 23:23:01 +00003471static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003472posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003473{
Barry Warsaw53699e91996-12-10 23:23:01 +00003474 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003475}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003476#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003477
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003478
Guido van Rossumad0ee831995-03-01 10:34:45 +00003479#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003480PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003481"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003482Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003483
Barry Warsaw53699e91996-12-10 23:23:01 +00003484static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003485posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003486{
Barry Warsaw53699e91996-12-10 23:23:01 +00003487 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003488}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003489#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003490
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003491
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003492PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003493"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003494Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003495
Barry Warsaw53699e91996-12-10 23:23:01 +00003496static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003497posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003498{
Barry Warsaw53699e91996-12-10 23:23:01 +00003499 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003500}
3501
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003502
Fred Drakec9680921999-12-13 16:37:25 +00003503#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003504PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003505"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003506Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003507
3508static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003509posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003510{
3511 PyObject *result = NULL;
3512
Fred Drakec9680921999-12-13 16:37:25 +00003513#ifdef NGROUPS_MAX
3514#define MAX_GROUPS NGROUPS_MAX
3515#else
3516 /* defined to be 16 on Solaris7, so this should be a small number */
3517#define MAX_GROUPS 64
3518#endif
3519 gid_t grouplist[MAX_GROUPS];
3520 int n;
3521
3522 n = getgroups(MAX_GROUPS, grouplist);
3523 if (n < 0)
3524 posix_error();
3525 else {
3526 result = PyList_New(n);
3527 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003528 int i;
3529 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003530 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003531 if (o == NULL) {
3532 Py_DECREF(result);
3533 result = NULL;
3534 break;
3535 }
3536 PyList_SET_ITEM(result, i, o);
3537 }
3538 }
3539 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003540
Fred Drakec9680921999-12-13 16:37:25 +00003541 return result;
3542}
3543#endif
3544
Martin v. Löwis606edc12002-06-13 21:09:11 +00003545#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003546PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003547"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003548Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003549
3550static PyObject *
3551posix_getpgid(PyObject *self, PyObject *args)
3552{
3553 int pid, pgid;
3554 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3555 return NULL;
3556 pgid = getpgid(pid);
3557 if (pgid < 0)
3558 return posix_error();
3559 return PyInt_FromLong((long)pgid);
3560}
3561#endif /* HAVE_GETPGID */
3562
3563
Guido van Rossumb6775db1994-08-01 11:34:53 +00003564#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003565PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003566"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003567Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003568
Barry Warsaw53699e91996-12-10 23:23:01 +00003569static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003570posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003571{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003572#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003573 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003574#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003575 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003576#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003577}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003578#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003579
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003580
Guido van Rossumb6775db1994-08-01 11:34:53 +00003581#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003582PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003583"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003584Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003585
Barry Warsaw53699e91996-12-10 23:23:01 +00003586static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003587posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003588{
Guido van Rossum64933891994-10-20 21:56:42 +00003589#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003590 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003591#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003592 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003593#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003594 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003595 Py_INCREF(Py_None);
3596 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003597}
3598
Guido van Rossumb6775db1994-08-01 11:34:53 +00003599#endif /* HAVE_SETPGRP */
3600
Guido van Rossumad0ee831995-03-01 10:34:45 +00003601#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003602PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003603"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003604Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003605
Barry Warsaw53699e91996-12-10 23:23:01 +00003606static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003607posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003608{
Barry Warsaw53699e91996-12-10 23:23:01 +00003609 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003610}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003611#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003612
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003613
Fred Drake12c6e2d1999-12-14 21:25:03 +00003614#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003615PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003616"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003617Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003618
3619static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003620posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003621{
Neal Norwitze241ce82003-02-17 18:17:05 +00003622 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003623 char *name;
3624 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003625
Fred Drakea30680b2000-12-06 21:24:28 +00003626 errno = 0;
3627 name = getlogin();
3628 if (name == NULL) {
3629 if (errno)
3630 posix_error();
3631 else
3632 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003633 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003634 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003635 else
3636 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003637 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003638
Fred Drake12c6e2d1999-12-14 21:25:03 +00003639 return result;
3640}
3641#endif
3642
Guido van Rossumad0ee831995-03-01 10:34:45 +00003643#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003644PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003645"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003646Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003647
Barry Warsaw53699e91996-12-10 23:23:01 +00003648static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003649posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003650{
Barry Warsaw53699e91996-12-10 23:23:01 +00003651 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003652}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003653#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003654
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003655
Guido van Rossumad0ee831995-03-01 10:34:45 +00003656#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003657PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003658"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003659Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003660
Barry Warsaw53699e91996-12-10 23:23:01 +00003661static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003662posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003663{
3664 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003665 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003666 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003667#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003668 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3669 APIRET rc;
3670 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003671 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003672
3673 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3674 APIRET rc;
3675 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003676 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003677
3678 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003679 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003680#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003681 if (kill(pid, sig) == -1)
3682 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003683#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003684 Py_INCREF(Py_None);
3685 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003686}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003687#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003688
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003689#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003690PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003691"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003692Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003693
3694static PyObject *
3695posix_killpg(PyObject *self, PyObject *args)
3696{
3697 int pgid, sig;
3698 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3699 return NULL;
3700 if (killpg(pgid, sig) == -1)
3701 return posix_error();
3702 Py_INCREF(Py_None);
3703 return Py_None;
3704}
3705#endif
3706
Guido van Rossumc0125471996-06-28 18:55:32 +00003707#ifdef HAVE_PLOCK
3708
3709#ifdef HAVE_SYS_LOCK_H
3710#include <sys/lock.h>
3711#endif
3712
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003713PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003714"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003715Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003716
Barry Warsaw53699e91996-12-10 23:23:01 +00003717static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003718posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003719{
3720 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003721 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003722 return NULL;
3723 if (plock(op) == -1)
3724 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003725 Py_INCREF(Py_None);
3726 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003727}
3728#endif
3729
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003730
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003731#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003732PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003733"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003734Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003735
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003736#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003737#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003738static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003739async_system(const char *command)
3740{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003741 char errormsg[256], args[1024];
3742 RESULTCODES rcodes;
3743 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003744
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003745 char *shell = getenv("COMSPEC");
3746 if (!shell)
3747 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003748
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003749 /* avoid overflowing the argument buffer */
3750 if (strlen(shell) + 3 + strlen(command) >= 1024)
3751 return ERROR_NOT_ENOUGH_MEMORY
3752
3753 args[0] = '\0';
3754 strcat(args, shell);
3755 strcat(args, "/c ");
3756 strcat(args, command);
3757
3758 /* execute asynchronously, inheriting the environment */
3759 rc = DosExecPgm(errormsg,
3760 sizeof(errormsg),
3761 EXEC_ASYNC,
3762 args,
3763 NULL,
3764 &rcodes,
3765 shell);
3766 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003767}
3768
Guido van Rossumd48f2521997-12-05 22:19:34 +00003769static FILE *
3770popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003771{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003772 int oldfd, tgtfd;
3773 HFILE pipeh[2];
3774 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003775
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003776 /* mode determines which of stdin or stdout is reconnected to
3777 * the pipe to the child
3778 */
3779 if (strchr(mode, 'r') != NULL) {
3780 tgt_fd = 1; /* stdout */
3781 } else if (strchr(mode, 'w')) {
3782 tgt_fd = 0; /* stdin */
3783 } else {
3784 *err = ERROR_INVALID_ACCESS;
3785 return NULL;
3786 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003787
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00003788 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003789 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3790 *err = rc;
3791 return NULL;
3792 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003793
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003794 /* prevent other threads accessing stdio */
3795 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003796
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003797 /* reconnect stdio and execute child */
3798 oldfd = dup(tgtfd);
3799 close(tgtfd);
3800 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3801 DosClose(pipeh[tgtfd]);
3802 rc = async_system(command);
3803 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003804
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003805 /* restore stdio */
3806 dup2(oldfd, tgtfd);
3807 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003808
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003809 /* allow other threads access to stdio */
3810 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003811
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003812 /* if execution of child was successful return file stream */
3813 if (rc == NO_ERROR)
3814 return fdopen(pipeh[1 - tgtfd], mode);
3815 else {
3816 DosClose(pipeh[1 - tgtfd]);
3817 *err = rc;
3818 return NULL;
3819 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003820}
3821
3822static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003823posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003824{
3825 char *name;
3826 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003827 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003828 FILE *fp;
3829 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003830 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003831 return NULL;
3832 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003833 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003834 Py_END_ALLOW_THREADS
3835 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003836 return os2_error(err);
3837
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003838 f = PyFile_FromFile(fp, name, mode, fclose);
3839 if (f != NULL)
3840 PyFile_SetBufSize(f, bufsize);
3841 return f;
3842}
3843
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003844#elif defined(PYCC_GCC)
3845
3846/* standard posix version of popen() support */
3847static PyObject *
3848posix_popen(PyObject *self, PyObject *args)
3849{
3850 char *name;
3851 char *mode = "r";
3852 int bufsize = -1;
3853 FILE *fp;
3854 PyObject *f;
3855 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3856 return NULL;
3857 Py_BEGIN_ALLOW_THREADS
3858 fp = popen(name, mode);
3859 Py_END_ALLOW_THREADS
3860 if (fp == NULL)
3861 return posix_error();
3862 f = PyFile_FromFile(fp, name, mode, pclose);
3863 if (f != NULL)
3864 PyFile_SetBufSize(f, bufsize);
3865 return f;
3866}
3867
3868/* fork() under OS/2 has lots'o'warts
3869 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3870 * most of this code is a ripoff of the win32 code, but using the
3871 * capabilities of EMX's C library routines
3872 */
3873
3874/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3875#define POPEN_1 1
3876#define POPEN_2 2
3877#define POPEN_3 3
3878#define POPEN_4 4
3879
3880static PyObject *_PyPopen(char *, int, int, int);
3881static int _PyPclose(FILE *file);
3882
3883/*
3884 * Internal dictionary mapping popen* file pointers to process handles,
3885 * for use when retrieving the process exit code. See _PyPclose() below
3886 * for more information on this dictionary's use.
3887 */
3888static PyObject *_PyPopenProcs = NULL;
3889
3890/* os2emx version of popen2()
3891 *
3892 * The result of this function is a pipe (file) connected to the
3893 * process's stdin, and a pipe connected to the process's stdout.
3894 */
3895
3896static PyObject *
3897os2emx_popen2(PyObject *self, PyObject *args)
3898{
3899 PyObject *f;
3900 int tm=0;
3901
3902 char *cmdstring;
3903 char *mode = "t";
3904 int bufsize = -1;
3905 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3906 return NULL;
3907
3908 if (*mode == 't')
3909 tm = O_TEXT;
3910 else if (*mode != 'b') {
3911 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3912 return NULL;
3913 } else
3914 tm = O_BINARY;
3915
3916 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3917
3918 return f;
3919}
3920
3921/*
3922 * Variation on os2emx.popen2
3923 *
3924 * The result of this function is 3 pipes - the process's stdin,
3925 * stdout and stderr
3926 */
3927
3928static PyObject *
3929os2emx_popen3(PyObject *self, PyObject *args)
3930{
3931 PyObject *f;
3932 int tm = 0;
3933
3934 char *cmdstring;
3935 char *mode = "t";
3936 int bufsize = -1;
3937 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3938 return NULL;
3939
3940 if (*mode == 't')
3941 tm = O_TEXT;
3942 else if (*mode != 'b') {
3943 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3944 return NULL;
3945 } else
3946 tm = O_BINARY;
3947
3948 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3949
3950 return f;
3951}
3952
3953/*
3954 * Variation on os2emx.popen2
3955 *
Tim Peters11b23062003-04-23 02:39:17 +00003956 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003957 * and stdout+stderr combined as a single pipe.
3958 */
3959
3960static PyObject *
3961os2emx_popen4(PyObject *self, PyObject *args)
3962{
3963 PyObject *f;
3964 int tm = 0;
3965
3966 char *cmdstring;
3967 char *mode = "t";
3968 int bufsize = -1;
3969 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3970 return NULL;
3971
3972 if (*mode == 't')
3973 tm = O_TEXT;
3974 else if (*mode != 'b') {
3975 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3976 return NULL;
3977 } else
3978 tm = O_BINARY;
3979
3980 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3981
3982 return f;
3983}
3984
3985/* a couple of structures for convenient handling of multiple
3986 * file handles and pipes
3987 */
3988struct file_ref
3989{
3990 int handle;
3991 int flags;
3992};
3993
3994struct pipe_ref
3995{
3996 int rd;
3997 int wr;
3998};
3999
4000/* The following code is derived from the win32 code */
4001
4002static PyObject *
4003_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4004{
4005 struct file_ref stdio[3];
4006 struct pipe_ref p_fd[3];
4007 FILE *p_s[3];
4008 int file_count, i, pipe_err, pipe_pid;
4009 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4010 PyObject *f, *p_f[3];
4011
4012 /* file modes for subsequent fdopen's on pipe handles */
4013 if (mode == O_TEXT)
4014 {
4015 rd_mode = "rt";
4016 wr_mode = "wt";
4017 }
4018 else
4019 {
4020 rd_mode = "rb";
4021 wr_mode = "wb";
4022 }
4023
4024 /* prepare shell references */
4025 if ((shell = getenv("EMXSHELL")) == NULL)
4026 if ((shell = getenv("COMSPEC")) == NULL)
4027 {
4028 errno = ENOENT;
4029 return posix_error();
4030 }
4031
4032 sh_name = _getname(shell);
4033 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4034 opt = "/c";
4035 else
4036 opt = "-c";
4037
4038 /* save current stdio fds + their flags, and set not inheritable */
4039 i = pipe_err = 0;
4040 while (pipe_err >= 0 && i < 3)
4041 {
4042 pipe_err = stdio[i].handle = dup(i);
4043 stdio[i].flags = fcntl(i, F_GETFD, 0);
4044 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4045 i++;
4046 }
4047 if (pipe_err < 0)
4048 {
4049 /* didn't get them all saved - clean up and bail out */
4050 int saved_err = errno;
4051 while (i-- > 0)
4052 {
4053 close(stdio[i].handle);
4054 }
4055 errno = saved_err;
4056 return posix_error();
4057 }
4058
4059 /* create pipe ends */
4060 file_count = 2;
4061 if (n == POPEN_3)
4062 file_count = 3;
4063 i = pipe_err = 0;
4064 while ((pipe_err == 0) && (i < file_count))
4065 pipe_err = pipe((int *)&p_fd[i++]);
4066 if (pipe_err < 0)
4067 {
4068 /* didn't get them all made - clean up and bail out */
4069 while (i-- > 0)
4070 {
4071 close(p_fd[i].wr);
4072 close(p_fd[i].rd);
4073 }
4074 errno = EPIPE;
4075 return posix_error();
4076 }
4077
4078 /* change the actual standard IO streams over temporarily,
4079 * making the retained pipe ends non-inheritable
4080 */
4081 pipe_err = 0;
4082
4083 /* - stdin */
4084 if (dup2(p_fd[0].rd, 0) == 0)
4085 {
4086 close(p_fd[0].rd);
4087 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4088 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4089 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4090 {
4091 close(p_fd[0].wr);
4092 pipe_err = -1;
4093 }
4094 }
4095 else
4096 {
4097 pipe_err = -1;
4098 }
4099
4100 /* - stdout */
4101 if (pipe_err == 0)
4102 {
4103 if (dup2(p_fd[1].wr, 1) == 1)
4104 {
4105 close(p_fd[1].wr);
4106 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4107 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4108 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4109 {
4110 close(p_fd[1].rd);
4111 pipe_err = -1;
4112 }
4113 }
4114 else
4115 {
4116 pipe_err = -1;
4117 }
4118 }
4119
4120 /* - stderr, as required */
4121 if (pipe_err == 0)
4122 switch (n)
4123 {
4124 case POPEN_3:
4125 {
4126 if (dup2(p_fd[2].wr, 2) == 2)
4127 {
4128 close(p_fd[2].wr);
4129 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4130 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4131 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4132 {
4133 close(p_fd[2].rd);
4134 pipe_err = -1;
4135 }
4136 }
4137 else
4138 {
4139 pipe_err = -1;
4140 }
4141 break;
4142 }
4143
4144 case POPEN_4:
4145 {
4146 if (dup2(1, 2) != 2)
4147 {
4148 pipe_err = -1;
4149 }
4150 break;
4151 }
4152 }
4153
4154 /* spawn the child process */
4155 if (pipe_err == 0)
4156 {
4157 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4158 if (pipe_pid == -1)
4159 {
4160 pipe_err = -1;
4161 }
4162 else
4163 {
4164 /* save the PID into the FILE structure
4165 * NOTE: this implementation doesn't actually
4166 * take advantage of this, but do it for
4167 * completeness - AIM Apr01
4168 */
4169 for (i = 0; i < file_count; i++)
4170 p_s[i]->_pid = pipe_pid;
4171 }
4172 }
4173
4174 /* reset standard IO to normal */
4175 for (i = 0; i < 3; i++)
4176 {
4177 dup2(stdio[i].handle, i);
4178 fcntl(i, F_SETFD, stdio[i].flags);
4179 close(stdio[i].handle);
4180 }
4181
4182 /* if any remnant problems, clean up and bail out */
4183 if (pipe_err < 0)
4184 {
4185 for (i = 0; i < 3; i++)
4186 {
4187 close(p_fd[i].rd);
4188 close(p_fd[i].wr);
4189 }
4190 errno = EPIPE;
4191 return posix_error_with_filename(cmdstring);
4192 }
4193
4194 /* build tuple of file objects to return */
4195 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4196 PyFile_SetBufSize(p_f[0], bufsize);
4197 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4198 PyFile_SetBufSize(p_f[1], bufsize);
4199 if (n == POPEN_3)
4200 {
4201 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4202 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004203 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004204 }
4205 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004206 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004207
4208 /*
4209 * Insert the files we've created into the process dictionary
4210 * all referencing the list with the process handle and the
4211 * initial number of files (see description below in _PyPclose).
4212 * Since if _PyPclose later tried to wait on a process when all
4213 * handles weren't closed, it could create a deadlock with the
4214 * child, we spend some energy here to try to ensure that we
4215 * either insert all file handles into the dictionary or none
4216 * at all. It's a little clumsy with the various popen modes
4217 * and variable number of files involved.
4218 */
4219 if (!_PyPopenProcs)
4220 {
4221 _PyPopenProcs = PyDict_New();
4222 }
4223
4224 if (_PyPopenProcs)
4225 {
4226 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4227 int ins_rc[3];
4228
4229 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4230 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4231
4232 procObj = PyList_New(2);
4233 pidObj = PyInt_FromLong((long) pipe_pid);
4234 intObj = PyInt_FromLong((long) file_count);
4235
4236 if (procObj && pidObj && intObj)
4237 {
4238 PyList_SetItem(procObj, 0, pidObj);
4239 PyList_SetItem(procObj, 1, intObj);
4240
4241 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4242 if (fileObj[0])
4243 {
4244 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4245 fileObj[0],
4246 procObj);
4247 }
4248 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4249 if (fileObj[1])
4250 {
4251 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4252 fileObj[1],
4253 procObj);
4254 }
4255 if (file_count >= 3)
4256 {
4257 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4258 if (fileObj[2])
4259 {
4260 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4261 fileObj[2],
4262 procObj);
4263 }
4264 }
4265
4266 if (ins_rc[0] < 0 || !fileObj[0] ||
4267 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4268 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4269 {
4270 /* Something failed - remove any dictionary
4271 * entries that did make it.
4272 */
4273 if (!ins_rc[0] && fileObj[0])
4274 {
4275 PyDict_DelItem(_PyPopenProcs,
4276 fileObj[0]);
4277 }
4278 if (!ins_rc[1] && fileObj[1])
4279 {
4280 PyDict_DelItem(_PyPopenProcs,
4281 fileObj[1]);
4282 }
4283 if (!ins_rc[2] && fileObj[2])
4284 {
4285 PyDict_DelItem(_PyPopenProcs,
4286 fileObj[2]);
4287 }
4288 }
4289 }
Tim Peters11b23062003-04-23 02:39:17 +00004290
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004291 /*
4292 * Clean up our localized references for the dictionary keys
4293 * and value since PyDict_SetItem will Py_INCREF any copies
4294 * that got placed in the dictionary.
4295 */
4296 Py_XDECREF(procObj);
4297 Py_XDECREF(fileObj[0]);
4298 Py_XDECREF(fileObj[1]);
4299 Py_XDECREF(fileObj[2]);
4300 }
4301
4302 /* Child is launched. */
4303 return f;
4304}
4305
4306/*
4307 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4308 * exit code for the child process and return as a result of the close.
4309 *
4310 * This function uses the _PyPopenProcs dictionary in order to map the
4311 * input file pointer to information about the process that was
4312 * originally created by the popen* call that created the file pointer.
4313 * The dictionary uses the file pointer as a key (with one entry
4314 * inserted for each file returned by the original popen* call) and a
4315 * single list object as the value for all files from a single call.
4316 * The list object contains the Win32 process handle at [0], and a file
4317 * count at [1], which is initialized to the total number of file
4318 * handles using that list.
4319 *
4320 * This function closes whichever handle it is passed, and decrements
4321 * the file count in the dictionary for the process handle pointed to
4322 * by this file. On the last close (when the file count reaches zero),
4323 * this function will wait for the child process and then return its
4324 * exit code as the result of the close() operation. This permits the
4325 * files to be closed in any order - it is always the close() of the
4326 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004327 *
4328 * NOTE: This function is currently called with the GIL released.
4329 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004330 */
4331
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004332static int _PyPclose(FILE *file)
4333{
4334 int result;
4335 int exit_code;
4336 int pipe_pid;
4337 PyObject *procObj, *pidObj, *intObj, *fileObj;
4338 int file_count;
4339#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004340 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004341#endif
4342
4343 /* Close the file handle first, to ensure it can't block the
4344 * child from exiting if it's the last handle.
4345 */
4346 result = fclose(file);
4347
4348#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004349 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004350#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004351 if (_PyPopenProcs)
4352 {
4353 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4354 (procObj = PyDict_GetItem(_PyPopenProcs,
4355 fileObj)) != NULL &&
4356 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4357 (intObj = PyList_GetItem(procObj,1)) != NULL)
4358 {
4359 pipe_pid = (int) PyInt_AsLong(pidObj);
4360 file_count = (int) PyInt_AsLong(intObj);
4361
4362 if (file_count > 1)
4363 {
4364 /* Still other files referencing process */
4365 file_count--;
4366 PyList_SetItem(procObj,1,
4367 PyInt_FromLong((long) file_count));
4368 }
4369 else
4370 {
4371 /* Last file for this process */
4372 if (result != EOF &&
4373 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4374 {
4375 /* extract exit status */
4376 if (WIFEXITED(exit_code))
4377 {
4378 result = WEXITSTATUS(exit_code);
4379 }
4380 else
4381 {
4382 errno = EPIPE;
4383 result = -1;
4384 }
4385 }
4386 else
4387 {
4388 /* Indicate failure - this will cause the file object
4389 * to raise an I/O error and translate the last
4390 * error code from errno. We do have a problem with
4391 * last errors that overlap the normal errno table,
4392 * but that's a consistent problem with the file object.
4393 */
4394 result = -1;
4395 }
4396 }
4397
4398 /* Remove this file pointer from dictionary */
4399 PyDict_DelItem(_PyPopenProcs, fileObj);
4400
4401 if (PyDict_Size(_PyPopenProcs) == 0)
4402 {
4403 Py_DECREF(_PyPopenProcs);
4404 _PyPopenProcs = NULL;
4405 }
4406
4407 } /* if object retrieval ok */
4408
4409 Py_XDECREF(fileObj);
4410 } /* if _PyPopenProcs */
4411
4412#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004413 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004414#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004415 return result;
4416}
4417
4418#endif /* PYCC_??? */
4419
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004420#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004421
4422/*
4423 * Portable 'popen' replacement for Win32.
4424 *
4425 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4426 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004427 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004428 */
4429
4430#include <malloc.h>
4431#include <io.h>
4432#include <fcntl.h>
4433
4434/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4435#define POPEN_1 1
4436#define POPEN_2 2
4437#define POPEN_3 3
4438#define POPEN_4 4
4439
4440static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004441static int _PyPclose(FILE *file);
4442
4443/*
4444 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004445 * for use when retrieving the process exit code. See _PyPclose() below
4446 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004447 */
4448static PyObject *_PyPopenProcs = NULL;
4449
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004450
4451/* popen that works from a GUI.
4452 *
4453 * The result of this function is a pipe (file) connected to the
4454 * processes stdin or stdout, depending on the requested mode.
4455 */
4456
4457static PyObject *
4458posix_popen(PyObject *self, PyObject *args)
4459{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004460 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004461 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004462
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004463 char *cmdstring;
4464 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004465 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004466 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004467 return NULL;
4468
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004469 if (*mode == 'r')
4470 tm = _O_RDONLY;
4471 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004472 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004473 return NULL;
4474 } else
4475 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004476
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004477 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004478 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004479 return NULL;
4480 }
4481
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004482 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004483 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004484 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004485 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004486 else
4487 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4488
4489 return f;
4490}
4491
4492/* Variation on win32pipe.popen
4493 *
4494 * The result of this function is a pipe (file) connected to the
4495 * process's stdin, and a pipe connected to the process's stdout.
4496 */
4497
4498static PyObject *
4499win32_popen2(PyObject *self, PyObject *args)
4500{
4501 PyObject *f;
4502 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004503
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004504 char *cmdstring;
4505 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004506 int bufsize = -1;
4507 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004508 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004509
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004510 if (*mode == 't')
4511 tm = _O_TEXT;
4512 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004513 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004514 return NULL;
4515 } else
4516 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004517
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004518 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004519 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004520 return NULL;
4521 }
4522
4523 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004524
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004525 return f;
4526}
4527
4528/*
4529 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004530 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004531 * The result of this function is 3 pipes - the process's stdin,
4532 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004533 */
4534
4535static PyObject *
4536win32_popen3(PyObject *self, PyObject *args)
4537{
4538 PyObject *f;
4539 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004540
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004541 char *cmdstring;
4542 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004543 int bufsize = -1;
4544 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004545 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004546
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004547 if (*mode == 't')
4548 tm = _O_TEXT;
4549 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004550 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004551 return NULL;
4552 } else
4553 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004554
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004555 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004556 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004557 return NULL;
4558 }
4559
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004560 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004561
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004562 return f;
4563}
4564
4565/*
4566 * Variation on win32pipe.popen
4567 *
Tim Peters5aa91602002-01-30 05:46:57 +00004568 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004569 * and stdout+stderr combined as a single pipe.
4570 */
4571
4572static PyObject *
4573win32_popen4(PyObject *self, PyObject *args)
4574{
4575 PyObject *f;
4576 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004577
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004578 char *cmdstring;
4579 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004580 int bufsize = -1;
4581 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004582 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004583
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004584 if (*mode == 't')
4585 tm = _O_TEXT;
4586 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004587 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004588 return NULL;
4589 } else
4590 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004591
4592 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004593 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004594 return NULL;
4595 }
4596
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004597 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004598
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004599 return f;
4600}
4601
Mark Hammond08501372001-01-31 07:30:29 +00004602static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004603_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004604 HANDLE hStdin,
4605 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004606 HANDLE hStderr,
4607 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004608{
4609 PROCESS_INFORMATION piProcInfo;
4610 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004611 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004612 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004613 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004614 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004615 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004616
4617 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004618 char *comshell;
4619
Tim Peters92e4dd82002-10-05 01:47:34 +00004620 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004621 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004622 /* x < i, so x fits into an integer */
4623 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004624
4625 /* Explicitly check if we are using COMMAND.COM. If we are
4626 * then use the w9xpopen hack.
4627 */
4628 comshell = s1 + x;
4629 while (comshell >= s1 && *comshell != '\\')
4630 --comshell;
4631 ++comshell;
4632
4633 if (GetVersion() < 0x80000000 &&
4634 _stricmp(comshell, "command.com") != 0) {
4635 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004636 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004637 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004638 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004639 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004640 }
4641 else {
4642 /*
Tim Peters402d5982001-08-27 06:37:48 +00004643 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4644 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004645 */
Mark Hammond08501372001-01-31 07:30:29 +00004646 char modulepath[_MAX_PATH];
4647 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004648 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Thomas Wouters477c8d52006-05-27 19:21:47 +00004649 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004650 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004651 x = i+1;
4652 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004653 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004654 strncat(modulepath,
4655 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004656 (sizeof(modulepath)/sizeof(modulepath[0]))
4657 -strlen(modulepath));
4658 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004659 /* Eeek - file-not-found - possibly an embedding
4660 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004661 */
Tim Peters5aa91602002-01-30 05:46:57 +00004662 strncpy(modulepath,
4663 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004664 sizeof(modulepath)/sizeof(modulepath[0]));
4665 if (modulepath[strlen(modulepath)-1] != '\\')
4666 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004667 strncat(modulepath,
4668 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004669 (sizeof(modulepath)/sizeof(modulepath[0]))
4670 -strlen(modulepath));
4671 /* No where else to look - raise an easily identifiable
4672 error, rather than leaving Windows to report
4673 "file not found" - as the user is probably blissfully
4674 unaware this shim EXE is used, and it will confuse them.
4675 (well, it confused me for a while ;-)
4676 */
4677 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004678 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004679 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004680 "for popen to work with your shell "
4681 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004682 szConsoleSpawn);
4683 return FALSE;
4684 }
4685 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004686 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004687 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004688 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004689
Tim Peters92e4dd82002-10-05 01:47:34 +00004690 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004691 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004692 /* To maintain correct argument passing semantics,
4693 we pass the command-line as it stands, and allow
4694 quoting to be applied. w9xpopen.exe will then
4695 use its argv vector, and re-quote the necessary
4696 args for the ultimate child process.
4697 */
Tim Peters75cdad52001-11-28 22:07:30 +00004698 PyOS_snprintf(
4699 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004700 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004701 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004702 s1,
4703 s3,
4704 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004705 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004706 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004707 dialog:
4708 "Your program accessed mem currently in use at xxx"
4709 and a hopeful warning about the stability of your
4710 system.
4711 Cost is Ctrl+C wont kill children, but anyone
4712 who cares can have a go!
4713 */
4714 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004715 }
4716 }
4717
4718 /* Could be an else here to try cmd.exe / command.com in the path
4719 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004720 else {
Tim Peters402d5982001-08-27 06:37:48 +00004721 PyErr_SetString(PyExc_RuntimeError,
4722 "Cannot locate a COMSPEC environment variable to "
4723 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004724 return FALSE;
4725 }
Tim Peters5aa91602002-01-30 05:46:57 +00004726
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004727 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4728 siStartInfo.cb = sizeof(STARTUPINFO);
4729 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4730 siStartInfo.hStdInput = hStdin;
4731 siStartInfo.hStdOutput = hStdout;
4732 siStartInfo.hStdError = hStderr;
4733 siStartInfo.wShowWindow = SW_HIDE;
4734
4735 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004736 s2,
4737 NULL,
4738 NULL,
4739 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004740 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004741 NULL,
4742 NULL,
4743 &siStartInfo,
4744 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004745 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004746 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004747
Mark Hammondb37a3732000-08-14 04:47:33 +00004748 /* Return process handle */
4749 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004750 return TRUE;
4751 }
Tim Peters402d5982001-08-27 06:37:48 +00004752 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004753 return FALSE;
4754}
4755
4756/* The following code is based off of KB: Q190351 */
4757
4758static PyObject *
4759_PyPopen(char *cmdstring, int mode, int n)
4760{
4761 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4762 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004763 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004764
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004765 SECURITY_ATTRIBUTES saAttr;
4766 BOOL fSuccess;
4767 int fd1, fd2, fd3;
4768 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004769 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004770 PyObject *f;
4771
4772 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4773 saAttr.bInheritHandle = TRUE;
4774 saAttr.lpSecurityDescriptor = NULL;
4775
4776 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4777 return win32_error("CreatePipe", NULL);
4778
4779 /* Create new output read handle and the input write handle. Set
4780 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004781 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004782 * being created. */
4783 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004784 GetCurrentProcess(), &hChildStdinWrDup, 0,
4785 FALSE,
4786 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004787 if (!fSuccess)
4788 return win32_error("DuplicateHandle", NULL);
4789
4790 /* Close the inheritable version of ChildStdin
4791 that we're using. */
4792 CloseHandle(hChildStdinWr);
4793
4794 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4795 return win32_error("CreatePipe", NULL);
4796
4797 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004798 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4799 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004800 if (!fSuccess)
4801 return win32_error("DuplicateHandle", NULL);
4802
4803 /* Close the inheritable version of ChildStdout
4804 that we're using. */
4805 CloseHandle(hChildStdoutRd);
4806
4807 if (n != POPEN_4) {
4808 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4809 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004810 fSuccess = DuplicateHandle(GetCurrentProcess(),
4811 hChildStderrRd,
4812 GetCurrentProcess(),
4813 &hChildStderrRdDup, 0,
4814 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004815 if (!fSuccess)
4816 return win32_error("DuplicateHandle", NULL);
4817 /* Close the inheritable version of ChildStdErr that we're using. */
4818 CloseHandle(hChildStderrRd);
4819 }
Tim Peters5aa91602002-01-30 05:46:57 +00004820
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004821 switch (n) {
4822 case POPEN_1:
4823 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4824 case _O_WRONLY | _O_TEXT:
4825 /* Case for writing to child Stdin in text mode. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00004826 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004827 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004828 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004829 PyFile_SetBufSize(f, 0);
4830 /* We don't care about these pipes anymore, so close them. */
4831 CloseHandle(hChildStdoutRdDup);
4832 CloseHandle(hChildStderrRdDup);
4833 break;
4834
4835 case _O_RDONLY | _O_TEXT:
4836 /* Case for reading from child Stdout in text mode. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00004837 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004838 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004839 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004840 PyFile_SetBufSize(f, 0);
4841 /* We don't care about these pipes anymore, so close them. */
4842 CloseHandle(hChildStdinWrDup);
4843 CloseHandle(hChildStderrRdDup);
4844 break;
4845
4846 case _O_RDONLY | _O_BINARY:
4847 /* Case for readinig from child Stdout in binary mode. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00004848 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004849 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004850 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004851 PyFile_SetBufSize(f, 0);
4852 /* We don't care about these pipes anymore, so close them. */
4853 CloseHandle(hChildStdinWrDup);
4854 CloseHandle(hChildStderrRdDup);
4855 break;
4856
4857 case _O_WRONLY | _O_BINARY:
4858 /* Case for writing to child Stdin in binary mode. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00004859 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004860 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004861 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004862 PyFile_SetBufSize(f, 0);
4863 /* We don't care about these pipes anymore, so close them. */
4864 CloseHandle(hChildStdoutRdDup);
4865 CloseHandle(hChildStderrRdDup);
4866 break;
4867 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004868 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004869 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004870
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004871 case POPEN_2:
4872 case POPEN_4:
4873 {
4874 char *m1, *m2;
4875 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004876
Tim Peters7dca21e2002-08-19 00:42:29 +00004877 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004878 m1 = "r";
4879 m2 = "w";
4880 } else {
4881 m1 = "rb";
4882 m2 = "wb";
4883 }
4884
Thomas Wouters477c8d52006-05-27 19:21:47 +00004885 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004886 f1 = _fdopen(fd1, m2);
Thomas Wouters477c8d52006-05-27 19:21:47 +00004887 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004888 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004889 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004890 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004891 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004892 PyFile_SetBufSize(p2, 0);
4893
4894 if (n != 4)
4895 CloseHandle(hChildStderrRdDup);
4896
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004897 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004898 Py_XDECREF(p1);
4899 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004900 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004901 break;
4902 }
Tim Peters5aa91602002-01-30 05:46:57 +00004903
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004904 case POPEN_3:
4905 {
4906 char *m1, *m2;
4907 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004908
Tim Peters7dca21e2002-08-19 00:42:29 +00004909 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004910 m1 = "r";
4911 m2 = "w";
4912 } else {
4913 m1 = "rb";
4914 m2 = "wb";
4915 }
4916
Thomas Wouters477c8d52006-05-27 19:21:47 +00004917 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004918 f1 = _fdopen(fd1, m2);
Thomas Wouters477c8d52006-05-27 19:21:47 +00004919 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004920 f2 = _fdopen(fd2, m1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00004921 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004922 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004923 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004924 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4925 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004926 PyFile_SetBufSize(p1, 0);
4927 PyFile_SetBufSize(p2, 0);
4928 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004929 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004930 Py_XDECREF(p1);
4931 Py_XDECREF(p2);
4932 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004933 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004934 break;
4935 }
4936 }
4937
4938 if (n == POPEN_4) {
4939 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004940 hChildStdinRd,
4941 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004942 hChildStdoutWr,
4943 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004944 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004945 }
4946 else {
4947 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004948 hChildStdinRd,
4949 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004950 hChildStderrWr,
4951 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004952 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004953 }
4954
Mark Hammondb37a3732000-08-14 04:47:33 +00004955 /*
4956 * Insert the files we've created into the process dictionary
4957 * all referencing the list with the process handle and the
4958 * initial number of files (see description below in _PyPclose).
4959 * Since if _PyPclose later tried to wait on a process when all
4960 * handles weren't closed, it could create a deadlock with the
4961 * child, we spend some energy here to try to ensure that we
4962 * either insert all file handles into the dictionary or none
4963 * at all. It's a little clumsy with the various popen modes
4964 * and variable number of files involved.
4965 */
4966 if (!_PyPopenProcs) {
4967 _PyPopenProcs = PyDict_New();
4968 }
4969
4970 if (_PyPopenProcs) {
4971 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4972 int ins_rc[3];
4973
4974 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4975 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4976
4977 procObj = PyList_New(2);
4978 hProcessObj = PyLong_FromVoidPtr(hProcess);
4979 intObj = PyInt_FromLong(file_count);
4980
4981 if (procObj && hProcessObj && intObj) {
4982 PyList_SetItem(procObj,0,hProcessObj);
4983 PyList_SetItem(procObj,1,intObj);
4984
4985 fileObj[0] = PyLong_FromVoidPtr(f1);
4986 if (fileObj[0]) {
4987 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4988 fileObj[0],
4989 procObj);
4990 }
4991 if (file_count >= 2) {
4992 fileObj[1] = PyLong_FromVoidPtr(f2);
4993 if (fileObj[1]) {
4994 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4995 fileObj[1],
4996 procObj);
4997 }
4998 }
4999 if (file_count >= 3) {
5000 fileObj[2] = PyLong_FromVoidPtr(f3);
5001 if (fileObj[2]) {
5002 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5003 fileObj[2],
5004 procObj);
5005 }
5006 }
5007
5008 if (ins_rc[0] < 0 || !fileObj[0] ||
5009 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5010 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5011 /* Something failed - remove any dictionary
5012 * entries that did make it.
5013 */
5014 if (!ins_rc[0] && fileObj[0]) {
5015 PyDict_DelItem(_PyPopenProcs,
5016 fileObj[0]);
5017 }
5018 if (!ins_rc[1] && fileObj[1]) {
5019 PyDict_DelItem(_PyPopenProcs,
5020 fileObj[1]);
5021 }
5022 if (!ins_rc[2] && fileObj[2]) {
5023 PyDict_DelItem(_PyPopenProcs,
5024 fileObj[2]);
5025 }
5026 }
5027 }
Tim Peters5aa91602002-01-30 05:46:57 +00005028
Mark Hammondb37a3732000-08-14 04:47:33 +00005029 /*
5030 * Clean up our localized references for the dictionary keys
5031 * and value since PyDict_SetItem will Py_INCREF any copies
5032 * that got placed in the dictionary.
5033 */
5034 Py_XDECREF(procObj);
5035 Py_XDECREF(fileObj[0]);
5036 Py_XDECREF(fileObj[1]);
5037 Py_XDECREF(fileObj[2]);
5038 }
5039
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005040 /* Child is launched. Close the parents copy of those pipe
5041 * handles that only the child should have open. You need to
5042 * make sure that no handles to the write end of the output pipe
5043 * are maintained in this process or else the pipe will not close
5044 * when the child process exits and the ReadFile will hang. */
5045
5046 if (!CloseHandle(hChildStdinRd))
5047 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005048
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005049 if (!CloseHandle(hChildStdoutWr))
5050 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005051
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005052 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5053 return win32_error("CloseHandle", NULL);
5054
5055 return f;
5056}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005057
5058/*
5059 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5060 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005061 *
5062 * This function uses the _PyPopenProcs dictionary in order to map the
5063 * input file pointer to information about the process that was
5064 * originally created by the popen* call that created the file pointer.
5065 * The dictionary uses the file pointer as a key (with one entry
5066 * inserted for each file returned by the original popen* call) and a
5067 * single list object as the value for all files from a single call.
5068 * The list object contains the Win32 process handle at [0], and a file
5069 * count at [1], which is initialized to the total number of file
5070 * handles using that list.
5071 *
5072 * This function closes whichever handle it is passed, and decrements
5073 * the file count in the dictionary for the process handle pointed to
5074 * by this file. On the last close (when the file count reaches zero),
5075 * this function will wait for the child process and then return its
5076 * exit code as the result of the close() operation. This permits the
5077 * files to be closed in any order - it is always the close() of the
5078 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005079 *
5080 * NOTE: This function is currently called with the GIL released.
5081 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005082 */
Tim Peters736aa322000-09-01 06:51:24 +00005083
Fredrik Lundh56055a42000-07-23 19:47:12 +00005084static int _PyPclose(FILE *file)
5085{
Fredrik Lundh20318932000-07-26 17:29:12 +00005086 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005087 DWORD exit_code;
5088 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00005089 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5090 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005091#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005092 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005093#endif
5094
Fredrik Lundh20318932000-07-26 17:29:12 +00005095 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00005096 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00005097 */
5098 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005099#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005100 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005101#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005102 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005103 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5104 (procObj = PyDict_GetItem(_PyPopenProcs,
5105 fileObj)) != NULL &&
5106 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5107 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5108
5109 hProcess = PyLong_AsVoidPtr(hProcessObj);
5110 file_count = PyInt_AsLong(intObj);
5111
5112 if (file_count > 1) {
5113 /* Still other files referencing process */
5114 file_count--;
5115 PyList_SetItem(procObj,1,
5116 PyInt_FromLong(file_count));
5117 } else {
5118 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00005119 if (result != EOF &&
5120 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5121 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00005122 /* Possible truncation here in 16-bit environments, but
5123 * real exit codes are just the lower byte in any event.
5124 */
5125 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005126 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00005127 /* Indicate failure - this will cause the file object
5128 * to raise an I/O error and translate the last Win32
5129 * error code from errno. We do have a problem with
5130 * last errors that overlap the normal errno table,
5131 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005132 */
Fredrik Lundh20318932000-07-26 17:29:12 +00005133 if (result != EOF) {
5134 /* If the error wasn't from the fclose(), then
5135 * set errno for the file object error handling.
5136 */
5137 errno = GetLastError();
5138 }
5139 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005140 }
5141
5142 /* Free up the native handle at this point */
5143 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00005144 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005145
Mark Hammondb37a3732000-08-14 04:47:33 +00005146 /* Remove this file pointer from dictionary */
5147 PyDict_DelItem(_PyPopenProcs, fileObj);
5148
5149 if (PyDict_Size(_PyPopenProcs) == 0) {
5150 Py_DECREF(_PyPopenProcs);
5151 _PyPopenProcs = NULL;
5152 }
5153
5154 } /* if object retrieval ok */
5155
5156 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005157 } /* if _PyPopenProcs */
5158
Tim Peters736aa322000-09-01 06:51:24 +00005159#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005160 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005161#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005162 return result;
5163}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005164
5165#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005166static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005167posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005168{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005169 char *name;
5170 char *mode = "r";
5171 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00005172 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005173 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005174 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00005175 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00005176 /* Strip mode of binary or text modifiers */
5177 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5178 mode = "r";
5179 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5180 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00005181 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005182 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005183 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00005184 if (fp == NULL)
5185 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005186 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005187 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005188 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005189 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005190}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005191
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005192#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005193#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005194
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005195
Guido van Rossumb6775db1994-08-01 11:34:53 +00005196#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005197PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005198"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005199Set the current process's user id.");
5200
Barry Warsaw53699e91996-12-10 23:23:01 +00005201static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005202posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005203{
5204 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005205 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005206 return NULL;
5207 if (setuid(uid) < 0)
5208 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005209 Py_INCREF(Py_None);
5210 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005211}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005212#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005213
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005214
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005215#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005216PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005217"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005218Set the current process's effective user id.");
5219
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005220static PyObject *
5221posix_seteuid (PyObject *self, PyObject *args)
5222{
5223 int euid;
5224 if (!PyArg_ParseTuple(args, "i", &euid)) {
5225 return NULL;
5226 } else if (seteuid(euid) < 0) {
5227 return posix_error();
5228 } else {
5229 Py_INCREF(Py_None);
5230 return Py_None;
5231 }
5232}
5233#endif /* HAVE_SETEUID */
5234
5235#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005236PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005237"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005238Set the current process's effective group id.");
5239
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005240static PyObject *
5241posix_setegid (PyObject *self, PyObject *args)
5242{
5243 int egid;
5244 if (!PyArg_ParseTuple(args, "i", &egid)) {
5245 return NULL;
5246 } else if (setegid(egid) < 0) {
5247 return posix_error();
5248 } else {
5249 Py_INCREF(Py_None);
5250 return Py_None;
5251 }
5252}
5253#endif /* HAVE_SETEGID */
5254
5255#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005256PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005257"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005258Set the current process's real and effective user ids.");
5259
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005260static PyObject *
5261posix_setreuid (PyObject *self, PyObject *args)
5262{
5263 int ruid, euid;
5264 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
5265 return NULL;
5266 } else if (setreuid(ruid, euid) < 0) {
5267 return posix_error();
5268 } else {
5269 Py_INCREF(Py_None);
5270 return Py_None;
5271 }
5272}
5273#endif /* HAVE_SETREUID */
5274
5275#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005276PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005277"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005278Set the current process's real and effective group ids.");
5279
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005280static PyObject *
5281posix_setregid (PyObject *self, PyObject *args)
5282{
5283 int rgid, egid;
5284 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
5285 return NULL;
5286 } else if (setregid(rgid, egid) < 0) {
5287 return posix_error();
5288 } else {
5289 Py_INCREF(Py_None);
5290 return Py_None;
5291 }
5292}
5293#endif /* HAVE_SETREGID */
5294
Guido van Rossumb6775db1994-08-01 11:34:53 +00005295#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005296PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005297"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005298Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005299
Barry Warsaw53699e91996-12-10 23:23:01 +00005300static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005301posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005302{
5303 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005304 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005305 return NULL;
5306 if (setgid(gid) < 0)
5307 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005308 Py_INCREF(Py_None);
5309 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005310}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005311#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005312
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005313#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005314PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005315"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005316Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005317
5318static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00005319posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005320{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005321 int i, len;
5322 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005323
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005324 if (!PySequence_Check(groups)) {
5325 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5326 return NULL;
5327 }
5328 len = PySequence_Size(groups);
5329 if (len > MAX_GROUPS) {
5330 PyErr_SetString(PyExc_ValueError, "too many groups");
5331 return NULL;
5332 }
5333 for(i = 0; i < len; i++) {
5334 PyObject *elem;
5335 elem = PySequence_GetItem(groups, i);
5336 if (!elem)
5337 return NULL;
5338 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005339 if (!PyLong_Check(elem)) {
5340 PyErr_SetString(PyExc_TypeError,
5341 "groups must be integers");
5342 Py_DECREF(elem);
5343 return NULL;
5344 } else {
5345 unsigned long x = PyLong_AsUnsignedLong(elem);
5346 if (PyErr_Occurred()) {
5347 PyErr_SetString(PyExc_TypeError,
5348 "group id too big");
5349 Py_DECREF(elem);
5350 return NULL;
5351 }
5352 grouplist[i] = x;
5353 /* read back the value to see if it fitted in gid_t */
5354 if (grouplist[i] != x) {
5355 PyErr_SetString(PyExc_TypeError,
5356 "group id too big");
5357 Py_DECREF(elem);
5358 return NULL;
5359 }
5360 }
5361 } else {
5362 long x = PyInt_AsLong(elem);
5363 grouplist[i] = x;
5364 if (grouplist[i] != x) {
5365 PyErr_SetString(PyExc_TypeError,
5366 "group id too big");
5367 Py_DECREF(elem);
5368 return NULL;
5369 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005370 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005371 Py_DECREF(elem);
5372 }
5373
5374 if (setgroups(len, grouplist) < 0)
5375 return posix_error();
5376 Py_INCREF(Py_None);
5377 return Py_None;
5378}
5379#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005380
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005381#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
5382static PyObject *
5383wait_helper(int pid, int status, struct rusage *ru)
5384{
5385 PyObject *result;
5386 static PyObject *struct_rusage;
5387
5388 if (pid == -1)
5389 return posix_error();
5390
5391 if (struct_rusage == NULL) {
5392 PyObject *m = PyImport_ImportModule("resource");
5393 if (m == NULL)
5394 return NULL;
5395 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5396 Py_DECREF(m);
5397 if (struct_rusage == NULL)
5398 return NULL;
5399 }
5400
5401 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5402 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5403 if (!result)
5404 return NULL;
5405
5406#ifndef doubletime
5407#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5408#endif
5409
5410 PyStructSequence_SET_ITEM(result, 0,
5411 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5412 PyStructSequence_SET_ITEM(result, 1,
5413 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5414#define SET_INT(result, index, value)\
5415 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5416 SET_INT(result, 2, ru->ru_maxrss);
5417 SET_INT(result, 3, ru->ru_ixrss);
5418 SET_INT(result, 4, ru->ru_idrss);
5419 SET_INT(result, 5, ru->ru_isrss);
5420 SET_INT(result, 6, ru->ru_minflt);
5421 SET_INT(result, 7, ru->ru_majflt);
5422 SET_INT(result, 8, ru->ru_nswap);
5423 SET_INT(result, 9, ru->ru_inblock);
5424 SET_INT(result, 10, ru->ru_oublock);
5425 SET_INT(result, 11, ru->ru_msgsnd);
5426 SET_INT(result, 12, ru->ru_msgrcv);
5427 SET_INT(result, 13, ru->ru_nsignals);
5428 SET_INT(result, 14, ru->ru_nvcsw);
5429 SET_INT(result, 15, ru->ru_nivcsw);
5430#undef SET_INT
5431
5432 if (PyErr_Occurred()) {
5433 Py_DECREF(result);
5434 return NULL;
5435 }
5436
5437 return Py_BuildValue("iiN", pid, status, result);
5438}
5439#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
5440
5441#ifdef HAVE_WAIT3
5442PyDoc_STRVAR(posix_wait3__doc__,
5443"wait3(options) -> (pid, status, rusage)\n\n\
5444Wait for completion of a child process.");
5445
5446static PyObject *
5447posix_wait3(PyObject *self, PyObject *args)
5448{
5449 int pid, options;
5450 struct rusage ru;
5451 WAIT_TYPE status;
5452 WAIT_STATUS_INT(status) = 0;
5453
5454 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5455 return NULL;
5456
5457 Py_BEGIN_ALLOW_THREADS
5458 pid = wait3(&status, options, &ru);
5459 Py_END_ALLOW_THREADS
5460
5461 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
5462}
5463#endif /* HAVE_WAIT3 */
5464
5465#ifdef HAVE_WAIT4
5466PyDoc_STRVAR(posix_wait4__doc__,
5467"wait4(pid, options) -> (pid, status, rusage)\n\n\
5468Wait for completion of a given child process.");
5469
5470static PyObject *
5471posix_wait4(PyObject *self, PyObject *args)
5472{
5473 int pid, options;
5474 struct rusage ru;
5475 WAIT_TYPE status;
5476 WAIT_STATUS_INT(status) = 0;
5477
5478 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5479 return NULL;
5480
5481 Py_BEGIN_ALLOW_THREADS
5482 pid = wait4(pid, &status, options, &ru);
5483 Py_END_ALLOW_THREADS
5484
5485 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
5486}
5487#endif /* HAVE_WAIT4 */
5488
Guido van Rossumb6775db1994-08-01 11:34:53 +00005489#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005490PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005491"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005492Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005493
Barry Warsaw53699e91996-12-10 23:23:01 +00005494static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005495posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005496{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005497 int pid, options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005498 WAIT_TYPE status;
5499 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005500
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005501 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005502 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005503 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005504 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005505 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005506 if (pid == -1)
5507 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005508
5509 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005510}
5511
Tim Petersab034fa2002-02-01 11:27:43 +00005512#elif defined(HAVE_CWAIT)
5513
5514/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005515PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005516"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005517"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005518
5519static PyObject *
5520posix_waitpid(PyObject *self, PyObject *args)
5521{
Thomas Wouters477c8d52006-05-27 19:21:47 +00005522 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005523 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005524
5525 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5526 return NULL;
5527 Py_BEGIN_ALLOW_THREADS
5528 pid = _cwait(&status, pid, options);
5529 Py_END_ALLOW_THREADS
5530 if (pid == -1)
5531 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005532
5533 /* shift the status left a byte so this is more like the POSIX waitpid */
5534 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005535}
5536#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005537
Guido van Rossumad0ee831995-03-01 10:34:45 +00005538#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005539PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005540"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005541Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005542
Barry Warsaw53699e91996-12-10 23:23:01 +00005543static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005544posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005545{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005546 int pid;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005547 WAIT_TYPE status;
5548 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005549
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005550 Py_BEGIN_ALLOW_THREADS
5551 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005552 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005553 if (pid == -1)
5554 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005555
5556 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005557}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005558#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005559
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005560
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005561PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005562"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005563Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005564
Barry Warsaw53699e91996-12-10 23:23:01 +00005565static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005566posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005567{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005568#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005569 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005570#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005571#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005572 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005573#else
5574 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5575#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005576#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005577}
5578
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005579
Guido van Rossumb6775db1994-08-01 11:34:53 +00005580#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005581PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005582"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005583Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005584
Barry Warsaw53699e91996-12-10 23:23:01 +00005585static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005586posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005587{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005588 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005589 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005590 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005591 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005592 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005593 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005594 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005595 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005596 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005597 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00005598 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005599}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005600#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005601
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005602
Guido van Rossumb6775db1994-08-01 11:34:53 +00005603#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005604PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005605"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005606Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005607
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005608static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005609posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005610{
Thomas Wouters477c8d52006-05-27 19:21:47 +00005611 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005612}
5613#endif /* HAVE_SYMLINK */
5614
5615
5616#ifdef HAVE_TIMES
5617#ifndef HZ
5618#define HZ 60 /* Universal constant :-) */
5619#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005620
Guido van Rossumd48f2521997-12-05 22:19:34 +00005621#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5622static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005623system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005624{
5625 ULONG value = 0;
5626
5627 Py_BEGIN_ALLOW_THREADS
5628 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5629 Py_END_ALLOW_THREADS
5630
5631 return value;
5632}
5633
5634static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005635posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005636{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005637 /* Currently Only Uptime is Provided -- Others Later */
5638 return Py_BuildValue("ddddd",
5639 (double)0 /* t.tms_utime / HZ */,
5640 (double)0 /* t.tms_stime / HZ */,
5641 (double)0 /* t.tms_cutime / HZ */,
5642 (double)0 /* t.tms_cstime / HZ */,
5643 (double)system_uptime() / 1000);
5644}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005645#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005646static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005647posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005648{
5649 struct tms t;
5650 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005651 errno = 0;
5652 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005653 if (c == (clock_t) -1)
5654 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005655 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005656 (double)t.tms_utime / HZ,
5657 (double)t.tms_stime / HZ,
5658 (double)t.tms_cutime / HZ,
5659 (double)t.tms_cstime / HZ,
5660 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005661}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005662#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005663#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005664
5665
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005666#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005667#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005668static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005669posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005670{
5671 FILETIME create, exit, kernel, user;
5672 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005673 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005674 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5675 /* The fields of a FILETIME structure are the hi and lo part
5676 of a 64-bit value expressed in 100 nanosecond units.
5677 1e7 is one second in such units; 1e-7 the inverse.
5678 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5679 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005680 return Py_BuildValue(
5681 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005682 (double)(kernel.dwHighDateTime*429.4967296 +
5683 kernel.dwLowDateTime*1e-7),
5684 (double)(user.dwHighDateTime*429.4967296 +
5685 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005686 (double)0,
5687 (double)0,
5688 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005689}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005690#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005691
5692#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005693PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005694"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005695Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005696#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005697
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005698
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005699#ifdef HAVE_GETSID
5700PyDoc_STRVAR(posix_getsid__doc__,
5701"getsid(pid) -> sid\n\n\
5702Call the system call getsid().");
5703
5704static PyObject *
5705posix_getsid(PyObject *self, PyObject *args)
5706{
5707 int pid, sid;
5708 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5709 return NULL;
5710 sid = getsid(pid);
5711 if (sid < 0)
5712 return posix_error();
5713 return PyInt_FromLong((long)sid);
5714}
5715#endif /* HAVE_GETSID */
5716
5717
Guido van Rossumb6775db1994-08-01 11:34:53 +00005718#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005719PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005720"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005721Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005722
Barry Warsaw53699e91996-12-10 23:23:01 +00005723static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005724posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005725{
Guido van Rossum687dd131993-05-17 08:34:16 +00005726 if (setsid() < 0)
5727 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005728 Py_INCREF(Py_None);
5729 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005730}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005731#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005732
Guido van Rossumb6775db1994-08-01 11:34:53 +00005733#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005734PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005735"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005736Call the system call setpgid().");
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_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005740{
5741 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005742 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005743 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005744 if (setpgid(pid, pgrp) < 0)
5745 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005746 Py_INCREF(Py_None);
5747 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005748}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005749#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005750
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005751
Guido van Rossumb6775db1994-08-01 11:34:53 +00005752#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005753PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005754"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005755Return 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_tcgetpgrp(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, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005762 return NULL;
5763 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005764 if (pgid < 0)
5765 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005766 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005767}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005768#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005769
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005770
Guido van Rossumb6775db1994-08-01 11:34:53 +00005771#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005772PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005773"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005774Set the process group associated with the terminal given by a fd.");
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_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005778{
5779 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005780 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005781 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005782 if (tcsetpgrp(fd, pgid) < 0)
5783 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005784 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005785 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005786}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005787#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005788
Guido van Rossum687dd131993-05-17 08:34:16 +00005789/* Functions acting on file descriptors */
5790
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005791PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005792"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005793Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005794
Barry Warsaw53699e91996-12-10 23:23:01 +00005795static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005796posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005797{
Mark Hammondef8b6542001-05-13 08:04:26 +00005798 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005799 int flag;
5800 int mode = 0777;
5801 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005802
5803#ifdef MS_WINDOWS
5804 if (unicode_file_names()) {
5805 PyUnicodeObject *po;
5806 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5807 Py_BEGIN_ALLOW_THREADS
5808 /* PyUnicode_AS_UNICODE OK without thread
5809 lock as it is a simple dereference. */
5810 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5811 Py_END_ALLOW_THREADS
5812 if (fd < 0)
5813 return posix_error();
5814 return PyInt_FromLong((long)fd);
5815 }
5816 /* Drop the argument parsing error as narrow strings
5817 are also valid. */
5818 PyErr_Clear();
5819 }
5820#endif
5821
Tim Peters5aa91602002-01-30 05:46:57 +00005822 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005823 Py_FileSystemDefaultEncoding, &file,
5824 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005825 return NULL;
5826
Barry Warsaw53699e91996-12-10 23:23:01 +00005827 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005828 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005829 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005830 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005831 return posix_error_with_allocated_filename(file);
5832 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005833 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005834}
5835
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005836
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005837PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005838"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005839Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005840
Barry Warsaw53699e91996-12-10 23:23:01 +00005841static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005842posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005843{
5844 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005845 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005846 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005847 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005848 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005849 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005850 if (res < 0)
5851 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005852 Py_INCREF(Py_None);
5853 return Py_None;
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_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005858"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005859Return a duplicate of a 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_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005863{
5864 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005865 if (!PyArg_ParseTuple(args, "i:dup", &fd))
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 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005869 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005870 if (fd < 0)
5871 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005872 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005873}
5874
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005875
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005876PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005877"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005878Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005879
Barry Warsaw53699e91996-12-10 23:23:01 +00005880static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005881posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005882{
5883 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005884 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005885 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005886 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005887 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005888 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005889 if (res < 0)
5890 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005891 Py_INCREF(Py_None);
5892 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005893}
5894
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005895
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005896PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005897"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005898Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005899
Barry Warsaw53699e91996-12-10 23:23:01 +00005900static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005901posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005902{
5903 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005904#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005905 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005906#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005907 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005908#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005909 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005910 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005911 return NULL;
5912#ifdef SEEK_SET
5913 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5914 switch (how) {
5915 case 0: how = SEEK_SET; break;
5916 case 1: how = SEEK_CUR; break;
5917 case 2: how = SEEK_END; break;
5918 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005919#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005920
5921#if !defined(HAVE_LARGEFILE_SUPPORT)
5922 pos = PyInt_AsLong(posobj);
5923#else
5924 pos = PyLong_Check(posobj) ?
5925 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5926#endif
5927 if (PyErr_Occurred())
5928 return NULL;
5929
Barry Warsaw53699e91996-12-10 23:23:01 +00005930 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005931#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005932 res = _lseeki64(fd, pos, how);
5933#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005934 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005935#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005936 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005937 if (res < 0)
5938 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005939
5940#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005941 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005942#else
5943 return PyLong_FromLongLong(res);
5944#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005945}
5946
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005947
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005948PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005949"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005950Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005951
Barry Warsaw53699e91996-12-10 23:23:01 +00005952static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005953posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005954{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005955 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005956 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005957 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005958 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005959 if (size < 0) {
5960 errno = EINVAL;
5961 return posix_error();
5962 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005963 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005964 if (buffer == NULL)
5965 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005966 Py_BEGIN_ALLOW_THREADS
5967 n = read(fd, PyString_AsString(buffer), size);
5968 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005969 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005970 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005971 return posix_error();
5972 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005973 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005974 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005975 return buffer;
5976}
5977
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005978
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005979PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005980"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005981Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005982
Barry Warsaw53699e91996-12-10 23:23:01 +00005983static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005984posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005985{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005986 int fd;
5987 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00005988 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005989
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005990 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005991 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005992 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005993 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005994 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005995 if (size < 0)
5996 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005997 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005998}
5999
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006000
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006001PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006002"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006003Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006004
Barry Warsaw53699e91996-12-10 23:23:01 +00006005static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006006posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006007{
6008 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00006009 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00006010 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006011 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006012 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006013#ifdef __VMS
6014 /* on OpenVMS we must ensure that all bytes are written to the file */
6015 fsync(fd);
6016#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006017 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00006018 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00006019 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00006020 if (res != 0) {
6021#ifdef MS_WINDOWS
6022 return win32_error("fstat", NULL);
6023#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006024 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006025#endif
6026 }
Tim Peters5aa91602002-01-30 05:46:57 +00006027
Martin v. Löwis14694662006-02-03 12:54:16 +00006028 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006029}
6030
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006031
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006032PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006033"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006034Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006035
Barry Warsaw53699e91996-12-10 23:23:01 +00006036static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006037posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006038{
Guido van Rossum687dd131993-05-17 08:34:16 +00006039 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006040 char *mode = "r";
6041 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00006042 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00006043 PyObject *f;
6044 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00006045 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006046
Thomas Heller1f043e22002-11-07 16:00:59 +00006047 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
6048 PyErr_Format(PyExc_ValueError,
6049 "invalid file mode '%s'", mode);
6050 return NULL;
6051 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006052 Py_BEGIN_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006053#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
6054 if (mode[0] == 'a') {
6055 /* try to make sure the O_APPEND flag is set */
6056 int flags;
6057 flags = fcntl(fd, F_GETFL);
6058 if (flags != -1)
6059 fcntl(fd, F_SETFL, flags | O_APPEND);
6060 fp = fdopen(fd, mode);
6061 if (fp == NULL && flags != -1)
6062 /* restore old mode if fdopen failed */
6063 fcntl(fd, F_SETFL, flags);
6064 } else {
6065 fp = fdopen(fd, mode);
6066 }
6067#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006068 fp = fdopen(fd, mode);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006069#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006070 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006071 if (fp == NULL)
6072 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00006073 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006074 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00006075 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006076 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006077}
6078
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006079PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006080"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006081Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006082connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006083
6084static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006085posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006086{
6087 int fd;
6088 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6089 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006090 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006091}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006092
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006093#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006094PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006095"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006096Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006097
Barry Warsaw53699e91996-12-10 23:23:01 +00006098static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006099posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006100{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006101#if defined(PYOS_OS2)
6102 HFILE read, write;
6103 APIRET rc;
6104
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006105 Py_BEGIN_ALLOW_THREADS
6106 rc = DosCreatePipe( &read, &write, 4096);
6107 Py_END_ALLOW_THREADS
6108 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006109 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006110
6111 return Py_BuildValue("(ii)", read, write);
6112#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006113#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00006114 int fds[2];
6115 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00006116 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006117 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00006118 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006119 if (res != 0)
6120 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006121 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006122#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00006123 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006124 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00006125 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00006126 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006127 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00006128 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00006129 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006130 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00006131 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6132 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006133 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006134#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006135#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006136}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006137#endif /* HAVE_PIPE */
6138
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006139
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006140#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006141PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006142"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006143Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006144
Barry Warsaw53699e91996-12-10 23:23:01 +00006145static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006146posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006147{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006148 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006149 int mode = 0666;
6150 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006151 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006152 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006153 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006154 res = mkfifo(filename, mode);
6155 Py_END_ALLOW_THREADS
6156 if (res < 0)
6157 return posix_error();
6158 Py_INCREF(Py_None);
6159 return Py_None;
6160}
6161#endif
6162
6163
Neal Norwitz11690112002-07-30 01:08:28 +00006164#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006165PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006166"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006167Create a filesystem node (file, device special file or named pipe)\n\
6168named filename. mode specifies both the permissions to use and the\n\
6169type of node to be created, being combined (bitwise OR) with one of\n\
6170S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006171device defines the newly created device special file (probably using\n\
6172os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006173
6174
6175static PyObject *
6176posix_mknod(PyObject *self, PyObject *args)
6177{
6178 char *filename;
6179 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006180 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006181 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00006182 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006183 return NULL;
6184 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006185 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00006186 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006187 if (res < 0)
6188 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006189 Py_INCREF(Py_None);
6190 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006191}
6192#endif
6193
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006194#ifdef HAVE_DEVICE_MACROS
6195PyDoc_STRVAR(posix_major__doc__,
6196"major(device) -> major number\n\
6197Extracts a device major number from a raw device number.");
6198
6199static PyObject *
6200posix_major(PyObject *self, PyObject *args)
6201{
6202 int device;
6203 if (!PyArg_ParseTuple(args, "i:major", &device))
6204 return NULL;
6205 return PyInt_FromLong((long)major(device));
6206}
6207
6208PyDoc_STRVAR(posix_minor__doc__,
6209"minor(device) -> minor number\n\
6210Extracts a device minor number from a raw device number.");
6211
6212static PyObject *
6213posix_minor(PyObject *self, PyObject *args)
6214{
6215 int device;
6216 if (!PyArg_ParseTuple(args, "i:minor", &device))
6217 return NULL;
6218 return PyInt_FromLong((long)minor(device));
6219}
6220
6221PyDoc_STRVAR(posix_makedev__doc__,
6222"makedev(major, minor) -> device number\n\
6223Composes a raw device number from the major and minor device numbers.");
6224
6225static PyObject *
6226posix_makedev(PyObject *self, PyObject *args)
6227{
6228 int major, minor;
6229 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6230 return NULL;
6231 return PyInt_FromLong((long)makedev(major, minor));
6232}
6233#endif /* device macros */
6234
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006235
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006236#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006237PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006238"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006239Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006240
Barry Warsaw53699e91996-12-10 23:23:01 +00006241static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006242posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006243{
6244 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006245 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006246 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006247 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006248
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006249 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006250 return NULL;
6251
6252#if !defined(HAVE_LARGEFILE_SUPPORT)
6253 length = PyInt_AsLong(lenobj);
6254#else
6255 length = PyLong_Check(lenobj) ?
6256 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6257#endif
6258 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006259 return NULL;
6260
Barry Warsaw53699e91996-12-10 23:23:01 +00006261 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006262 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006263 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006264 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006265 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006266 return NULL;
6267 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006268 Py_INCREF(Py_None);
6269 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006270}
6271#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006272
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006273#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006274PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006275"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006276Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006277
Fred Drake762e2061999-08-26 17:23:54 +00006278/* Save putenv() parameters as values here, so we can collect them when they
6279 * get re-set with another call for the same key. */
6280static PyObject *posix_putenv_garbage;
6281
Tim Peters5aa91602002-01-30 05:46:57 +00006282static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006283posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006284{
6285 char *s1, *s2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006286 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006287 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006288 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006289
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006290 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006291 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006292
6293#if defined(PYOS_OS2)
6294 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6295 APIRET rc;
6296
Guido van Rossumd48f2521997-12-05 22:19:34 +00006297 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6298 if (rc != NO_ERROR)
6299 return os2_error(rc);
6300
6301 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6302 APIRET rc;
6303
Guido van Rossumd48f2521997-12-05 22:19:34 +00006304 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6305 if (rc != NO_ERROR)
6306 return os2_error(rc);
6307 } else {
6308#endif
6309
Fred Drake762e2061999-08-26 17:23:54 +00006310 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006311 len = strlen(s1) + strlen(s2) + 2;
6312 /* len includes space for a trailing \0; the size arg to
6313 PyString_FromStringAndSize does not count that */
6314 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006315 if (newstr == NULL)
6316 return PyErr_NoMemory();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006317 newenv = PyString_AS_STRING(newstr);
6318 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6319 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006320 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006321 posix_error();
6322 return NULL;
6323 }
Fred Drake762e2061999-08-26 17:23:54 +00006324 /* Install the first arg and newstr in posix_putenv_garbage;
6325 * this will cause previous value to be collected. This has to
6326 * happen after the real putenv() call because the old value
6327 * was still accessible until then. */
6328 if (PyDict_SetItem(posix_putenv_garbage,
6329 PyTuple_GET_ITEM(args, 0), newstr)) {
6330 /* really not much we can do; just leak */
6331 PyErr_Clear();
6332 }
6333 else {
6334 Py_DECREF(newstr);
6335 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006336
6337#if defined(PYOS_OS2)
6338 }
6339#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006340 Py_INCREF(Py_None);
6341 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006342}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006343#endif /* putenv */
6344
Guido van Rossumc524d952001-10-19 01:31:59 +00006345#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006346PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006347"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006348Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006349
6350static PyObject *
6351posix_unsetenv(PyObject *self, PyObject *args)
6352{
6353 char *s1;
6354
6355 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6356 return NULL;
6357
6358 unsetenv(s1);
6359
6360 /* Remove the key from posix_putenv_garbage;
6361 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006362 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006363 * old value was still accessible until then.
6364 */
6365 if (PyDict_DelItem(posix_putenv_garbage,
6366 PyTuple_GET_ITEM(args, 0))) {
6367 /* really not much we can do; just leak */
6368 PyErr_Clear();
6369 }
6370
6371 Py_INCREF(Py_None);
6372 return Py_None;
6373}
6374#endif /* unsetenv */
6375
Guido van Rossumb6a47161997-09-15 22:54:34 +00006376#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006377PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006378"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006379Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006380
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006381static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006382posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006383{
6384 int code;
6385 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006386 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006387 return NULL;
6388 message = strerror(code);
6389 if (message == NULL) {
6390 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006391 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006392 return NULL;
6393 }
6394 return PyString_FromString(message);
6395}
6396#endif /* strerror */
6397
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006398
Guido van Rossumc9641791998-08-04 15:26:23 +00006399#ifdef HAVE_SYS_WAIT_H
6400
Fred Drake106c1a02002-04-23 15:58:02 +00006401#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006402PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006403"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006404Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006405
6406static PyObject *
6407posix_WCOREDUMP(PyObject *self, PyObject *args)
6408{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006409 WAIT_TYPE status;
6410 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006411
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006412 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006413 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006414
6415 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006416}
6417#endif /* WCOREDUMP */
6418
6419#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006420PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006421"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006422Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006423job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006424
6425static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006426posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006427{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006428 WAIT_TYPE status;
6429 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006430
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006431 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006432 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006433
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006434 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006435}
6436#endif /* WIFCONTINUED */
6437
Guido van Rossumc9641791998-08-04 15:26:23 +00006438#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006439PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006440"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006441Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006442
6443static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006444posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006445{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006446 WAIT_TYPE status;
6447 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006448
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006449 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006450 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006451
Fred Drake106c1a02002-04-23 15:58:02 +00006452 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006453}
6454#endif /* WIFSTOPPED */
6455
6456#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006457PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006458"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006459Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006460
6461static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006462posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006463{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006464 WAIT_TYPE status;
6465 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006466
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006467 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &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(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006471}
6472#endif /* WIFSIGNALED */
6473
6474#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006475PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006476"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006477Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006478system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006479
6480static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006481posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006482{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006483 WAIT_TYPE status;
6484 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006485
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006486 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006487 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006488
Fred Drake106c1a02002-04-23 15:58:02 +00006489 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006490}
6491#endif /* WIFEXITED */
6492
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006493#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006494PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006495"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006496Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006497
6498static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006499posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006500{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006501 WAIT_TYPE status;
6502 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006503
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006504 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &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", WEXITSTATUS(status));
6508}
6509#endif /* WEXITSTATUS */
6510
6511#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006512PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006513"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006514Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006515value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006516
6517static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006518posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006519{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006520 WAIT_TYPE status;
6521 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006522
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006523 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &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", WTERMSIG(status));
6527}
6528#endif /* WTERMSIG */
6529
6530#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006531PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006532"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006533Return the signal that stopped the process that provided\n\
6534the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006535
6536static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006537posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006538{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006539 WAIT_TYPE status;
6540 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006541
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006542 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006543 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006544
Guido van Rossumc9641791998-08-04 15:26:23 +00006545 return Py_BuildValue("i", WSTOPSIG(status));
6546}
6547#endif /* WSTOPSIG */
6548
6549#endif /* HAVE_SYS_WAIT_H */
6550
6551
Thomas Wouters477c8d52006-05-27 19:21:47 +00006552#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006553#ifdef _SCO_DS
6554/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6555 needed definitions in sys/statvfs.h */
6556#define _SVID3
6557#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006558#include <sys/statvfs.h>
6559
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006560static PyObject*
6561_pystatvfs_fromstructstatvfs(struct statvfs st) {
6562 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6563 if (v == NULL)
6564 return NULL;
6565
6566#if !defined(HAVE_LARGEFILE_SUPPORT)
6567 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6568 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6569 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6570 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6571 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6572 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6573 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6574 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6575 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6576 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6577#else
6578 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6579 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006580 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006581 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006582 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006583 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006584 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006585 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006586 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006587 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006588 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006589 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006590 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006591 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006592 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6593 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6594#endif
6595
6596 return v;
6597}
6598
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006599PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006600"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006601Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006602
6603static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006604posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006605{
6606 int fd, res;
6607 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006608
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006609 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006610 return NULL;
6611 Py_BEGIN_ALLOW_THREADS
6612 res = fstatvfs(fd, &st);
6613 Py_END_ALLOW_THREADS
6614 if (res != 0)
6615 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006616
6617 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006618}
Thomas Wouters477c8d52006-05-27 19:21:47 +00006619#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006620
6621
Thomas Wouters477c8d52006-05-27 19:21:47 +00006622#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006623#include <sys/statvfs.h>
6624
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006625PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006626"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006627Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006628
6629static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006630posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006631{
6632 char *path;
6633 int res;
6634 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006635 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006636 return NULL;
6637 Py_BEGIN_ALLOW_THREADS
6638 res = statvfs(path, &st);
6639 Py_END_ALLOW_THREADS
6640 if (res != 0)
6641 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006642
6643 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006644}
6645#endif /* HAVE_STATVFS */
6646
6647
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006648#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006649PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006650"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006651Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006652The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006653or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006654
6655static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006656posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006657{
6658 PyObject *result = NULL;
6659 char *dir = NULL;
6660 char *pfx = NULL;
6661 char *name;
6662
6663 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6664 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006665
6666 if (PyErr_Warn(PyExc_RuntimeWarning,
6667 "tempnam is a potential security risk to your program") < 0)
6668 return NULL;
6669
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006670#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006671 name = _tempnam(dir, pfx);
6672#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006673 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006674#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006675 if (name == NULL)
6676 return PyErr_NoMemory();
6677 result = PyString_FromString(name);
6678 free(name);
6679 return result;
6680}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006681#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006682
6683
6684#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006685PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006686"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006687Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006688
6689static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006690posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006691{
6692 FILE *fp;
6693
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006694 fp = tmpfile();
6695 if (fp == NULL)
6696 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006697 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006698}
6699#endif
6700
6701
6702#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006703PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006704"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006705Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006706
6707static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006708posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006709{
6710 char buffer[L_tmpnam];
6711 char *name;
6712
Skip Montanaro95618b52001-08-18 18:52:10 +00006713 if (PyErr_Warn(PyExc_RuntimeWarning,
6714 "tmpnam is a potential security risk to your program") < 0)
6715 return NULL;
6716
Greg Wardb48bc172000-03-01 21:51:56 +00006717#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006718 name = tmpnam_r(buffer);
6719#else
6720 name = tmpnam(buffer);
6721#endif
6722 if (name == NULL) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006723 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006724#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006725 "unexpected NULL from tmpnam_r"
6726#else
6727 "unexpected NULL from tmpnam"
6728#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006729 );
6730 PyErr_SetObject(PyExc_OSError, err);
6731 Py_XDECREF(err);
6732 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006733 }
6734 return PyString_FromString(buffer);
6735}
6736#endif
6737
6738
Fred Drakec9680921999-12-13 16:37:25 +00006739/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6740 * It maps strings representing configuration variable names to
6741 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006742 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006743 * rarely-used constants. There are three separate tables that use
6744 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006745 *
6746 * This code is always included, even if none of the interfaces that
6747 * need it are included. The #if hackery needed to avoid it would be
6748 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006749 */
6750struct constdef {
6751 char *name;
6752 long value;
6753};
6754
Fred Drake12c6e2d1999-12-14 21:25:03 +00006755static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006756conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6757 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006758{
6759 if (PyInt_Check(arg)) {
6760 *valuep = PyInt_AS_LONG(arg);
6761 return 1;
6762 }
6763 if (PyString_Check(arg)) {
6764 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006765 size_t lo = 0;
6766 size_t mid;
6767 size_t hi = tablesize;
6768 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006769 char *confname = PyString_AS_STRING(arg);
6770 while (lo < hi) {
6771 mid = (lo + hi) / 2;
6772 cmp = strcmp(confname, table[mid].name);
6773 if (cmp < 0)
6774 hi = mid;
6775 else if (cmp > 0)
6776 lo = mid + 1;
6777 else {
6778 *valuep = table[mid].value;
6779 return 1;
6780 }
6781 }
6782 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6783 }
6784 else
6785 PyErr_SetString(PyExc_TypeError,
6786 "configuration names must be strings or integers");
6787 return 0;
6788}
6789
6790
6791#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6792static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006793#ifdef _PC_ABI_AIO_XFER_MAX
6794 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6795#endif
6796#ifdef _PC_ABI_ASYNC_IO
6797 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6798#endif
Fred Drakec9680921999-12-13 16:37:25 +00006799#ifdef _PC_ASYNC_IO
6800 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6801#endif
6802#ifdef _PC_CHOWN_RESTRICTED
6803 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6804#endif
6805#ifdef _PC_FILESIZEBITS
6806 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6807#endif
6808#ifdef _PC_LAST
6809 {"PC_LAST", _PC_LAST},
6810#endif
6811#ifdef _PC_LINK_MAX
6812 {"PC_LINK_MAX", _PC_LINK_MAX},
6813#endif
6814#ifdef _PC_MAX_CANON
6815 {"PC_MAX_CANON", _PC_MAX_CANON},
6816#endif
6817#ifdef _PC_MAX_INPUT
6818 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6819#endif
6820#ifdef _PC_NAME_MAX
6821 {"PC_NAME_MAX", _PC_NAME_MAX},
6822#endif
6823#ifdef _PC_NO_TRUNC
6824 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6825#endif
6826#ifdef _PC_PATH_MAX
6827 {"PC_PATH_MAX", _PC_PATH_MAX},
6828#endif
6829#ifdef _PC_PIPE_BUF
6830 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6831#endif
6832#ifdef _PC_PRIO_IO
6833 {"PC_PRIO_IO", _PC_PRIO_IO},
6834#endif
6835#ifdef _PC_SOCK_MAXBUF
6836 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6837#endif
6838#ifdef _PC_SYNC_IO
6839 {"PC_SYNC_IO", _PC_SYNC_IO},
6840#endif
6841#ifdef _PC_VDISABLE
6842 {"PC_VDISABLE", _PC_VDISABLE},
6843#endif
6844};
6845
Fred Drakec9680921999-12-13 16:37:25 +00006846static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006847conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006848{
6849 return conv_confname(arg, valuep, posix_constants_pathconf,
6850 sizeof(posix_constants_pathconf)
6851 / sizeof(struct constdef));
6852}
6853#endif
6854
6855#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006856PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006857"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006858Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006859If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006860
6861static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006862posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006863{
6864 PyObject *result = NULL;
6865 int name, fd;
6866
Fred Drake12c6e2d1999-12-14 21:25:03 +00006867 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6868 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006869 long limit;
6870
6871 errno = 0;
6872 limit = fpathconf(fd, name);
6873 if (limit == -1 && errno != 0)
6874 posix_error();
6875 else
6876 result = PyInt_FromLong(limit);
6877 }
6878 return result;
6879}
6880#endif
6881
6882
6883#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006884PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006885"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006886Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006887If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006888
6889static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006890posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006891{
6892 PyObject *result = NULL;
6893 int name;
6894 char *path;
6895
6896 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6897 conv_path_confname, &name)) {
6898 long limit;
6899
6900 errno = 0;
6901 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006902 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006903 if (errno == EINVAL)
6904 /* could be a path or name problem */
6905 posix_error();
6906 else
6907 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006908 }
Fred Drakec9680921999-12-13 16:37:25 +00006909 else
6910 result = PyInt_FromLong(limit);
6911 }
6912 return result;
6913}
6914#endif
6915
6916#ifdef HAVE_CONFSTR
6917static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006918#ifdef _CS_ARCHITECTURE
6919 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6920#endif
6921#ifdef _CS_HOSTNAME
6922 {"CS_HOSTNAME", _CS_HOSTNAME},
6923#endif
6924#ifdef _CS_HW_PROVIDER
6925 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6926#endif
6927#ifdef _CS_HW_SERIAL
6928 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6929#endif
6930#ifdef _CS_INITTAB_NAME
6931 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6932#endif
Fred Drakec9680921999-12-13 16:37:25 +00006933#ifdef _CS_LFS64_CFLAGS
6934 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6935#endif
6936#ifdef _CS_LFS64_LDFLAGS
6937 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6938#endif
6939#ifdef _CS_LFS64_LIBS
6940 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6941#endif
6942#ifdef _CS_LFS64_LINTFLAGS
6943 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6944#endif
6945#ifdef _CS_LFS_CFLAGS
6946 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6947#endif
6948#ifdef _CS_LFS_LDFLAGS
6949 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6950#endif
6951#ifdef _CS_LFS_LIBS
6952 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6953#endif
6954#ifdef _CS_LFS_LINTFLAGS
6955 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6956#endif
Fred Draked86ed291999-12-15 15:34:33 +00006957#ifdef _CS_MACHINE
6958 {"CS_MACHINE", _CS_MACHINE},
6959#endif
Fred Drakec9680921999-12-13 16:37:25 +00006960#ifdef _CS_PATH
6961 {"CS_PATH", _CS_PATH},
6962#endif
Fred Draked86ed291999-12-15 15:34:33 +00006963#ifdef _CS_RELEASE
6964 {"CS_RELEASE", _CS_RELEASE},
6965#endif
6966#ifdef _CS_SRPC_DOMAIN
6967 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6968#endif
6969#ifdef _CS_SYSNAME
6970 {"CS_SYSNAME", _CS_SYSNAME},
6971#endif
6972#ifdef _CS_VERSION
6973 {"CS_VERSION", _CS_VERSION},
6974#endif
Fred Drakec9680921999-12-13 16:37:25 +00006975#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6976 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6977#endif
6978#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6979 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6980#endif
6981#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6982 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6983#endif
6984#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6985 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6986#endif
6987#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6988 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6989#endif
6990#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6991 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6992#endif
6993#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6994 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6995#endif
6996#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6997 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6998#endif
6999#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7000 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
7001#endif
7002#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7003 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7004#endif
7005#ifdef _CS_XBS5_LP64_OFF64_LIBS
7006 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7007#endif
7008#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7009 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7010#endif
7011#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7012 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7013#endif
7014#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7015 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7016#endif
7017#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7018 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7019#endif
7020#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7021 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7022#endif
Fred Draked86ed291999-12-15 15:34:33 +00007023#ifdef _MIPS_CS_AVAIL_PROCESSORS
7024 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7025#endif
7026#ifdef _MIPS_CS_BASE
7027 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7028#endif
7029#ifdef _MIPS_CS_HOSTID
7030 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7031#endif
7032#ifdef _MIPS_CS_HW_NAME
7033 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7034#endif
7035#ifdef _MIPS_CS_NUM_PROCESSORS
7036 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7037#endif
7038#ifdef _MIPS_CS_OSREL_MAJ
7039 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7040#endif
7041#ifdef _MIPS_CS_OSREL_MIN
7042 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7043#endif
7044#ifdef _MIPS_CS_OSREL_PATCH
7045 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7046#endif
7047#ifdef _MIPS_CS_OS_NAME
7048 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7049#endif
7050#ifdef _MIPS_CS_OS_PROVIDER
7051 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7052#endif
7053#ifdef _MIPS_CS_PROCESSORS
7054 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7055#endif
7056#ifdef _MIPS_CS_SERIAL
7057 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7058#endif
7059#ifdef _MIPS_CS_VENDOR
7060 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7061#endif
Fred Drakec9680921999-12-13 16:37:25 +00007062};
7063
7064static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007065conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007066{
7067 return conv_confname(arg, valuep, posix_constants_confstr,
7068 sizeof(posix_constants_confstr)
7069 / sizeof(struct constdef));
7070}
7071
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007072PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007073"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007074Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007075
7076static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007077posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007078{
7079 PyObject *result = NULL;
7080 int name;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007081 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007082
7083 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007084 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007085
Fred Drakec9680921999-12-13 16:37:25 +00007086 errno = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007087 len = confstr(name, buffer, sizeof(buffer));
7088 if (len == 0) {
7089 if (errno) {
7090 posix_error();
7091 }
7092 else {
7093 result = Py_None;
7094 Py_INCREF(Py_None);
7095 }
Fred Drakec9680921999-12-13 16:37:25 +00007096 }
7097 else {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007098 if ((unsigned int)len >= sizeof(buffer)) {
7099 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007100 if (result != NULL)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007101 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00007102 }
7103 else
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007104 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007105 }
7106 }
7107 return result;
7108}
7109#endif
7110
7111
7112#ifdef HAVE_SYSCONF
7113static struct constdef posix_constants_sysconf[] = {
7114#ifdef _SC_2_CHAR_TERM
7115 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7116#endif
7117#ifdef _SC_2_C_BIND
7118 {"SC_2_C_BIND", _SC_2_C_BIND},
7119#endif
7120#ifdef _SC_2_C_DEV
7121 {"SC_2_C_DEV", _SC_2_C_DEV},
7122#endif
7123#ifdef _SC_2_C_VERSION
7124 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7125#endif
7126#ifdef _SC_2_FORT_DEV
7127 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7128#endif
7129#ifdef _SC_2_FORT_RUN
7130 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7131#endif
7132#ifdef _SC_2_LOCALEDEF
7133 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7134#endif
7135#ifdef _SC_2_SW_DEV
7136 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7137#endif
7138#ifdef _SC_2_UPE
7139 {"SC_2_UPE", _SC_2_UPE},
7140#endif
7141#ifdef _SC_2_VERSION
7142 {"SC_2_VERSION", _SC_2_VERSION},
7143#endif
Fred Draked86ed291999-12-15 15:34:33 +00007144#ifdef _SC_ABI_ASYNCHRONOUS_IO
7145 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7146#endif
7147#ifdef _SC_ACL
7148 {"SC_ACL", _SC_ACL},
7149#endif
Fred Drakec9680921999-12-13 16:37:25 +00007150#ifdef _SC_AIO_LISTIO_MAX
7151 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7152#endif
Fred Drakec9680921999-12-13 16:37:25 +00007153#ifdef _SC_AIO_MAX
7154 {"SC_AIO_MAX", _SC_AIO_MAX},
7155#endif
7156#ifdef _SC_AIO_PRIO_DELTA_MAX
7157 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7158#endif
7159#ifdef _SC_ARG_MAX
7160 {"SC_ARG_MAX", _SC_ARG_MAX},
7161#endif
7162#ifdef _SC_ASYNCHRONOUS_IO
7163 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7164#endif
7165#ifdef _SC_ATEXIT_MAX
7166 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7167#endif
Fred Draked86ed291999-12-15 15:34:33 +00007168#ifdef _SC_AUDIT
7169 {"SC_AUDIT", _SC_AUDIT},
7170#endif
Fred Drakec9680921999-12-13 16:37:25 +00007171#ifdef _SC_AVPHYS_PAGES
7172 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7173#endif
7174#ifdef _SC_BC_BASE_MAX
7175 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7176#endif
7177#ifdef _SC_BC_DIM_MAX
7178 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7179#endif
7180#ifdef _SC_BC_SCALE_MAX
7181 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7182#endif
7183#ifdef _SC_BC_STRING_MAX
7184 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7185#endif
Fred Draked86ed291999-12-15 15:34:33 +00007186#ifdef _SC_CAP
7187 {"SC_CAP", _SC_CAP},
7188#endif
Fred Drakec9680921999-12-13 16:37:25 +00007189#ifdef _SC_CHARCLASS_NAME_MAX
7190 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7191#endif
7192#ifdef _SC_CHAR_BIT
7193 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7194#endif
7195#ifdef _SC_CHAR_MAX
7196 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7197#endif
7198#ifdef _SC_CHAR_MIN
7199 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7200#endif
7201#ifdef _SC_CHILD_MAX
7202 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7203#endif
7204#ifdef _SC_CLK_TCK
7205 {"SC_CLK_TCK", _SC_CLK_TCK},
7206#endif
7207#ifdef _SC_COHER_BLKSZ
7208 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7209#endif
7210#ifdef _SC_COLL_WEIGHTS_MAX
7211 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7212#endif
7213#ifdef _SC_DCACHE_ASSOC
7214 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7215#endif
7216#ifdef _SC_DCACHE_BLKSZ
7217 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7218#endif
7219#ifdef _SC_DCACHE_LINESZ
7220 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7221#endif
7222#ifdef _SC_DCACHE_SZ
7223 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7224#endif
7225#ifdef _SC_DCACHE_TBLKSZ
7226 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7227#endif
7228#ifdef _SC_DELAYTIMER_MAX
7229 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7230#endif
7231#ifdef _SC_EQUIV_CLASS_MAX
7232 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7233#endif
7234#ifdef _SC_EXPR_NEST_MAX
7235 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7236#endif
7237#ifdef _SC_FSYNC
7238 {"SC_FSYNC", _SC_FSYNC},
7239#endif
7240#ifdef _SC_GETGR_R_SIZE_MAX
7241 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7242#endif
7243#ifdef _SC_GETPW_R_SIZE_MAX
7244 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7245#endif
7246#ifdef _SC_ICACHE_ASSOC
7247 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7248#endif
7249#ifdef _SC_ICACHE_BLKSZ
7250 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7251#endif
7252#ifdef _SC_ICACHE_LINESZ
7253 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7254#endif
7255#ifdef _SC_ICACHE_SZ
7256 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7257#endif
Fred Draked86ed291999-12-15 15:34:33 +00007258#ifdef _SC_INF
7259 {"SC_INF", _SC_INF},
7260#endif
Fred Drakec9680921999-12-13 16:37:25 +00007261#ifdef _SC_INT_MAX
7262 {"SC_INT_MAX", _SC_INT_MAX},
7263#endif
7264#ifdef _SC_INT_MIN
7265 {"SC_INT_MIN", _SC_INT_MIN},
7266#endif
7267#ifdef _SC_IOV_MAX
7268 {"SC_IOV_MAX", _SC_IOV_MAX},
7269#endif
Fred Draked86ed291999-12-15 15:34:33 +00007270#ifdef _SC_IP_SECOPTS
7271 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7272#endif
Fred Drakec9680921999-12-13 16:37:25 +00007273#ifdef _SC_JOB_CONTROL
7274 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7275#endif
Fred Draked86ed291999-12-15 15:34:33 +00007276#ifdef _SC_KERN_POINTERS
7277 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7278#endif
7279#ifdef _SC_KERN_SIM
7280 {"SC_KERN_SIM", _SC_KERN_SIM},
7281#endif
Fred Drakec9680921999-12-13 16:37:25 +00007282#ifdef _SC_LINE_MAX
7283 {"SC_LINE_MAX", _SC_LINE_MAX},
7284#endif
7285#ifdef _SC_LOGIN_NAME_MAX
7286 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7287#endif
7288#ifdef _SC_LOGNAME_MAX
7289 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7290#endif
7291#ifdef _SC_LONG_BIT
7292 {"SC_LONG_BIT", _SC_LONG_BIT},
7293#endif
Fred Draked86ed291999-12-15 15:34:33 +00007294#ifdef _SC_MAC
7295 {"SC_MAC", _SC_MAC},
7296#endif
Fred Drakec9680921999-12-13 16:37:25 +00007297#ifdef _SC_MAPPED_FILES
7298 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7299#endif
7300#ifdef _SC_MAXPID
7301 {"SC_MAXPID", _SC_MAXPID},
7302#endif
7303#ifdef _SC_MB_LEN_MAX
7304 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7305#endif
7306#ifdef _SC_MEMLOCK
7307 {"SC_MEMLOCK", _SC_MEMLOCK},
7308#endif
7309#ifdef _SC_MEMLOCK_RANGE
7310 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7311#endif
7312#ifdef _SC_MEMORY_PROTECTION
7313 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7314#endif
7315#ifdef _SC_MESSAGE_PASSING
7316 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7317#endif
Fred Draked86ed291999-12-15 15:34:33 +00007318#ifdef _SC_MMAP_FIXED_ALIGNMENT
7319 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7320#endif
Fred Drakec9680921999-12-13 16:37:25 +00007321#ifdef _SC_MQ_OPEN_MAX
7322 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7323#endif
7324#ifdef _SC_MQ_PRIO_MAX
7325 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7326#endif
Fred Draked86ed291999-12-15 15:34:33 +00007327#ifdef _SC_NACLS_MAX
7328 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7329#endif
Fred Drakec9680921999-12-13 16:37:25 +00007330#ifdef _SC_NGROUPS_MAX
7331 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7332#endif
7333#ifdef _SC_NL_ARGMAX
7334 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7335#endif
7336#ifdef _SC_NL_LANGMAX
7337 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7338#endif
7339#ifdef _SC_NL_MSGMAX
7340 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7341#endif
7342#ifdef _SC_NL_NMAX
7343 {"SC_NL_NMAX", _SC_NL_NMAX},
7344#endif
7345#ifdef _SC_NL_SETMAX
7346 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7347#endif
7348#ifdef _SC_NL_TEXTMAX
7349 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7350#endif
7351#ifdef _SC_NPROCESSORS_CONF
7352 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7353#endif
7354#ifdef _SC_NPROCESSORS_ONLN
7355 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7356#endif
Fred Draked86ed291999-12-15 15:34:33 +00007357#ifdef _SC_NPROC_CONF
7358 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7359#endif
7360#ifdef _SC_NPROC_ONLN
7361 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7362#endif
Fred Drakec9680921999-12-13 16:37:25 +00007363#ifdef _SC_NZERO
7364 {"SC_NZERO", _SC_NZERO},
7365#endif
7366#ifdef _SC_OPEN_MAX
7367 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7368#endif
7369#ifdef _SC_PAGESIZE
7370 {"SC_PAGESIZE", _SC_PAGESIZE},
7371#endif
7372#ifdef _SC_PAGE_SIZE
7373 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7374#endif
7375#ifdef _SC_PASS_MAX
7376 {"SC_PASS_MAX", _SC_PASS_MAX},
7377#endif
7378#ifdef _SC_PHYS_PAGES
7379 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7380#endif
7381#ifdef _SC_PII
7382 {"SC_PII", _SC_PII},
7383#endif
7384#ifdef _SC_PII_INTERNET
7385 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7386#endif
7387#ifdef _SC_PII_INTERNET_DGRAM
7388 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7389#endif
7390#ifdef _SC_PII_INTERNET_STREAM
7391 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7392#endif
7393#ifdef _SC_PII_OSI
7394 {"SC_PII_OSI", _SC_PII_OSI},
7395#endif
7396#ifdef _SC_PII_OSI_CLTS
7397 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7398#endif
7399#ifdef _SC_PII_OSI_COTS
7400 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7401#endif
7402#ifdef _SC_PII_OSI_M
7403 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7404#endif
7405#ifdef _SC_PII_SOCKET
7406 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7407#endif
7408#ifdef _SC_PII_XTI
7409 {"SC_PII_XTI", _SC_PII_XTI},
7410#endif
7411#ifdef _SC_POLL
7412 {"SC_POLL", _SC_POLL},
7413#endif
7414#ifdef _SC_PRIORITIZED_IO
7415 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7416#endif
7417#ifdef _SC_PRIORITY_SCHEDULING
7418 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7419#endif
7420#ifdef _SC_REALTIME_SIGNALS
7421 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7422#endif
7423#ifdef _SC_RE_DUP_MAX
7424 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7425#endif
7426#ifdef _SC_RTSIG_MAX
7427 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7428#endif
7429#ifdef _SC_SAVED_IDS
7430 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7431#endif
7432#ifdef _SC_SCHAR_MAX
7433 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7434#endif
7435#ifdef _SC_SCHAR_MIN
7436 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7437#endif
7438#ifdef _SC_SELECT
7439 {"SC_SELECT", _SC_SELECT},
7440#endif
7441#ifdef _SC_SEMAPHORES
7442 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7443#endif
7444#ifdef _SC_SEM_NSEMS_MAX
7445 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7446#endif
7447#ifdef _SC_SEM_VALUE_MAX
7448 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7449#endif
7450#ifdef _SC_SHARED_MEMORY_OBJECTS
7451 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7452#endif
7453#ifdef _SC_SHRT_MAX
7454 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7455#endif
7456#ifdef _SC_SHRT_MIN
7457 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7458#endif
7459#ifdef _SC_SIGQUEUE_MAX
7460 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7461#endif
7462#ifdef _SC_SIGRT_MAX
7463 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7464#endif
7465#ifdef _SC_SIGRT_MIN
7466 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7467#endif
Fred Draked86ed291999-12-15 15:34:33 +00007468#ifdef _SC_SOFTPOWER
7469 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7470#endif
Fred Drakec9680921999-12-13 16:37:25 +00007471#ifdef _SC_SPLIT_CACHE
7472 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7473#endif
7474#ifdef _SC_SSIZE_MAX
7475 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7476#endif
7477#ifdef _SC_STACK_PROT
7478 {"SC_STACK_PROT", _SC_STACK_PROT},
7479#endif
7480#ifdef _SC_STREAM_MAX
7481 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7482#endif
7483#ifdef _SC_SYNCHRONIZED_IO
7484 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7485#endif
7486#ifdef _SC_THREADS
7487 {"SC_THREADS", _SC_THREADS},
7488#endif
7489#ifdef _SC_THREAD_ATTR_STACKADDR
7490 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7491#endif
7492#ifdef _SC_THREAD_ATTR_STACKSIZE
7493 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7494#endif
7495#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7496 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7497#endif
7498#ifdef _SC_THREAD_KEYS_MAX
7499 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7500#endif
7501#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7502 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7503#endif
7504#ifdef _SC_THREAD_PRIO_INHERIT
7505 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7506#endif
7507#ifdef _SC_THREAD_PRIO_PROTECT
7508 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7509#endif
7510#ifdef _SC_THREAD_PROCESS_SHARED
7511 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7512#endif
7513#ifdef _SC_THREAD_SAFE_FUNCTIONS
7514 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7515#endif
7516#ifdef _SC_THREAD_STACK_MIN
7517 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7518#endif
7519#ifdef _SC_THREAD_THREADS_MAX
7520 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7521#endif
7522#ifdef _SC_TIMERS
7523 {"SC_TIMERS", _SC_TIMERS},
7524#endif
7525#ifdef _SC_TIMER_MAX
7526 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7527#endif
7528#ifdef _SC_TTY_NAME_MAX
7529 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7530#endif
7531#ifdef _SC_TZNAME_MAX
7532 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7533#endif
7534#ifdef _SC_T_IOV_MAX
7535 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7536#endif
7537#ifdef _SC_UCHAR_MAX
7538 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7539#endif
7540#ifdef _SC_UINT_MAX
7541 {"SC_UINT_MAX", _SC_UINT_MAX},
7542#endif
7543#ifdef _SC_UIO_MAXIOV
7544 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7545#endif
7546#ifdef _SC_ULONG_MAX
7547 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7548#endif
7549#ifdef _SC_USHRT_MAX
7550 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7551#endif
7552#ifdef _SC_VERSION
7553 {"SC_VERSION", _SC_VERSION},
7554#endif
7555#ifdef _SC_WORD_BIT
7556 {"SC_WORD_BIT", _SC_WORD_BIT},
7557#endif
7558#ifdef _SC_XBS5_ILP32_OFF32
7559 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7560#endif
7561#ifdef _SC_XBS5_ILP32_OFFBIG
7562 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7563#endif
7564#ifdef _SC_XBS5_LP64_OFF64
7565 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7566#endif
7567#ifdef _SC_XBS5_LPBIG_OFFBIG
7568 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7569#endif
7570#ifdef _SC_XOPEN_CRYPT
7571 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7572#endif
7573#ifdef _SC_XOPEN_ENH_I18N
7574 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7575#endif
7576#ifdef _SC_XOPEN_LEGACY
7577 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7578#endif
7579#ifdef _SC_XOPEN_REALTIME
7580 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7581#endif
7582#ifdef _SC_XOPEN_REALTIME_THREADS
7583 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7584#endif
7585#ifdef _SC_XOPEN_SHM
7586 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7587#endif
7588#ifdef _SC_XOPEN_UNIX
7589 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7590#endif
7591#ifdef _SC_XOPEN_VERSION
7592 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7593#endif
7594#ifdef _SC_XOPEN_XCU_VERSION
7595 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7596#endif
7597#ifdef _SC_XOPEN_XPG2
7598 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7599#endif
7600#ifdef _SC_XOPEN_XPG3
7601 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7602#endif
7603#ifdef _SC_XOPEN_XPG4
7604 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7605#endif
7606};
7607
7608static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007609conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007610{
7611 return conv_confname(arg, valuep, posix_constants_sysconf,
7612 sizeof(posix_constants_sysconf)
7613 / sizeof(struct constdef));
7614}
7615
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007616PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007617"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007618Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007619
7620static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007621posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007622{
7623 PyObject *result = NULL;
7624 int name;
7625
7626 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7627 int value;
7628
7629 errno = 0;
7630 value = sysconf(name);
7631 if (value == -1 && errno != 0)
7632 posix_error();
7633 else
7634 result = PyInt_FromLong(value);
7635 }
7636 return result;
7637}
7638#endif
7639
7640
Fred Drakebec628d1999-12-15 18:31:10 +00007641/* This code is used to ensure that the tables of configuration value names
7642 * are in sorted order as required by conv_confname(), and also to build the
7643 * the exported dictionaries that are used to publish information about the
7644 * names available on the host platform.
7645 *
7646 * Sorting the table at runtime ensures that the table is properly ordered
7647 * when used, even for platforms we're not able to test on. It also makes
7648 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007649 */
Fred Drakebec628d1999-12-15 18:31:10 +00007650
7651static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007652cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007653{
7654 const struct constdef *c1 =
7655 (const struct constdef *) v1;
7656 const struct constdef *c2 =
7657 (const struct constdef *) v2;
7658
7659 return strcmp(c1->name, c2->name);
7660}
7661
7662static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007663setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007664 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007665{
Fred Drakebec628d1999-12-15 18:31:10 +00007666 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007667 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007668
7669 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7670 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007671 if (d == NULL)
7672 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007673
Barry Warsaw3155db32000-04-13 15:20:40 +00007674 for (i=0; i < tablesize; ++i) {
7675 PyObject *o = PyInt_FromLong(table[i].value);
7676 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7677 Py_XDECREF(o);
7678 Py_DECREF(d);
7679 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007680 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007681 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007682 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007683 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007684}
7685
Fred Drakebec628d1999-12-15 18:31:10 +00007686/* Return -1 on failure, 0 on success. */
7687static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007688setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007689{
7690#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007691 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007692 sizeof(posix_constants_pathconf)
7693 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007694 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007695 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007696#endif
7697#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007698 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007699 sizeof(posix_constants_confstr)
7700 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007701 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007702 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007703#endif
7704#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007705 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007706 sizeof(posix_constants_sysconf)
7707 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007708 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007709 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007710#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007711 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007712}
Fred Draked86ed291999-12-15 15:34:33 +00007713
7714
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007715PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007716"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007717Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007718in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007719
7720static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007721posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007722{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007723 abort();
7724 /*NOTREACHED*/
7725 Py_FatalError("abort() called from Python code didn't abort!");
7726 return NULL;
7727}
Fred Drakebec628d1999-12-15 18:31:10 +00007728
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007729#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007730PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007731"startfile(filepath [, operation]) - Start a file with its associated\n\
7732application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007733\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007734When \"operation\" is not specified or \"open\", this acts like\n\
7735double-clicking the file in Explorer, or giving the file name as an\n\
7736argument to the DOS \"start\" command: the file is opened with whatever\n\
7737application (if any) its extension is associated.\n\
7738When another \"operation\" is given, it specifies what should be done with\n\
7739the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007740\n\
7741startfile returns as soon as the associated application is launched.\n\
7742There is no option to wait for the application to close, and no way\n\
7743to retrieve the application's exit status.\n\
7744\n\
7745The filepath is relative to the current directory. If you want to use\n\
7746an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007747the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007748
7749static PyObject *
7750win32_startfile(PyObject *self, PyObject *args)
7751{
7752 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00007753 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007754 HINSTANCE rc;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007755#ifdef Py_WIN_WIDE_FILENAMES
7756 if (unicode_file_names()) {
7757 PyObject *unipath, *woperation = NULL;
7758 if (!PyArg_ParseTuple(args, "U|s:startfile",
7759 &unipath, &operation)) {
7760 PyErr_Clear();
7761 goto normal;
7762 }
7763
7764
7765 if (operation) {
7766 woperation = PyUnicode_DecodeASCII(operation,
7767 strlen(operation), NULL);
7768 if (!woperation) {
7769 PyErr_Clear();
7770 operation = NULL;
7771 goto normal;
7772 }
7773 }
7774
7775 Py_BEGIN_ALLOW_THREADS
7776 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
7777 PyUnicode_AS_UNICODE(unipath),
7778 NULL, NULL, SW_SHOWNORMAL);
7779 Py_END_ALLOW_THREADS
7780
7781 Py_XDECREF(woperation);
7782 if (rc <= (HINSTANCE)32) {
7783 PyObject *errval = win32_error_unicode("startfile",
7784 PyUnicode_AS_UNICODE(unipath));
7785 return errval;
7786 }
7787 Py_INCREF(Py_None);
7788 return Py_None;
7789 }
7790#endif
7791
7792normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00007793 if (!PyArg_ParseTuple(args, "et|s:startfile",
7794 Py_FileSystemDefaultEncoding, &filepath,
7795 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00007796 return NULL;
7797 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00007798 rc = ShellExecute((HWND)0, operation, filepath,
7799 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007800 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00007801 if (rc <= (HINSTANCE)32) {
7802 PyObject *errval = win32_error("startfile", filepath);
7803 PyMem_Free(filepath);
7804 return errval;
7805 }
7806 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007807 Py_INCREF(Py_None);
7808 return Py_None;
7809}
7810#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007811
Martin v. Löwis438b5342002-12-27 10:16:42 +00007812#ifdef HAVE_GETLOADAVG
7813PyDoc_STRVAR(posix_getloadavg__doc__,
7814"getloadavg() -> (float, float, float)\n\n\
7815Return the number of processes in the system run queue averaged over\n\
7816the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7817was unobtainable");
7818
7819static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007820posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007821{
7822 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007823 if (getloadavg(loadavg, 3)!=3) {
7824 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7825 return NULL;
7826 } else
7827 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7828}
7829#endif
7830
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007831#ifdef MS_WINDOWS
7832
7833PyDoc_STRVAR(win32_urandom__doc__,
7834"urandom(n) -> str\n\n\
7835Return a string of n random bytes suitable for cryptographic use.");
7836
7837typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7838 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7839 DWORD dwFlags );
7840typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7841 BYTE *pbBuffer );
7842
7843static CRYPTGENRANDOM pCryptGenRandom = NULL;
7844static HCRYPTPROV hCryptProv = 0;
7845
Tim Peters4ad82172004-08-30 17:02:04 +00007846static PyObject*
7847win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007848{
Tim Petersd3115382004-08-30 17:36:46 +00007849 int howMany;
7850 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007851
Tim Peters4ad82172004-08-30 17:02:04 +00007852 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00007853 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00007854 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00007855 if (howMany < 0)
7856 return PyErr_Format(PyExc_ValueError,
7857 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007858
Tim Peters4ad82172004-08-30 17:02:04 +00007859 if (hCryptProv == 0) {
7860 HINSTANCE hAdvAPI32 = NULL;
7861 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007862
Tim Peters4ad82172004-08-30 17:02:04 +00007863 /* Obtain handle to the DLL containing CryptoAPI
7864 This should not fail */
7865 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7866 if(hAdvAPI32 == NULL)
7867 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007868
Tim Peters4ad82172004-08-30 17:02:04 +00007869 /* Obtain pointers to the CryptoAPI functions
7870 This will fail on some early versions of Win95 */
7871 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7872 hAdvAPI32,
7873 "CryptAcquireContextA");
7874 if (pCryptAcquireContext == NULL)
7875 return PyErr_Format(PyExc_NotImplementedError,
7876 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007877
Tim Peters4ad82172004-08-30 17:02:04 +00007878 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7879 hAdvAPI32, "CryptGenRandom");
7880 if (pCryptAcquireContext == NULL)
7881 return PyErr_Format(PyExc_NotImplementedError,
7882 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007883
Tim Peters4ad82172004-08-30 17:02:04 +00007884 /* Acquire context */
7885 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7886 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7887 return win32_error("CryptAcquireContext", NULL);
7888 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007889
Tim Peters4ad82172004-08-30 17:02:04 +00007890 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00007891 result = PyString_FromStringAndSize(NULL, howMany);
7892 if (result != NULL) {
7893 /* Get random data */
7894 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7895 PyString_AS_STRING(result))) {
7896 Py_DECREF(result);
7897 return win32_error("CryptGenRandom", NULL);
7898 }
Tim Peters4ad82172004-08-30 17:02:04 +00007899 }
Tim Petersd3115382004-08-30 17:36:46 +00007900 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007901}
7902#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007903
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007904#ifdef __VMS
7905/* Use openssl random routine */
7906#include <openssl/rand.h>
7907PyDoc_STRVAR(vms_urandom__doc__,
7908"urandom(n) -> str\n\n\
7909Return a string of n random bytes suitable for cryptographic use.");
7910
7911static PyObject*
7912vms_urandom(PyObject *self, PyObject *args)
7913{
7914 int howMany;
7915 PyObject* result;
7916
7917 /* Read arguments */
7918 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7919 return NULL;
7920 if (howMany < 0)
7921 return PyErr_Format(PyExc_ValueError,
7922 "negative argument not allowed");
7923
7924 /* Allocate bytes */
7925 result = PyString_FromStringAndSize(NULL, howMany);
7926 if (result != NULL) {
7927 /* Get random data */
7928 if (RAND_pseudo_bytes((unsigned char*)
7929 PyString_AS_STRING(result),
7930 howMany) < 0) {
7931 Py_DECREF(result);
7932 return PyErr_Format(PyExc_ValueError,
7933 "RAND_pseudo_bytes");
7934 }
7935 }
7936 return result;
7937}
7938#endif
7939
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007940static PyMethodDef posix_methods[] = {
7941 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7942#ifdef HAVE_TTYNAME
7943 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7944#endif
7945 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7946 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007947#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007948 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007949#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007950#ifdef HAVE_LCHOWN
7951 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7952#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007953#ifdef HAVE_CHROOT
7954 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7955#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007956#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007957 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007958#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007959#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007960 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007961#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007962 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007963#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007964#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007965#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007966 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007967#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007968 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7969 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7970 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007971#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007972 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007973#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007974#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007975 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007976#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007977 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7978 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7979 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007980 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007981#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007982 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007983#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007984#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007985 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007986#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007987 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007988#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007989 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007990#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007991 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7992 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7993 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007994#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007995 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007996#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007997 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007998#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007999 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8000 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008001#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008002#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008003 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8004 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008005#if defined(PYOS_OS2)
8006 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8007 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8008#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008009#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008010#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00008011 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008012#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008013#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00008014 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008015#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008016#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00008017 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008018#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008019#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00008020 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008021#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008022#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008023 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008024#endif /* HAVE_GETEGID */
8025#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008026 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008027#endif /* HAVE_GETEUID */
8028#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008029 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008030#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008031#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00008032 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008033#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008034 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008035#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008036 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008037#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008038#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00008039 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008040#endif /* HAVE_GETPPID */
8041#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008042 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008043#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008044#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00008045 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008046#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008047#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008048 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008049#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008050#ifdef HAVE_KILLPG
8051 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8052#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008053#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008054 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008055#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008056#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008057 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008058#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008059 {"popen2", win32_popen2, METH_VARARGS},
8060 {"popen3", win32_popen3, METH_VARARGS},
8061 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00008062 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008063#else
8064#if defined(PYOS_OS2) && defined(PYCC_GCC)
8065 {"popen2", os2emx_popen2, METH_VARARGS},
8066 {"popen3", os2emx_popen3, METH_VARARGS},
8067 {"popen4", os2emx_popen4, METH_VARARGS},
8068#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008069#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008070#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008071#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008072 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008073#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008074#ifdef HAVE_SETEUID
8075 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8076#endif /* HAVE_SETEUID */
8077#ifdef HAVE_SETEGID
8078 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8079#endif /* HAVE_SETEGID */
8080#ifdef HAVE_SETREUID
8081 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8082#endif /* HAVE_SETREUID */
8083#ifdef HAVE_SETREGID
8084 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8085#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008086#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008087 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008088#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008089#ifdef HAVE_SETGROUPS
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00008090 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008091#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008092#ifdef HAVE_GETPGID
8093 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8094#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008095#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008096 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008097#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008098#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00008099 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008100#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008101#ifdef HAVE_WAIT3
8102 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8103#endif /* HAVE_WAIT3 */
8104#ifdef HAVE_WAIT4
8105 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8106#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008107#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008108 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008109#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008110#ifdef HAVE_GETSID
8111 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8112#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008113#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00008114 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008115#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008116#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008117 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008118#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008119#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008120 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008121#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008122#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008123 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008124#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008125 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8126 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8127 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8128 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8129 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8130 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8131 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8132 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8133 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00008134 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008135#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00008136 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008137#endif
8138#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008139 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008140#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008141#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008142 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8143#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008144#ifdef HAVE_DEVICE_MACROS
8145 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8146 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8147 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8148#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008149#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008150 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008151#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008152#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008153 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008154#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008155#ifdef HAVE_UNSETENV
8156 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8157#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00008158#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008159 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00008160#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00008161#ifdef HAVE_FCHDIR
8162 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8163#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008164#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008165 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008166#endif
8167#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008168 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008169#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008170#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008171#ifdef WCOREDUMP
8172 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8173#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008174#ifdef WIFCONTINUED
8175 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8176#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008177#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008178 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008179#endif /* WIFSTOPPED */
8180#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008181 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008182#endif /* WIFSIGNALED */
8183#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008184 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008185#endif /* WIFEXITED */
8186#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008187 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008188#endif /* WEXITSTATUS */
8189#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008190 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008191#endif /* WTERMSIG */
8192#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008193 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008194#endif /* WSTOPSIG */
8195#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008196#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008197 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008198#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00008199#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008200 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008201#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008202#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00008203 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008204#endif
8205#ifdef HAVE_TEMPNAM
8206 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8207#endif
8208#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00008209 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008210#endif
Fred Drakec9680921999-12-13 16:37:25 +00008211#ifdef HAVE_CONFSTR
8212 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8213#endif
8214#ifdef HAVE_SYSCONF
8215 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8216#endif
8217#ifdef HAVE_FPATHCONF
8218 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8219#endif
8220#ifdef HAVE_PATHCONF
8221 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8222#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008223 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008224#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00008225 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8226#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008227#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00008228 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008229#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008230 #ifdef MS_WINDOWS
8231 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8232 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008233 #ifdef __VMS
8234 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8235 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008236 {NULL, NULL} /* Sentinel */
8237};
8238
8239
Barry Warsaw4a342091996-12-19 23:50:02 +00008240static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008241ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008242{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008243 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008244}
8245
Guido van Rossumd48f2521997-12-05 22:19:34 +00008246#if defined(PYOS_OS2)
8247/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008248static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008249{
8250 APIRET rc;
8251 ULONG values[QSV_MAX+1];
8252 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008253 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008254
8255 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008256 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008257 Py_END_ALLOW_THREADS
8258
8259 if (rc != NO_ERROR) {
8260 os2_error(rc);
8261 return -1;
8262 }
8263
Fred Drake4d1e64b2002-04-15 19:40:07 +00008264 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8265 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8266 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8267 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8268 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8269 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8270 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008271
8272 switch (values[QSV_VERSION_MINOR]) {
8273 case 0: ver = "2.00"; break;
8274 case 10: ver = "2.10"; break;
8275 case 11: ver = "2.11"; break;
8276 case 30: ver = "3.00"; break;
8277 case 40: ver = "4.00"; break;
8278 case 50: ver = "5.00"; break;
8279 default:
Tim Peters885d4572001-11-28 20:27:42 +00008280 PyOS_snprintf(tmp, sizeof(tmp),
8281 "%d-%d", values[QSV_VERSION_MAJOR],
8282 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008283 ver = &tmp[0];
8284 }
8285
8286 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008287 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008288 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008289
8290 /* Add Indicator of Which Drive was Used to Boot the System */
8291 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8292 tmp[1] = ':';
8293 tmp[2] = '\0';
8294
Fred Drake4d1e64b2002-04-15 19:40:07 +00008295 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008296}
8297#endif
8298
Barry Warsaw4a342091996-12-19 23:50:02 +00008299static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008300all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008301{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008302#ifdef F_OK
8303 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008304#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008305#ifdef R_OK
8306 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008307#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008308#ifdef W_OK
8309 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008310#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008311#ifdef X_OK
8312 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008313#endif
Fred Drakec9680921999-12-13 16:37:25 +00008314#ifdef NGROUPS_MAX
8315 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8316#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008317#ifdef TMP_MAX
8318 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8319#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008320#ifdef WCONTINUED
8321 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8322#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008323#ifdef WNOHANG
8324 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008325#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008326#ifdef WUNTRACED
8327 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8328#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008329#ifdef O_RDONLY
8330 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8331#endif
8332#ifdef O_WRONLY
8333 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8334#endif
8335#ifdef O_RDWR
8336 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8337#endif
8338#ifdef O_NDELAY
8339 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8340#endif
8341#ifdef O_NONBLOCK
8342 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8343#endif
8344#ifdef O_APPEND
8345 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8346#endif
8347#ifdef O_DSYNC
8348 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8349#endif
8350#ifdef O_RSYNC
8351 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8352#endif
8353#ifdef O_SYNC
8354 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8355#endif
8356#ifdef O_NOCTTY
8357 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8358#endif
8359#ifdef O_CREAT
8360 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8361#endif
8362#ifdef O_EXCL
8363 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8364#endif
8365#ifdef O_TRUNC
8366 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8367#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008368#ifdef O_BINARY
8369 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8370#endif
8371#ifdef O_TEXT
8372 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8373#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008374#ifdef O_LARGEFILE
8375 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8376#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008377#ifdef O_SHLOCK
8378 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8379#endif
8380#ifdef O_EXLOCK
8381 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8382#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008383
Tim Peters5aa91602002-01-30 05:46:57 +00008384/* MS Windows */
8385#ifdef O_NOINHERIT
8386 /* Don't inherit in child processes. */
8387 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8388#endif
8389#ifdef _O_SHORT_LIVED
8390 /* Optimize for short life (keep in memory). */
8391 /* MS forgot to define this one with a non-underscore form too. */
8392 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8393#endif
8394#ifdef O_TEMPORARY
8395 /* Automatically delete when last handle is closed. */
8396 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8397#endif
8398#ifdef O_RANDOM
8399 /* Optimize for random access. */
8400 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8401#endif
8402#ifdef O_SEQUENTIAL
8403 /* Optimize for sequential access. */
8404 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8405#endif
8406
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008407/* GNU extensions. */
8408#ifdef O_DIRECT
8409 /* Direct disk access. */
8410 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8411#endif
8412#ifdef O_DIRECTORY
8413 /* Must be a directory. */
8414 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8415#endif
8416#ifdef O_NOFOLLOW
8417 /* Do not follow links. */
8418 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8419#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008420
Barry Warsaw5676bd12003-01-07 20:57:09 +00008421 /* These come from sysexits.h */
8422#ifdef EX_OK
8423 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008424#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008425#ifdef EX_USAGE
8426 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008427#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008428#ifdef EX_DATAERR
8429 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008430#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008431#ifdef EX_NOINPUT
8432 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008433#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008434#ifdef EX_NOUSER
8435 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008436#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008437#ifdef EX_NOHOST
8438 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008439#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008440#ifdef EX_UNAVAILABLE
8441 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008442#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008443#ifdef EX_SOFTWARE
8444 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008445#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008446#ifdef EX_OSERR
8447 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008448#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008449#ifdef EX_OSFILE
8450 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008451#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008452#ifdef EX_CANTCREAT
8453 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008454#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008455#ifdef EX_IOERR
8456 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008457#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008458#ifdef EX_TEMPFAIL
8459 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008460#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008461#ifdef EX_PROTOCOL
8462 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008463#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008464#ifdef EX_NOPERM
8465 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008466#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008467#ifdef EX_CONFIG
8468 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008469#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008470#ifdef EX_NOTFOUND
8471 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008472#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008473
Guido van Rossum246bc171999-02-01 23:54:31 +00008474#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008475#if defined(PYOS_OS2) && defined(PYCC_GCC)
8476 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8477 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8478 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8479 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8480 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8481 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8482 if (ins(d, "P_PM", (long)P_PM)) return -1;
8483 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8484 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8485 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8486 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8487 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8488 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8489 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8490 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8491 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8492 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8493 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8494 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8495 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8496#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008497 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8498 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8499 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8500 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8501 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008502#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008503#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008504
Guido van Rossumd48f2521997-12-05 22:19:34 +00008505#if defined(PYOS_OS2)
8506 if (insertvalues(d)) return -1;
8507#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008508 return 0;
8509}
8510
8511
Tim Peters5aa91602002-01-30 05:46:57 +00008512#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008513#define INITFUNC initnt
8514#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008515
8516#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008517#define INITFUNC initos2
8518#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008519
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008520#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008521#define INITFUNC initposix
8522#define MODNAME "posix"
8523#endif
8524
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008525PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008526INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008527{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008528 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008529
Fred Drake4d1e64b2002-04-15 19:40:07 +00008530 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008531 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008532 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008533 if (m == NULL)
8534 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008535
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008536 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008537 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008538 Py_XINCREF(v);
8539 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008540 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008541 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008542
Fred Drake4d1e64b2002-04-15 19:40:07 +00008543 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008544 return;
8545
Fred Drake4d1e64b2002-04-15 19:40:07 +00008546 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008547 return;
8548
Fred Drake4d1e64b2002-04-15 19:40:07 +00008549 Py_INCREF(PyExc_OSError);
8550 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008551
Guido van Rossumb3d39562000-01-31 18:41:26 +00008552#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008553 if (posix_putenv_garbage == NULL)
8554 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008555#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008556
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008557 if (!initialized) {
8558 stat_result_desc.name = MODNAME ".stat_result";
8559 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8560 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8561 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8562 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8563 structseq_new = StatResultType.tp_new;
8564 StatResultType.tp_new = statresult_new;
8565
8566 statvfs_result_desc.name = MODNAME ".statvfs_result";
8567 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
8568 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008569 Py_INCREF((PyObject*) &StatResultType);
8570 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008571 Py_INCREF((PyObject*) &StatVFSResultType);
8572 PyModule_AddObject(m, "statvfs_result",
8573 (PyObject*) &StatVFSResultType);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008574 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008575
8576#ifdef __APPLE__
8577 /*
8578 * Step 2 of weak-linking support on Mac OS X.
8579 *
8580 * The code below removes functions that are not available on the
8581 * currently active platform.
8582 *
8583 * This block allow one to use a python binary that was build on
8584 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8585 * OSX 10.4.
8586 */
8587#ifdef HAVE_FSTATVFS
8588 if (fstatvfs == NULL) {
8589 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8590 return;
8591 }
8592 }
8593#endif /* HAVE_FSTATVFS */
8594
8595#ifdef HAVE_STATVFS
8596 if (statvfs == NULL) {
8597 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8598 return;
8599 }
8600 }
8601#endif /* HAVE_STATVFS */
8602
8603# ifdef HAVE_LCHOWN
8604 if (lchown == NULL) {
8605 if (PyObject_DelAttrString(m, "lchown") == -1) {
8606 return;
8607 }
8608 }
8609#endif /* HAVE_LCHOWN */
8610
8611
8612#endif /* __APPLE__ */
8613
Guido van Rossumb6775db1994-08-01 11:34:53 +00008614}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008615
8616#ifdef __cplusplus
8617}
8618#endif
8619