blob: d968b6c4cd4df0e015411edc8745b02eb5bb8728 [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
1124 if (_stat_float_times) {
1125 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1126 } else {
1127 fval = ival;
1128 Py_INCREF(fval);
1129 }
1130 PyStructSequence_SET_ITEM(v, index, ival);
1131 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001132}
1133
Tim Peters5aa91602002-01-30 05:46:57 +00001134/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001135 (used by posix_stat() and posix_fstat()) */
1136static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001137_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001138{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001139 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001140 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001141 if (v == NULL)
1142 return NULL;
1143
Martin v. Löwis14694662006-02-03 12:54:16 +00001144 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001145#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001146 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001147 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001148#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001149 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001150#endif
1151#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001152 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001153 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001154#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001155 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001156#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001157 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1158 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1159 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001160#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001161 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001162 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001163#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001164 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001165#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001166
Martin v. Löwis14694662006-02-03 12:54:16 +00001167#if defined(HAVE_STAT_TV_NSEC)
1168 ansec = st->st_atim.tv_nsec;
1169 mnsec = st->st_mtim.tv_nsec;
1170 cnsec = st->st_ctim.tv_nsec;
1171#elif defined(HAVE_STAT_TV_NSEC2)
1172 ansec = st->st_atimespec.tv_nsec;
1173 mnsec = st->st_mtimespec.tv_nsec;
1174 cnsec = st->st_ctimespec.tv_nsec;
1175#elif defined(HAVE_STAT_NSEC)
1176 ansec = st->st_atime_nsec;
1177 mnsec = st->st_mtime_nsec;
1178 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001179#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001180 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001181#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001182 fill_time(v, 7, st->st_atime, ansec);
1183 fill_time(v, 8, st->st_mtime, mnsec);
1184 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001185
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001186#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001187 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001188 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001189#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001190#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001191 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001192 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001193#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001194#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001195 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001196 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001197#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001198#ifdef HAVE_STRUCT_STAT_ST_GEN
1199 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001200 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001201#endif
1202#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1203 {
1204 PyObject *val;
1205 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001206 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001207#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001208 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001209#else
1210 bnsec = 0;
1211#endif
1212 if (_stat_float_times) {
1213 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1214 } else {
1215 val = PyInt_FromLong((long)bsec);
1216 }
1217 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1218 val);
1219 }
1220#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001221#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1222 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001223 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001224#endif
Fred Drake699f3522000-06-29 21:12:41 +00001225
1226 if (PyErr_Occurred()) {
1227 Py_DECREF(v);
1228 return NULL;
1229 }
1230
1231 return v;
1232}
1233
Martin v. Löwisd8948722004-06-02 09:57:56 +00001234#ifdef MS_WINDOWS
1235
1236/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1237 where / can be used in place of \ and the trailing slash is optional.
1238 Both SERVER and SHARE must have at least one character.
1239*/
1240
1241#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1242#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001243#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001244#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001245#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001246
Tim Peters4ad82172004-08-30 17:02:04 +00001247static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001248IsUNCRootA(char *path, int pathlen)
1249{
1250 #define ISSLASH ISSLASHA
1251
1252 int i, share;
1253
1254 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1255 /* minimum UNCRoot is \\x\y */
1256 return FALSE;
1257 for (i = 2; i < pathlen ; i++)
1258 if (ISSLASH(path[i])) break;
1259 if (i == 2 || i == pathlen)
1260 /* do not allow \\\SHARE or \\SERVER */
1261 return FALSE;
1262 share = i+1;
1263 for (i = share; i < pathlen; i++)
1264 if (ISSLASH(path[i])) break;
1265 return (i != share && (i == pathlen || i == pathlen-1));
1266
1267 #undef ISSLASH
1268}
1269
1270#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001271static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001272IsUNCRootW(Py_UNICODE *path, int pathlen)
1273{
1274 #define ISSLASH ISSLASHW
1275
1276 int i, share;
1277
1278 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1279 /* minimum UNCRoot is \\x\y */
1280 return FALSE;
1281 for (i = 2; i < pathlen ; i++)
1282 if (ISSLASH(path[i])) break;
1283 if (i == 2 || i == pathlen)
1284 /* do not allow \\\SHARE or \\SERVER */
1285 return FALSE;
1286 share = i+1;
1287 for (i = share; i < pathlen; i++)
1288 if (ISSLASH(path[i])) break;
1289 return (i != share && (i == pathlen || i == pathlen-1));
1290
1291 #undef ISSLASH
1292}
1293#endif /* Py_WIN_WIDE_FILENAMES */
1294#endif /* MS_WINDOWS */
1295
Barry Warsaw53699e91996-12-10 23:23:01 +00001296static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001297posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001298 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001299#ifdef __VMS
1300 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1301#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001302 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001303#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001304 char *wformat,
1305 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001306{
Fred Drake699f3522000-06-29 21:12:41 +00001307 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001308 char *path = NULL; /* pass this to stat; do not free() it */
1309 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001310 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001311 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001312
1313#ifdef Py_WIN_WIDE_FILENAMES
1314 /* If on wide-character-capable OS see if argument
1315 is Unicode and if so use wide API. */
1316 if (unicode_file_names()) {
1317 PyUnicodeObject *po;
1318 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001319 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1320
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001321 Py_BEGIN_ALLOW_THREADS
1322 /* PyUnicode_AS_UNICODE result OK without
1323 thread lock as it is a simple dereference. */
1324 res = wstatfunc(wpath, &st);
1325 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001326
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001327 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001328 return win32_error_unicode("stat", wpath);
1329 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001330 }
1331 /* Drop the argument parsing error as narrow strings
1332 are also valid. */
1333 PyErr_Clear();
1334 }
1335#endif
1336
Tim Peters5aa91602002-01-30 05:46:57 +00001337 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001338 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001339 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001340 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001341
Barry Warsaw53699e91996-12-10 23:23:01 +00001342 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001343 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001344 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001345
1346 if (res != 0) {
1347#ifdef MS_WINDOWS
1348 result = win32_error("stat", pathfree);
1349#else
1350 result = posix_error_with_filename(pathfree);
1351#endif
1352 }
1353 else
1354 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001355
Tim Peters500bd032001-12-19 19:05:01 +00001356 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001357 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001358}
1359
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001360/* POSIX methods */
1361
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001362PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001363"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001364Use the real uid/gid to test for access to a path. Note that most\n\
1365operations will use the effective uid/gid, therefore this routine can\n\
1366be used in a suid/sgid environment to test if the invoking user has the\n\
1367specified access to the path. The mode argument can be F_OK to test\n\
1368existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001369
1370static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001371posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001372{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001373 char *path;
1374 int mode;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001375
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001376#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001377 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001378 if (unicode_file_names()) {
1379 PyUnicodeObject *po;
1380 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1381 Py_BEGIN_ALLOW_THREADS
1382 /* PyUnicode_AS_UNICODE OK without thread lock as
1383 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001384 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001385 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001386 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001387 }
1388 /* Drop the argument parsing error as narrow strings
1389 are also valid. */
1390 PyErr_Clear();
1391 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001392 if (!PyArg_ParseTuple(args, "eti:access",
1393 Py_FileSystemDefaultEncoding, &path, &mode))
1394 return 0;
1395 Py_BEGIN_ALLOW_THREADS
1396 attr = GetFileAttributesA(path);
1397 Py_END_ALLOW_THREADS
1398 PyMem_Free(path);
1399finish:
1400 if (attr == 0xFFFFFFFF)
1401 /* File does not exist, or cannot read attributes */
1402 return PyBool_FromLong(0);
1403 /* Access is possible if either write access wasn't requested, or
1404 the file isn't read-only. */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001405 return PyBool_FromLong(!(mode & 2) || !(attr & FILE_ATTRIBUTE_READONLY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001406#else
1407 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001408 if (!PyArg_ParseTuple(args, "eti:access",
1409 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001410 return NULL;
1411 Py_BEGIN_ALLOW_THREADS
1412 res = access(path, mode);
1413 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001414 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001415 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001416#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001417}
1418
Guido van Rossumd371ff11999-01-25 16:12:23 +00001419#ifndef F_OK
1420#define F_OK 0
1421#endif
1422#ifndef R_OK
1423#define R_OK 4
1424#endif
1425#ifndef W_OK
1426#define W_OK 2
1427#endif
1428#ifndef X_OK
1429#define X_OK 1
1430#endif
1431
1432#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001433PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001434"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001435Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001436
1437static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001438posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001439{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001440 int id;
1441 char *ret;
1442
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001443 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001444 return NULL;
1445
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001446#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001447 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001448 if (id == 0) {
1449 ret = ttyname();
1450 }
1451 else {
1452 ret = NULL;
1453 }
1454#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001455 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001456#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001457 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001458 return posix_error();
1459 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001460}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001461#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001462
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001463#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001464PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001465"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001466Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001467
1468static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001469posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001470{
1471 char *ret;
1472 char buffer[L_ctermid];
1473
Greg Wardb48bc172000-03-01 21:51:56 +00001474#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001475 ret = ctermid_r(buffer);
1476#else
1477 ret = ctermid(buffer);
1478#endif
1479 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001480 return posix_error();
1481 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001482}
1483#endif
1484
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001485PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001486"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001487Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001488
Barry Warsaw53699e91996-12-10 23:23:01 +00001489static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001490posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001491{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001492#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001493 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001494#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001495 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001496#elif defined(__VMS)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001497 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001498#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001499 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001500#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001501}
1502
Fred Drake4d1e64b2002-04-15 19:40:07 +00001503#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001504PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001505"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001506Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001507opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001508
1509static PyObject *
1510posix_fchdir(PyObject *self, PyObject *fdobj)
1511{
1512 return posix_fildes(fdobj, fchdir);
1513}
1514#endif /* HAVE_FCHDIR */
1515
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001516
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001517PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001518"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001519Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001520
Barry Warsaw53699e91996-12-10 23:23:01 +00001521static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001522posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001523{
Mark Hammondef8b6542001-05-13 08:04:26 +00001524 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001525 int i;
1526 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001527#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001528 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001529 if (unicode_file_names()) {
1530 PyUnicodeObject *po;
1531 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1532 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001533 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1534 if (attr != 0xFFFFFFFF) {
1535 if (i & _S_IWRITE)
1536 attr &= ~FILE_ATTRIBUTE_READONLY;
1537 else
1538 attr |= FILE_ATTRIBUTE_READONLY;
1539 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1540 }
1541 else
1542 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001543 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001544 if (!res)
1545 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001546 PyUnicode_AS_UNICODE(po));
1547 Py_INCREF(Py_None);
1548 return Py_None;
1549 }
1550 /* Drop the argument parsing error as narrow strings
1551 are also valid. */
1552 PyErr_Clear();
1553 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001554 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1555 &path, &i))
1556 return NULL;
1557 Py_BEGIN_ALLOW_THREADS
1558 attr = GetFileAttributesA(path);
1559 if (attr != 0xFFFFFFFF) {
1560 if (i & _S_IWRITE)
1561 attr &= ~FILE_ATTRIBUTE_READONLY;
1562 else
1563 attr |= FILE_ATTRIBUTE_READONLY;
1564 res = SetFileAttributesA(path, attr);
1565 }
1566 else
1567 res = 0;
1568 Py_END_ALLOW_THREADS
1569 if (!res) {
1570 win32_error("chmod", path);
1571 PyMem_Free(path);
1572 return NULL;
1573 }
1574 PyMem_Free(path);
1575 Py_INCREF(Py_None);
1576 return Py_None;
1577#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001578 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001579 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001580 return NULL;
1581 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001582 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001583 Py_END_ALLOW_THREADS
1584 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001585 return posix_error_with_allocated_filename(path);
1586 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001587 Py_INCREF(Py_None);
1588 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001589#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001590}
1591
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001592
Martin v. Löwis244edc82001-10-04 22:44:26 +00001593#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001594PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001595"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001596Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001597
1598static PyObject *
1599posix_chroot(PyObject *self, PyObject *args)
1600{
Thomas Wouters477c8d52006-05-27 19:21:47 +00001601 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001602}
1603#endif
1604
Guido van Rossum21142a01999-01-08 21:05:37 +00001605#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001606PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001607"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001608force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001609
1610static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001611posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001612{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001613 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001614}
1615#endif /* HAVE_FSYNC */
1616
1617#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001618
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001619#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001620extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1621#endif
1622
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001623PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001624"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001625force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001626 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001627
1628static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001629posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001630{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001631 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001632}
1633#endif /* HAVE_FDATASYNC */
1634
1635
Fredrik Lundh10723342000-07-10 16:38:09 +00001636#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001637PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001638"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001639Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001640
Barry Warsaw53699e91996-12-10 23:23:01 +00001641static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001642posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001643{
Mark Hammondef8b6542001-05-13 08:04:26 +00001644 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001645 int uid, gid;
1646 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001647 if (!PyArg_ParseTuple(args, "etii:chown",
1648 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001649 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001650 return NULL;
1651 Py_BEGIN_ALLOW_THREADS
1652 res = chown(path, (uid_t) uid, (gid_t) gid);
1653 Py_END_ALLOW_THREADS
1654 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001655 return posix_error_with_allocated_filename(path);
1656 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001657 Py_INCREF(Py_None);
1658 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001659}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001660#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001661
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001662#ifdef HAVE_LCHOWN
1663PyDoc_STRVAR(posix_lchown__doc__,
1664"lchown(path, uid, gid)\n\n\
1665Change the owner and group id of path to the numeric uid and gid.\n\
1666This function will not follow symbolic links.");
1667
1668static PyObject *
1669posix_lchown(PyObject *self, PyObject *args)
1670{
1671 char *path = NULL;
1672 int uid, gid;
1673 int res;
1674 if (!PyArg_ParseTuple(args, "etii:lchown",
1675 Py_FileSystemDefaultEncoding, &path,
1676 &uid, &gid))
1677 return NULL;
1678 Py_BEGIN_ALLOW_THREADS
1679 res = lchown(path, (uid_t) uid, (gid_t) gid);
1680 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001681 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001682 return posix_error_with_allocated_filename(path);
1683 PyMem_Free(path);
1684 Py_INCREF(Py_None);
1685 return Py_None;
1686}
1687#endif /* HAVE_LCHOWN */
1688
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001689
Guido van Rossum36bc6801995-06-14 22:54:23 +00001690#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001691PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001692"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001693Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001694
Barry Warsaw53699e91996-12-10 23:23:01 +00001695static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001696posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001697{
1698 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001699 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001700
Barry Warsaw53699e91996-12-10 23:23:01 +00001701 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001702#if defined(PYOS_OS2) && defined(PYCC_GCC)
1703 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001704#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001705 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001706#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001707 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001708 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001709 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001710 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001711}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001712
Walter Dörwald3b918c32002-11-21 20:18:46 +00001713#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001714PyDoc_STRVAR(posix_getcwdu__doc__,
1715"getcwdu() -> path\n\n\
1716Return a unicode string representing the current working directory.");
1717
1718static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001719posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001720{
1721 char buf[1026];
1722 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001723
1724#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001725 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001726 if (unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001727 wchar_t wbuf[1026];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001728 wchar_t *wbuf2 = wbuf;
1729 PyObject *resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001730 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001731 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
1732 /* If the buffer is large enough, len does not include the
1733 terminating \0. If the buffer is too small, len includes
1734 the space needed for the terminator. */
1735 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
1736 wbuf2 = malloc(len * sizeof(wchar_t));
1737 if (wbuf2)
1738 len = GetCurrentDirectoryW(len, wbuf2);
1739 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001740 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001741 if (!wbuf2) {
1742 PyErr_NoMemory();
1743 return NULL;
1744 }
1745 if (!len) {
1746 if (wbuf2 != wbuf) free(wbuf2);
1747 return win32_error("getcwdu", NULL);
1748 }
1749 resobj = PyUnicode_FromWideChar(wbuf2, len);
1750 if (wbuf2 != wbuf) free(wbuf2);
1751 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001752 }
1753#endif
1754
1755 Py_BEGIN_ALLOW_THREADS
1756#if defined(PYOS_OS2) && defined(PYCC_GCC)
1757 res = _getcwd2(buf, sizeof buf);
1758#else
1759 res = getcwd(buf, sizeof buf);
1760#endif
1761 Py_END_ALLOW_THREADS
1762 if (res == NULL)
1763 return posix_error();
1764 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1765}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001766#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001767#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001768
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001769
Guido van Rossumb6775db1994-08-01 11:34:53 +00001770#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001771PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001772"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001773Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001774
Barry Warsaw53699e91996-12-10 23:23:01 +00001775static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001776posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001777{
Thomas Wouters477c8d52006-05-27 19:21:47 +00001778 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001779}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001780#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001781
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001782
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001783PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001784"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001785Return a list containing the names of the entries in the directory.\n\
1786\n\
1787 path: path of directory to list\n\
1788\n\
1789The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001790entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001791
Barry Warsaw53699e91996-12-10 23:23:01 +00001792static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001793posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001794{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001795 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001796 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001797#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001798
Barry Warsaw53699e91996-12-10 23:23:01 +00001799 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001800 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001801 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001802 WIN32_FIND_DATA FileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001803 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00001804 char *bufptr = namebuf;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001805 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001806
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001807#ifdef Py_WIN_WIDE_FILENAMES
1808 /* If on wide-character-capable OS see if argument
1809 is Unicode and if so use wide API. */
1810 if (unicode_file_names()) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001811 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001812 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1813 WIN32_FIND_DATAW wFileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001814 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001815 Py_UNICODE wch;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001816 /* Overallocate for \\*.*\0 */
1817 len = PyUnicode_GET_SIZE(po);
1818 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
1819 if (!wnamebuf) {
1820 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001821 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001822 }
1823 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
1824 wch = len > 0 ? wnamebuf[len-1] : '\0';
1825 if (wch != L'/' && wch != L'\\' && wch != L':')
1826 wnamebuf[len++] = L'\\';
1827 wcscpy(wnamebuf + len, L"*.*");
1828 if ((d = PyList_New(0)) == NULL) {
1829 free(wnamebuf);
1830 return NULL;
1831 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001832 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1833 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001834 int error = GetLastError();
1835 if (error == ERROR_FILE_NOT_FOUND) {
1836 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001837 return d;
1838 }
1839 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001840 win32_error_unicode("FindFirstFileW", wnamebuf);
1841 free(wnamebuf);
1842 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001843 }
1844 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001845 /* Skip over . and .. */
1846 if (wcscmp(wFileData.cFileName, L".") != 0 &&
1847 wcscmp(wFileData.cFileName, L"..") != 0) {
1848 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1849 if (v == NULL) {
1850 Py_DECREF(d);
1851 d = NULL;
1852 break;
1853 }
1854 if (PyList_Append(d, v) != 0) {
1855 Py_DECREF(v);
1856 Py_DECREF(d);
1857 d = NULL;
1858 break;
1859 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001860 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001861 }
Georg Brandl622927b2006-03-07 12:48:03 +00001862 Py_BEGIN_ALLOW_THREADS
1863 result = FindNextFileW(hFindFile, &wFileData);
1864 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001865 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
1866 it got to the end of the directory. */
1867 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
1868 Py_DECREF(d);
1869 win32_error_unicode("FindNextFileW", wnamebuf);
1870 FindClose(hFindFile);
1871 free(wnamebuf);
1872 return NULL;
1873 }
Georg Brandl622927b2006-03-07 12:48:03 +00001874 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001875
1876 if (FindClose(hFindFile) == FALSE) {
1877 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001878 win32_error_unicode("FindClose", wnamebuf);
1879 free(wnamebuf);
1880 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001881 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001882 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001883 return d;
1884 }
1885 /* Drop the argument parsing error as narrow strings
1886 are also valid. */
1887 PyErr_Clear();
1888 }
1889#endif
1890
Tim Peters5aa91602002-01-30 05:46:57 +00001891 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001892 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001893 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001894 if (len > 0) {
1895 char ch = namebuf[len-1];
1896 if (ch != SEP && ch != ALTSEP && ch != ':')
1897 namebuf[len++] = '/';
1898 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001899 strcpy(namebuf + len, "*.*");
1900
Barry Warsaw53699e91996-12-10 23:23:01 +00001901 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001902 return NULL;
1903
1904 hFindFile = FindFirstFile(namebuf, &FileData);
1905 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001906 int error = GetLastError();
1907 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001908 return d;
1909 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001910 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001911 }
1912 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001913 /* Skip over . and .. */
1914 if (strcmp(FileData.cFileName, ".") != 0 &&
1915 strcmp(FileData.cFileName, "..") != 0) {
1916 v = PyString_FromString(FileData.cFileName);
1917 if (v == NULL) {
1918 Py_DECREF(d);
1919 d = NULL;
1920 break;
1921 }
1922 if (PyList_Append(d, v) != 0) {
1923 Py_DECREF(v);
1924 Py_DECREF(d);
1925 d = NULL;
1926 break;
1927 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001928 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001929 }
Georg Brandl622927b2006-03-07 12:48:03 +00001930 Py_BEGIN_ALLOW_THREADS
1931 result = FindNextFile(hFindFile, &FileData);
1932 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001933 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
1934 it got to the end of the directory. */
1935 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
1936 Py_DECREF(d);
1937 win32_error("FindNextFile", namebuf);
1938 FindClose(hFindFile);
1939 return NULL;
1940 }
Georg Brandl622927b2006-03-07 12:48:03 +00001941 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001942
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001943 if (FindClose(hFindFile) == FALSE) {
1944 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001945 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001946 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001947
1948 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001949
Tim Peters0bb44a42000-09-15 07:44:49 +00001950#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001951
1952#ifndef MAX_PATH
1953#define MAX_PATH CCHMAXPATH
1954#endif
1955 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00001956 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001957 PyObject *d, *v;
1958 char namebuf[MAX_PATH+5];
1959 HDIR hdir = 1;
1960 ULONG srchcnt = 1;
1961 FILEFINDBUF3 ep;
1962 APIRET rc;
1963
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001964 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001965 return NULL;
1966 if (len >= MAX_PATH) {
1967 PyErr_SetString(PyExc_ValueError, "path too long");
1968 return NULL;
1969 }
1970 strcpy(namebuf, name);
1971 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001972 if (*pt == ALTSEP)
1973 *pt = SEP;
1974 if (namebuf[len-1] != SEP)
1975 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001976 strcpy(namebuf + len, "*.*");
1977
1978 if ((d = PyList_New(0)) == NULL)
1979 return NULL;
1980
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001981 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1982 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001983 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001984 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1985 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1986 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001987
1988 if (rc != NO_ERROR) {
1989 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001990 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001991 }
1992
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001993 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001994 do {
1995 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001996 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001997 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001998
1999 strcpy(namebuf, ep.achName);
2000
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002001 /* Leave Case of Name Alone -- In Native Form */
2002 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002003
2004 v = PyString_FromString(namebuf);
2005 if (v == NULL) {
2006 Py_DECREF(d);
2007 d = NULL;
2008 break;
2009 }
2010 if (PyList_Append(d, v) != 0) {
2011 Py_DECREF(v);
2012 Py_DECREF(d);
2013 d = NULL;
2014 break;
2015 }
2016 Py_DECREF(v);
2017 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2018 }
2019
2020 return d;
2021#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002022
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002023 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002024 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002025 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002026 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002027 int arg_is_unicode = 1;
2028
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002029 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002030 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2031 arg_is_unicode = 0;
2032 PyErr_Clear();
2033 }
2034 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002035 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002036 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002037 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002038 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002039 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002040 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002041 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002042 return NULL;
2043 }
Georg Brandl622927b2006-03-07 12:48:03 +00002044 for (;;) {
2045 Py_BEGIN_ALLOW_THREADS
2046 ep = readdir(dirp);
2047 Py_END_ALLOW_THREADS
2048 if (ep == NULL)
2049 break;
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002050 if (ep->d_name[0] == '.' &&
2051 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002052 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002053 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00002054 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002055 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002056 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002057 d = NULL;
2058 break;
2059 }
Just van Rossum46c97842003-02-25 21:42:15 +00002060#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00002061 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002062 PyObject *w;
2063
2064 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002065 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002066 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002067 if (w != NULL) {
2068 Py_DECREF(v);
2069 v = w;
2070 }
2071 else {
2072 /* fall back to the original byte string, as
2073 discussed in patch #683592 */
2074 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002075 }
Just van Rossum46c97842003-02-25 21:42:15 +00002076 }
2077#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002078 if (PyList_Append(d, v) != 0) {
2079 Py_DECREF(v);
2080 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002081 d = NULL;
2082 break;
2083 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002084 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002085 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002086 if (errno != 0 && d != NULL) {
2087 /* readdir() returned NULL and set errno */
2088 closedir(dirp);
2089 Py_DECREF(d);
2090 return posix_error_with_allocated_filename(name);
2091 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002092 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002093 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002094
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002095 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002096
Tim Peters0bb44a42000-09-15 07:44:49 +00002097#endif /* which OS */
2098} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002099
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002100#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002101/* A helper function for abspath on win32 */
2102static PyObject *
2103posix__getfullpathname(PyObject *self, PyObject *args)
2104{
2105 /* assume encoded strings wont more than double no of chars */
2106 char inbuf[MAX_PATH*2];
2107 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002108 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002109 char outbuf[MAX_PATH*2];
2110 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002111#ifdef Py_WIN_WIDE_FILENAMES
2112 if (unicode_file_names()) {
2113 PyUnicodeObject *po;
2114 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2115 Py_UNICODE woutbuf[MAX_PATH*2];
2116 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00002117 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002118 sizeof(woutbuf)/sizeof(woutbuf[0]),
2119 woutbuf, &wtemp))
2120 return win32_error("GetFullPathName", "");
2121 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
2122 }
2123 /* Drop the argument parsing error as narrow strings
2124 are also valid. */
2125 PyErr_Clear();
2126 }
2127#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002128 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2129 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002130 &insize))
2131 return NULL;
2132 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2133 outbuf, &temp))
2134 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002135 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2136 return PyUnicode_Decode(outbuf, strlen(outbuf),
2137 Py_FileSystemDefaultEncoding, NULL);
2138 }
Mark Hammondef8b6542001-05-13 08:04:26 +00002139 return PyString_FromString(outbuf);
2140} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002141#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002142
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002143PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002144"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002145Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002146
Barry Warsaw53699e91996-12-10 23:23:01 +00002147static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002148posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002149{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002150 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002151 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002152 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002153
2154#ifdef Py_WIN_WIDE_FILENAMES
2155 if (unicode_file_names()) {
2156 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002157 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002158 Py_BEGIN_ALLOW_THREADS
2159 /* PyUnicode_AS_UNICODE OK without thread lock as
2160 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002161 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002162 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002163 if (!res)
2164 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002165 Py_INCREF(Py_None);
2166 return Py_None;
2167 }
2168 /* Drop the argument parsing error as narrow strings
2169 are also valid. */
2170 PyErr_Clear();
2171 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002172 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2173 Py_FileSystemDefaultEncoding, &path, &mode))
2174 return NULL;
2175 Py_BEGIN_ALLOW_THREADS
2176 /* PyUnicode_AS_UNICODE OK without thread lock as
2177 it is a simple dereference. */
2178 res = CreateDirectoryA(path, NULL);
2179 Py_END_ALLOW_THREADS
2180 if (!res) {
2181 win32_error("mkdir", path);
2182 PyMem_Free(path);
2183 return NULL;
2184 }
2185 PyMem_Free(path);
2186 Py_INCREF(Py_None);
2187 return Py_None;
2188#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002189
Tim Peters5aa91602002-01-30 05:46:57 +00002190 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002191 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002192 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002193 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002194#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002195 res = mkdir(path);
2196#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002197 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002198#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002199 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002200 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002201 return posix_error_with_allocated_filename(path);
2202 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002203 Py_INCREF(Py_None);
2204 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002205#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002206}
2207
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002208
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002209/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2210#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002211#include <sys/resource.h>
2212#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002213
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002214
2215#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002216PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002217"nice(inc) -> new_priority\n\n\
2218Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002219
Barry Warsaw53699e91996-12-10 23:23:01 +00002220static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002221posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002222{
2223 int increment, value;
2224
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002225 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002226 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002227
2228 /* There are two flavours of 'nice': one that returns the new
2229 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002230 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2231 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002232
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002233 If we are of the nice family that returns the new priority, we
2234 need to clear errno before the call, and check if errno is filled
2235 before calling posix_error() on a returnvalue of -1, because the
2236 -1 may be the actual new priority! */
2237
2238 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002239 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002240#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002241 if (value == 0)
2242 value = getpriority(PRIO_PROCESS, 0);
2243#endif
2244 if (value == -1 && errno != 0)
2245 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002246 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002247 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002248}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002249#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002250
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002251PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002252"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002253Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002254
Barry Warsaw53699e91996-12-10 23:23:01 +00002255static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002256posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002257{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002258#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002259 PyObject *o1, *o2;
2260 char *p1, *p2;
2261 BOOL result;
2262 if (unicode_file_names()) {
2263 if (!PyArg_ParseTuple(args, "O&O&:rename",
2264 convert_to_unicode, &o1,
2265 convert_to_unicode, &o2))
2266 PyErr_Clear();
2267 else {
2268 Py_BEGIN_ALLOW_THREADS
2269 result = MoveFileW(PyUnicode_AsUnicode(o1),
2270 PyUnicode_AsUnicode(o2));
2271 Py_END_ALLOW_THREADS
2272 Py_DECREF(o1);
2273 Py_DECREF(o2);
2274 if (!result)
2275 return win32_error("rename", NULL);
2276 Py_INCREF(Py_None);
2277 return Py_None;
2278 }
2279 }
2280 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2281 return NULL;
2282 Py_BEGIN_ALLOW_THREADS
2283 result = MoveFileA(p1, p2);
2284 Py_END_ALLOW_THREADS
2285 if (!result)
2286 return win32_error("rename", NULL);
2287 Py_INCREF(Py_None);
2288 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002289#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002290 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002291#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002292}
2293
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002294
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002295PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002296"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002297Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002298
Barry Warsaw53699e91996-12-10 23:23:01 +00002299static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002300posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002301{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002302#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002303 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002304#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002305 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002306#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002307}
2308
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002309
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002310PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002311"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002312Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002313
Barry Warsaw53699e91996-12-10 23:23:01 +00002314static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002315posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002316{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002317#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002318 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002319#else
2320 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2321#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002322}
2323
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002324
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002325#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002326PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002327"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002328Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002329
Barry Warsaw53699e91996-12-10 23:23:01 +00002330static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002331posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002332{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002333 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002334 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002335 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002336 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002337 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002338 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002339 Py_END_ALLOW_THREADS
2340 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002341}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002342#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002343
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002344
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002345PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002346"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002347Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002348
Barry Warsaw53699e91996-12-10 23:23:01 +00002349static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002350posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002351{
2352 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002353 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002354 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002355 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002356 if (i < 0)
2357 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002358 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002359}
2360
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002361
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002362PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002363"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002364Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002365
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002366PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002367"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002368Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002369
Barry Warsaw53699e91996-12-10 23:23:01 +00002370static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002371posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002372{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002373#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002374 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002375#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002376 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002377#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002378}
2379
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002380
Guido van Rossumb6775db1994-08-01 11:34:53 +00002381#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002382PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002383"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002384Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002385
Barry Warsaw53699e91996-12-10 23:23:01 +00002386static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002387posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002388{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002389 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002390 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002391
Barry Warsaw53699e91996-12-10 23:23:01 +00002392 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002393 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002394 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002395 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002396 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002397 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002398 u.sysname,
2399 u.nodename,
2400 u.release,
2401 u.version,
2402 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002403}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002404#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002405
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002406static int
2407extract_time(PyObject *t, long* sec, long* usec)
2408{
2409 long intval;
2410 if (PyFloat_Check(t)) {
2411 double tval = PyFloat_AsDouble(t);
2412 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2413 if (!intobj)
2414 return -1;
2415 intval = PyInt_AsLong(intobj);
2416 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002417 if (intval == -1 && PyErr_Occurred())
2418 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002419 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002420 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002421 if (*usec < 0)
2422 /* If rounding gave us a negative number,
2423 truncate. */
2424 *usec = 0;
2425 return 0;
2426 }
2427 intval = PyInt_AsLong(t);
2428 if (intval == -1 && PyErr_Occurred())
2429 return -1;
2430 *sec = intval;
2431 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002432 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002433}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002434
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002435PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002436"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002437utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002438Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002439second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002440
Barry Warsaw53699e91996-12-10 23:23:01 +00002441static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002442posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002443{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002444#ifdef Py_WIN_WIDE_FILENAMES
2445 PyObject *arg;
2446 PyUnicodeObject *obwpath;
2447 wchar_t *wpath = NULL;
2448 char *apath = NULL;
2449 HANDLE hFile;
2450 long atimesec, mtimesec, ausec, musec;
2451 FILETIME atime, mtime;
2452 PyObject *result = NULL;
2453
2454 if (unicode_file_names()) {
2455 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2456 wpath = PyUnicode_AS_UNICODE(obwpath);
2457 Py_BEGIN_ALLOW_THREADS
2458 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2459 NULL, OPEN_EXISTING, 0, NULL);
2460 Py_END_ALLOW_THREADS
2461 if (hFile == INVALID_HANDLE_VALUE)
2462 return win32_error_unicode("utime", wpath);
2463 } else
2464 /* Drop the argument parsing error as narrow strings
2465 are also valid. */
2466 PyErr_Clear();
2467 }
2468 if (!wpath) {
2469 if (!PyArg_ParseTuple(args, "etO:utime",
2470 Py_FileSystemDefaultEncoding, &apath, &arg))
2471 return NULL;
2472 Py_BEGIN_ALLOW_THREADS
2473 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2474 NULL, OPEN_EXISTING, 0, NULL);
2475 Py_END_ALLOW_THREADS
2476 if (hFile == INVALID_HANDLE_VALUE) {
2477 win32_error("utime", apath);
2478 PyMem_Free(apath);
2479 return NULL;
2480 }
2481 PyMem_Free(apath);
2482 }
2483
2484 if (arg == Py_None) {
2485 SYSTEMTIME now;
2486 GetSystemTime(&now);
2487 if (!SystemTimeToFileTime(&now, &mtime) ||
2488 !SystemTimeToFileTime(&now, &atime)) {
2489 win32_error("utime", NULL);
2490 goto done;
2491 }
2492 }
2493 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2494 PyErr_SetString(PyExc_TypeError,
2495 "utime() arg 2 must be a tuple (atime, mtime)");
2496 goto done;
2497 }
2498 else {
2499 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2500 &atimesec, &ausec) == -1)
2501 goto done;
2502 time_t_to_FILE_TIME(atimesec, ausec, &atime);
2503 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2504 &mtimesec, &musec) == -1)
2505 goto done;
2506 time_t_to_FILE_TIME(mtimesec, musec, &mtime);
2507 }
2508 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2509 /* Avoid putting the file name into the error here,
2510 as that may confuse the user into believing that
2511 something is wrong with the file, when it also
2512 could be the time stamp that gives a problem. */
2513 win32_error("utime", NULL);
2514 }
2515 Py_INCREF(Py_None);
2516 result = Py_None;
2517done:
2518 CloseHandle(hFile);
2519 return result;
2520#else /* Py_WIN_WIDE_FILENAMES */
2521
Neal Norwitz2adf2102004-06-09 01:46:02 +00002522 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002523 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002524 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002525 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002526
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002527#if defined(HAVE_UTIMES)
2528 struct timeval buf[2];
2529#define ATIME buf[0].tv_sec
2530#define MTIME buf[1].tv_sec
2531#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002532/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002533 struct utimbuf buf;
2534#define ATIME buf.actime
2535#define MTIME buf.modtime
2536#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002537#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002538 time_t buf[2];
2539#define ATIME buf[0]
2540#define MTIME buf[1]
2541#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002542#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002543
Mark Hammond817c9292003-12-03 01:22:38 +00002544
Thomas Wouters477c8d52006-05-27 19:21:47 +00002545 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002546 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002547 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002548 if (arg == Py_None) {
2549 /* optional time values not given */
2550 Py_BEGIN_ALLOW_THREADS
2551 res = utime(path, NULL);
2552 Py_END_ALLOW_THREADS
2553 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002554 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002555 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002556 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002557 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002558 return NULL;
2559 }
2560 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002561 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002562 &atime, &ausec) == -1) {
2563 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002564 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002565 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002566 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002567 &mtime, &musec) == -1) {
2568 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002569 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002570 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002571 ATIME = atime;
2572 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002573#ifdef HAVE_UTIMES
2574 buf[0].tv_usec = ausec;
2575 buf[1].tv_usec = musec;
2576 Py_BEGIN_ALLOW_THREADS
2577 res = utimes(path, buf);
2578 Py_END_ALLOW_THREADS
2579#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002580 Py_BEGIN_ALLOW_THREADS
2581 res = utime(path, UTIME_ARG);
2582 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002583#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002584 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002585 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002586 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002587 }
Neal Norwitz96652712004-06-06 20:40:27 +00002588 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002589 Py_INCREF(Py_None);
2590 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002591#undef UTIME_ARG
2592#undef ATIME
2593#undef MTIME
Thomas Wouters477c8d52006-05-27 19:21:47 +00002594#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002595}
2596
Guido van Rossum85e3b011991-06-03 12:42:10 +00002597
Guido van Rossum3b066191991-06-04 19:40:25 +00002598/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002599
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002600PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002601"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002602Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002603
Barry Warsaw53699e91996-12-10 23:23:01 +00002604static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002605posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002606{
2607 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002608 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002609 return NULL;
2610 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002611 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002612}
2613
Martin v. Löwis114619e2002-10-07 06:44:21 +00002614#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2615static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002616free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002617{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002618 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002619 for (i = 0; i < count; i++)
2620 PyMem_Free(array[i]);
2621 PyMem_DEL(array);
2622}
2623#endif
2624
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002625
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002626#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002627PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002628"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002629Execute an executable path with arguments, replacing current process.\n\
2630\n\
2631 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002632 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002633
Barry Warsaw53699e91996-12-10 23:23:01 +00002634static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002635posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002636{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002637 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002638 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002639 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002640 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002641 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002642
Guido van Rossum89b33251993-10-22 14:26:06 +00002643 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002644 argv is a list or tuple of strings. */
2645
Martin v. Löwis114619e2002-10-07 06:44:21 +00002646 if (!PyArg_ParseTuple(args, "etO:execv",
2647 Py_FileSystemDefaultEncoding,
2648 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002649 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002650 if (PyList_Check(argv)) {
2651 argc = PyList_Size(argv);
2652 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002653 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002654 else if (PyTuple_Check(argv)) {
2655 argc = PyTuple_Size(argv);
2656 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002657 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002658 else {
Fred Drake661ea262000-10-24 19:57:45 +00002659 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002660 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002661 return NULL;
2662 }
2663
Barry Warsaw53699e91996-12-10 23:23:01 +00002664 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002665 if (argvlist == NULL) {
2666 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002667 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002668 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002669 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002670 if (!PyArg_Parse((*getitem)(argv, i), "et",
2671 Py_FileSystemDefaultEncoding,
2672 &argvlist[i])) {
2673 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002674 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002675 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002676 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002677 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002678
Guido van Rossum85e3b011991-06-03 12:42:10 +00002679 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002680 }
2681 argvlist[argc] = NULL;
2682
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002683 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002684
Guido van Rossum85e3b011991-06-03 12:42:10 +00002685 /* If we get here it's definitely an error */
2686
Martin v. Löwis114619e2002-10-07 06:44:21 +00002687 free_string_array(argvlist, argc);
2688 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002689 return posix_error();
2690}
2691
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002692
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002693PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002694"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002695Execute a path with arguments and environment, replacing current process.\n\
2696\n\
2697 path: path of executable file\n\
2698 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002699 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002700
Barry Warsaw53699e91996-12-10 23:23:01 +00002701static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002702posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002703{
2704 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002705 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002706 char **argvlist;
2707 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002708 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002709 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002710 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002711 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002712
2713 /* execve has three arguments: (path, argv, env), where
2714 argv is a list or tuple of strings and env is a dictionary
2715 like posix.environ. */
2716
Martin v. Löwis114619e2002-10-07 06:44:21 +00002717 if (!PyArg_ParseTuple(args, "etOO:execve",
2718 Py_FileSystemDefaultEncoding,
2719 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002720 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002721 if (PyList_Check(argv)) {
2722 argc = PyList_Size(argv);
2723 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002724 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002725 else if (PyTuple_Check(argv)) {
2726 argc = PyTuple_Size(argv);
2727 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002728 }
2729 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002730 PyErr_SetString(PyExc_TypeError,
2731 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002732 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002733 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002734 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002735 PyErr_SetString(PyExc_TypeError,
2736 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002737 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002738 }
2739
Barry Warsaw53699e91996-12-10 23:23:01 +00002740 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002741 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002742 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002743 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002744 }
2745 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002746 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002747 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002748 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002749 &argvlist[i]))
2750 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002751 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002752 goto fail_1;
2753 }
2754 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002755 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002756 argvlist[argc] = NULL;
2757
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002758 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002759 if (i < 0)
2760 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002761 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002762 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002763 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002764 goto fail_1;
2765 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002766 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002767 keys = PyMapping_Keys(env);
2768 vals = PyMapping_Values(env);
2769 if (!keys || !vals)
2770 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002771 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2772 PyErr_SetString(PyExc_TypeError,
2773 "execve(): env.keys() or env.values() is not a list");
2774 goto fail_2;
2775 }
Tim Peters5aa91602002-01-30 05:46:57 +00002776
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002777 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002778 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002779 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002780
2781 key = PyList_GetItem(keys, pos);
2782 val = PyList_GetItem(vals, pos);
2783 if (!key || !val)
2784 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002785
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002786 if (!PyArg_Parse(
2787 key,
2788 "s;execve() arg 3 contains a non-string key",
2789 &k) ||
2790 !PyArg_Parse(
2791 val,
2792 "s;execve() arg 3 contains a non-string value",
2793 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002794 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002795 goto fail_2;
2796 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002797
2798#if defined(PYOS_OS2)
2799 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2800 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2801#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002802 len = PyString_Size(key) + PyString_Size(val) + 2;
2803 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002804 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002805 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002806 goto fail_2;
2807 }
Tim Petersc8996f52001-12-03 20:41:00 +00002808 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002809 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002810#if defined(PYOS_OS2)
2811 }
2812#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002813 }
2814 envlist[envc] = 0;
2815
2816 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002817
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002818 /* If we get here it's definitely an error */
2819
2820 (void) posix_error();
2821
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002822 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002823 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002824 PyMem_DEL(envlist[envc]);
2825 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002826 fail_1:
2827 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002828 Py_XDECREF(vals);
2829 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002830 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002831 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002832 return NULL;
2833}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002834#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002835
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002836
Guido van Rossuma1065681999-01-25 23:20:23 +00002837#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002838PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002839"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002840Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002841\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002842 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002843 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002844 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002845
2846static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002847posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002848{
2849 char *path;
2850 PyObject *argv;
2851 char **argvlist;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002852 int mode, i;
2853 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002854 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002855 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00002856
2857 /* spawnv has three arguments: (mode, path, argv), where
2858 argv is a list or tuple of strings. */
2859
Martin v. Löwis114619e2002-10-07 06:44:21 +00002860 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2861 Py_FileSystemDefaultEncoding,
2862 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002863 return NULL;
2864 if (PyList_Check(argv)) {
2865 argc = PyList_Size(argv);
2866 getitem = PyList_GetItem;
2867 }
2868 else if (PyTuple_Check(argv)) {
2869 argc = PyTuple_Size(argv);
2870 getitem = PyTuple_GetItem;
2871 }
2872 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002873 PyErr_SetString(PyExc_TypeError,
2874 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002875 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002876 return NULL;
2877 }
2878
2879 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002880 if (argvlist == NULL) {
2881 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002882 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002883 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002884 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002885 if (!PyArg_Parse((*getitem)(argv, i), "et",
2886 Py_FileSystemDefaultEncoding,
2887 &argvlist[i])) {
2888 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002889 PyErr_SetString(
2890 PyExc_TypeError,
2891 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002892 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002893 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002894 }
2895 }
2896 argvlist[argc] = NULL;
2897
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002898#if defined(PYOS_OS2) && defined(PYCC_GCC)
2899 Py_BEGIN_ALLOW_THREADS
2900 spawnval = spawnv(mode, path, argvlist);
2901 Py_END_ALLOW_THREADS
2902#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002903 if (mode == _OLD_P_OVERLAY)
2904 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002905
Tim Peters25059d32001-12-07 20:35:43 +00002906 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002907 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002908 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002909#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002910
Martin v. Löwis114619e2002-10-07 06:44:21 +00002911 free_string_array(argvlist, argc);
2912 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002913
Fred Drake699f3522000-06-29 21:12:41 +00002914 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002915 return posix_error();
2916 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002917#if SIZEOF_LONG == SIZEOF_VOID_P
2918 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002919#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002920 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002921#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002922}
2923
2924
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002925PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002926"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002927Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002928\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002929 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002930 path: path of executable file\n\
2931 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002932 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002933
2934static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002935posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002936{
2937 char *path;
2938 PyObject *argv, *env;
2939 char **argvlist;
2940 char **envlist;
2941 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002942 int mode, pos, envc;
2943 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00002944 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002945 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002946 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002947
2948 /* spawnve has four arguments: (mode, path, argv, env), where
2949 argv is a list or tuple of strings and env is a dictionary
2950 like posix.environ. */
2951
Martin v. Löwis114619e2002-10-07 06:44:21 +00002952 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2953 Py_FileSystemDefaultEncoding,
2954 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002955 return NULL;
2956 if (PyList_Check(argv)) {
2957 argc = PyList_Size(argv);
2958 getitem = PyList_GetItem;
2959 }
2960 else if (PyTuple_Check(argv)) {
2961 argc = PyTuple_Size(argv);
2962 getitem = PyTuple_GetItem;
2963 }
2964 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002965 PyErr_SetString(PyExc_TypeError,
2966 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002967 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002968 }
2969 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002970 PyErr_SetString(PyExc_TypeError,
2971 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002972 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002973 }
2974
2975 argvlist = PyMem_NEW(char *, argc+1);
2976 if (argvlist == NULL) {
2977 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002978 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002979 }
2980 for (i = 0; i < argc; i++) {
2981 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002982 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002983 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002984 &argvlist[i]))
2985 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002986 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002987 goto fail_1;
2988 }
2989 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002990 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002991 argvlist[argc] = NULL;
2992
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002993 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002994 if (i < 0)
2995 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002996 envlist = PyMem_NEW(char *, i + 1);
2997 if (envlist == NULL) {
2998 PyErr_NoMemory();
2999 goto fail_1;
3000 }
3001 envc = 0;
3002 keys = PyMapping_Keys(env);
3003 vals = PyMapping_Values(env);
3004 if (!keys || !vals)
3005 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003006 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3007 PyErr_SetString(PyExc_TypeError,
3008 "spawnve(): env.keys() or env.values() is not a list");
3009 goto fail_2;
3010 }
Tim Peters5aa91602002-01-30 05:46:57 +00003011
Guido van Rossuma1065681999-01-25 23:20:23 +00003012 for (pos = 0; pos < i; pos++) {
3013 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003014 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003015
3016 key = PyList_GetItem(keys, pos);
3017 val = PyList_GetItem(vals, pos);
3018 if (!key || !val)
3019 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003020
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003021 if (!PyArg_Parse(
3022 key,
3023 "s;spawnve() arg 3 contains a non-string key",
3024 &k) ||
3025 !PyArg_Parse(
3026 val,
3027 "s;spawnve() arg 3 contains a non-string value",
3028 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003029 {
3030 goto fail_2;
3031 }
Tim Petersc8996f52001-12-03 20:41:00 +00003032 len = PyString_Size(key) + PyString_Size(val) + 2;
3033 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003034 if (p == NULL) {
3035 PyErr_NoMemory();
3036 goto fail_2;
3037 }
Tim Petersc8996f52001-12-03 20:41:00 +00003038 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003039 envlist[envc++] = p;
3040 }
3041 envlist[envc] = 0;
3042
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003043#if defined(PYOS_OS2) && defined(PYCC_GCC)
3044 Py_BEGIN_ALLOW_THREADS
3045 spawnval = spawnve(mode, path, argvlist, envlist);
3046 Py_END_ALLOW_THREADS
3047#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003048 if (mode == _OLD_P_OVERLAY)
3049 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003050
3051 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003052 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003053 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003054#endif
Tim Peters25059d32001-12-07 20:35:43 +00003055
Fred Drake699f3522000-06-29 21:12:41 +00003056 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003057 (void) posix_error();
3058 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003059#if SIZEOF_LONG == SIZEOF_VOID_P
3060 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003061#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003062 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003063#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003064
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003065 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003066 while (--envc >= 0)
3067 PyMem_DEL(envlist[envc]);
3068 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003069 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003070 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003071 Py_XDECREF(vals);
3072 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003073 fail_0:
3074 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003075 return res;
3076}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003077
3078/* OS/2 supports spawnvp & spawnvpe natively */
3079#if defined(PYOS_OS2)
3080PyDoc_STRVAR(posix_spawnvp__doc__,
3081"spawnvp(mode, file, args)\n\n\
3082Execute the program 'file' in a new process, using the environment\n\
3083search path to find the file.\n\
3084\n\
3085 mode: mode of process creation\n\
3086 file: executable file name\n\
3087 args: tuple or list of strings");
3088
3089static PyObject *
3090posix_spawnvp(PyObject *self, PyObject *args)
3091{
3092 char *path;
3093 PyObject *argv;
3094 char **argvlist;
3095 int mode, i, argc;
3096 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003097 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003098
3099 /* spawnvp has three arguments: (mode, path, argv), where
3100 argv is a list or tuple of strings. */
3101
3102 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3103 Py_FileSystemDefaultEncoding,
3104 &path, &argv))
3105 return NULL;
3106 if (PyList_Check(argv)) {
3107 argc = PyList_Size(argv);
3108 getitem = PyList_GetItem;
3109 }
3110 else if (PyTuple_Check(argv)) {
3111 argc = PyTuple_Size(argv);
3112 getitem = PyTuple_GetItem;
3113 }
3114 else {
3115 PyErr_SetString(PyExc_TypeError,
3116 "spawnvp() arg 2 must be a tuple or list");
3117 PyMem_Free(path);
3118 return NULL;
3119 }
3120
3121 argvlist = PyMem_NEW(char *, argc+1);
3122 if (argvlist == NULL) {
3123 PyMem_Free(path);
3124 return PyErr_NoMemory();
3125 }
3126 for (i = 0; i < argc; i++) {
3127 if (!PyArg_Parse((*getitem)(argv, i), "et",
3128 Py_FileSystemDefaultEncoding,
3129 &argvlist[i])) {
3130 free_string_array(argvlist, i);
3131 PyErr_SetString(
3132 PyExc_TypeError,
3133 "spawnvp() arg 2 must contain only strings");
3134 PyMem_Free(path);
3135 return NULL;
3136 }
3137 }
3138 argvlist[argc] = NULL;
3139
3140 Py_BEGIN_ALLOW_THREADS
3141#if defined(PYCC_GCC)
3142 spawnval = spawnvp(mode, path, argvlist);
3143#else
3144 spawnval = _spawnvp(mode, path, argvlist);
3145#endif
3146 Py_END_ALLOW_THREADS
3147
3148 free_string_array(argvlist, argc);
3149 PyMem_Free(path);
3150
3151 if (spawnval == -1)
3152 return posix_error();
3153 else
3154 return Py_BuildValue("l", (long) spawnval);
3155}
3156
3157
3158PyDoc_STRVAR(posix_spawnvpe__doc__,
3159"spawnvpe(mode, file, args, env)\n\n\
3160Execute the program 'file' in a new process, using the environment\n\
3161search path to find the file.\n\
3162\n\
3163 mode: mode of process creation\n\
3164 file: executable file name\n\
3165 args: tuple or list of arguments\n\
3166 env: dictionary of strings mapping to strings");
3167
3168static PyObject *
3169posix_spawnvpe(PyObject *self, PyObject *args)
3170{
3171 char *path;
3172 PyObject *argv, *env;
3173 char **argvlist;
3174 char **envlist;
3175 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3176 int mode, i, pos, argc, envc;
3177 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003178 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003179 int lastarg = 0;
3180
3181 /* spawnvpe has four arguments: (mode, path, argv, env), where
3182 argv is a list or tuple of strings and env is a dictionary
3183 like posix.environ. */
3184
3185 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3186 Py_FileSystemDefaultEncoding,
3187 &path, &argv, &env))
3188 return NULL;
3189 if (PyList_Check(argv)) {
3190 argc = PyList_Size(argv);
3191 getitem = PyList_GetItem;
3192 }
3193 else if (PyTuple_Check(argv)) {
3194 argc = PyTuple_Size(argv);
3195 getitem = PyTuple_GetItem;
3196 }
3197 else {
3198 PyErr_SetString(PyExc_TypeError,
3199 "spawnvpe() arg 2 must be a tuple or list");
3200 goto fail_0;
3201 }
3202 if (!PyMapping_Check(env)) {
3203 PyErr_SetString(PyExc_TypeError,
3204 "spawnvpe() arg 3 must be a mapping object");
3205 goto fail_0;
3206 }
3207
3208 argvlist = PyMem_NEW(char *, argc+1);
3209 if (argvlist == NULL) {
3210 PyErr_NoMemory();
3211 goto fail_0;
3212 }
3213 for (i = 0; i < argc; i++) {
3214 if (!PyArg_Parse((*getitem)(argv, i),
3215 "et;spawnvpe() arg 2 must contain only strings",
3216 Py_FileSystemDefaultEncoding,
3217 &argvlist[i]))
3218 {
3219 lastarg = i;
3220 goto fail_1;
3221 }
3222 }
3223 lastarg = argc;
3224 argvlist[argc] = NULL;
3225
3226 i = PyMapping_Size(env);
3227 if (i < 0)
3228 goto fail_1;
3229 envlist = PyMem_NEW(char *, i + 1);
3230 if (envlist == NULL) {
3231 PyErr_NoMemory();
3232 goto fail_1;
3233 }
3234 envc = 0;
3235 keys = PyMapping_Keys(env);
3236 vals = PyMapping_Values(env);
3237 if (!keys || !vals)
3238 goto fail_2;
3239 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3240 PyErr_SetString(PyExc_TypeError,
3241 "spawnvpe(): env.keys() or env.values() is not a list");
3242 goto fail_2;
3243 }
3244
3245 for (pos = 0; pos < i; pos++) {
3246 char *p, *k, *v;
3247 size_t len;
3248
3249 key = PyList_GetItem(keys, pos);
3250 val = PyList_GetItem(vals, pos);
3251 if (!key || !val)
3252 goto fail_2;
3253
3254 if (!PyArg_Parse(
3255 key,
3256 "s;spawnvpe() arg 3 contains a non-string key",
3257 &k) ||
3258 !PyArg_Parse(
3259 val,
3260 "s;spawnvpe() arg 3 contains a non-string value",
3261 &v))
3262 {
3263 goto fail_2;
3264 }
3265 len = PyString_Size(key) + PyString_Size(val) + 2;
3266 p = PyMem_NEW(char, len);
3267 if (p == NULL) {
3268 PyErr_NoMemory();
3269 goto fail_2;
3270 }
3271 PyOS_snprintf(p, len, "%s=%s", k, v);
3272 envlist[envc++] = p;
3273 }
3274 envlist[envc] = 0;
3275
3276 Py_BEGIN_ALLOW_THREADS
3277#if defined(PYCC_GCC)
3278 spawnval = spawnve(mode, path, argvlist, envlist);
3279#else
3280 spawnval = _spawnve(mode, path, argvlist, envlist);
3281#endif
3282 Py_END_ALLOW_THREADS
3283
3284 if (spawnval == -1)
3285 (void) posix_error();
3286 else
3287 res = Py_BuildValue("l", (long) spawnval);
3288
3289 fail_2:
3290 while (--envc >= 0)
3291 PyMem_DEL(envlist[envc]);
3292 PyMem_DEL(envlist);
3293 fail_1:
3294 free_string_array(argvlist, lastarg);
3295 Py_XDECREF(vals);
3296 Py_XDECREF(keys);
3297 fail_0:
3298 PyMem_Free(path);
3299 return res;
3300}
3301#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003302#endif /* HAVE_SPAWNV */
3303
3304
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003305#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003306PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003307"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003308Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3309\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003310Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003311
3312static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003313posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003314{
Neal Norwitze241ce82003-02-17 18:17:05 +00003315 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003316 if (pid == -1)
3317 return posix_error();
3318 PyOS_AfterFork();
3319 return PyInt_FromLong((long)pid);
3320}
3321#endif
3322
3323
Guido van Rossumad0ee831995-03-01 10:34:45 +00003324#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003325PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003326"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003327Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003328Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003329
Barry Warsaw53699e91996-12-10 23:23:01 +00003330static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003331posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003332{
Neal Norwitze241ce82003-02-17 18:17:05 +00003333 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003334 if (pid == -1)
3335 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003336 if (pid == 0)
3337 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003338 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003339}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003340#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003341
Neal Norwitzb59798b2003-03-21 01:43:31 +00003342/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003343/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3344#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003345#define DEV_PTY_FILE "/dev/ptc"
3346#define HAVE_DEV_PTMX
3347#else
3348#define DEV_PTY_FILE "/dev/ptmx"
3349#endif
3350
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003351#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003352#ifdef HAVE_PTY_H
3353#include <pty.h>
3354#else
3355#ifdef HAVE_LIBUTIL_H
3356#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003357#endif /* HAVE_LIBUTIL_H */
3358#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003359#ifdef HAVE_STROPTS_H
3360#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003361#endif
3362#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003363
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003364#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003365PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003366"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003367Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003368
3369static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003370posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003371{
3372 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003373#ifndef HAVE_OPENPTY
3374 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003375#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003376#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003377 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003378#ifdef sun
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003379 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003380#endif
3381#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003382
Thomas Wouters70c21a12000-07-14 14:28:33 +00003383#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003384 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3385 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003386#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003387 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3388 if (slave_name == NULL)
3389 return posix_error();
3390
3391 slave_fd = open(slave_name, O_RDWR);
3392 if (slave_fd < 0)
3393 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003394#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003395 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003396 if (master_fd < 0)
3397 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003398 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003399 /* change permission of slave */
3400 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003401 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003402 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003403 }
3404 /* unlock slave */
3405 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003406 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003407 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003408 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003409 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003410 slave_name = ptsname(master_fd); /* get name of slave */
3411 if (slave_name == NULL)
3412 return posix_error();
3413 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3414 if (slave_fd < 0)
3415 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003416#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003417 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3418 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003419#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003420 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003421#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003422#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003423#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003424
Fred Drake8cef4cf2000-06-28 16:40:38 +00003425 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003426
Fred Drake8cef4cf2000-06-28 16:40:38 +00003427}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003428#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003429
3430#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003431PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003432"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003433Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3434Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003435To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003436
3437static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003438posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003439{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003440 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003441
Fred Drake8cef4cf2000-06-28 16:40:38 +00003442 pid = forkpty(&master_fd, NULL, NULL, NULL);
3443 if (pid == -1)
3444 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003445 if (pid == 0)
3446 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003447 return Py_BuildValue("(ii)", pid, master_fd);
3448}
3449#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003450
Guido van Rossumad0ee831995-03-01 10:34:45 +00003451#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003452PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003453"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003454Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003455
Barry Warsaw53699e91996-12-10 23:23:01 +00003456static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003457posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003458{
Barry Warsaw53699e91996-12-10 23:23:01 +00003459 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003460}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003461#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003462
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003463
Guido van Rossumad0ee831995-03-01 10:34:45 +00003464#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003465PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003466"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003467Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003468
Barry Warsaw53699e91996-12-10 23:23:01 +00003469static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003470posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003471{
Barry Warsaw53699e91996-12-10 23:23:01 +00003472 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003473}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003474#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003475
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003476
Guido van Rossumad0ee831995-03-01 10:34:45 +00003477#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003478PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003479"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003480Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003481
Barry Warsaw53699e91996-12-10 23:23:01 +00003482static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003483posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003484{
Barry Warsaw53699e91996-12-10 23:23:01 +00003485 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003486}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003487#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003488
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003489
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003490PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003491"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003492Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003493
Barry Warsaw53699e91996-12-10 23:23:01 +00003494static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003495posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003496{
Barry Warsaw53699e91996-12-10 23:23:01 +00003497 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003498}
3499
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003500
Fred Drakec9680921999-12-13 16:37:25 +00003501#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003502PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003503"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003504Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003505
3506static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003507posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003508{
3509 PyObject *result = NULL;
3510
Fred Drakec9680921999-12-13 16:37:25 +00003511#ifdef NGROUPS_MAX
3512#define MAX_GROUPS NGROUPS_MAX
3513#else
3514 /* defined to be 16 on Solaris7, so this should be a small number */
3515#define MAX_GROUPS 64
3516#endif
3517 gid_t grouplist[MAX_GROUPS];
3518 int n;
3519
3520 n = getgroups(MAX_GROUPS, grouplist);
3521 if (n < 0)
3522 posix_error();
3523 else {
3524 result = PyList_New(n);
3525 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003526 int i;
3527 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003528 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003529 if (o == NULL) {
3530 Py_DECREF(result);
3531 result = NULL;
3532 break;
3533 }
3534 PyList_SET_ITEM(result, i, o);
3535 }
3536 }
3537 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003538
Fred Drakec9680921999-12-13 16:37:25 +00003539 return result;
3540}
3541#endif
3542
Martin v. Löwis606edc12002-06-13 21:09:11 +00003543#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003544PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003545"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003546Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003547
3548static PyObject *
3549posix_getpgid(PyObject *self, PyObject *args)
3550{
3551 int pid, pgid;
3552 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3553 return NULL;
3554 pgid = getpgid(pid);
3555 if (pgid < 0)
3556 return posix_error();
3557 return PyInt_FromLong((long)pgid);
3558}
3559#endif /* HAVE_GETPGID */
3560
3561
Guido van Rossumb6775db1994-08-01 11:34:53 +00003562#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003563PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003564"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003565Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003566
Barry Warsaw53699e91996-12-10 23:23:01 +00003567static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003568posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003569{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003570#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003571 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003572#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003573 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003574#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003575}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003576#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003577
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003578
Guido van Rossumb6775db1994-08-01 11:34:53 +00003579#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003580PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003581"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003582Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003583
Barry Warsaw53699e91996-12-10 23:23:01 +00003584static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003585posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003586{
Guido van Rossum64933891994-10-20 21:56:42 +00003587#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003588 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003589#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003590 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003591#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003592 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003593 Py_INCREF(Py_None);
3594 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003595}
3596
Guido van Rossumb6775db1994-08-01 11:34:53 +00003597#endif /* HAVE_SETPGRP */
3598
Guido van Rossumad0ee831995-03-01 10:34:45 +00003599#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003600PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003601"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003602Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003603
Barry Warsaw53699e91996-12-10 23:23:01 +00003604static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003605posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003606{
Barry Warsaw53699e91996-12-10 23:23:01 +00003607 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003608}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003609#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003610
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003611
Fred Drake12c6e2d1999-12-14 21:25:03 +00003612#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003613PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003614"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003615Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003616
3617static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003618posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003619{
Neal Norwitze241ce82003-02-17 18:17:05 +00003620 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003621 char *name;
3622 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003623
Fred Drakea30680b2000-12-06 21:24:28 +00003624 errno = 0;
3625 name = getlogin();
3626 if (name == NULL) {
3627 if (errno)
3628 posix_error();
3629 else
3630 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003631 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003632 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003633 else
3634 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003635 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003636
Fred Drake12c6e2d1999-12-14 21:25:03 +00003637 return result;
3638}
3639#endif
3640
Guido van Rossumad0ee831995-03-01 10:34:45 +00003641#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003642PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003643"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003644Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003645
Barry Warsaw53699e91996-12-10 23:23:01 +00003646static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003647posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003648{
Barry Warsaw53699e91996-12-10 23:23:01 +00003649 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003650}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003651#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003652
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003653
Guido van Rossumad0ee831995-03-01 10:34:45 +00003654#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003655PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003656"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003657Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003658
Barry Warsaw53699e91996-12-10 23:23:01 +00003659static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003660posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003661{
3662 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003663 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003664 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003665#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003666 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3667 APIRET rc;
3668 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003669 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003670
3671 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3672 APIRET rc;
3673 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003674 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003675
3676 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003677 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003678#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003679 if (kill(pid, sig) == -1)
3680 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003681#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003682 Py_INCREF(Py_None);
3683 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003684}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003685#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003686
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003687#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003688PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003689"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003690Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003691
3692static PyObject *
3693posix_killpg(PyObject *self, PyObject *args)
3694{
3695 int pgid, sig;
3696 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3697 return NULL;
3698 if (killpg(pgid, sig) == -1)
3699 return posix_error();
3700 Py_INCREF(Py_None);
3701 return Py_None;
3702}
3703#endif
3704
Guido van Rossumc0125471996-06-28 18:55:32 +00003705#ifdef HAVE_PLOCK
3706
3707#ifdef HAVE_SYS_LOCK_H
3708#include <sys/lock.h>
3709#endif
3710
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003711PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003712"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003713Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003714
Barry Warsaw53699e91996-12-10 23:23:01 +00003715static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003716posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003717{
3718 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003719 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003720 return NULL;
3721 if (plock(op) == -1)
3722 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003723 Py_INCREF(Py_None);
3724 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003725}
3726#endif
3727
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003728
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003729#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003730PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003731"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003732Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003733
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003734#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003735#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003736static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003737async_system(const char *command)
3738{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003739 char errormsg[256], args[1024];
3740 RESULTCODES rcodes;
3741 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003742
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003743 char *shell = getenv("COMSPEC");
3744 if (!shell)
3745 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003746
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003747 /* avoid overflowing the argument buffer */
3748 if (strlen(shell) + 3 + strlen(command) >= 1024)
3749 return ERROR_NOT_ENOUGH_MEMORY
3750
3751 args[0] = '\0';
3752 strcat(args, shell);
3753 strcat(args, "/c ");
3754 strcat(args, command);
3755
3756 /* execute asynchronously, inheriting the environment */
3757 rc = DosExecPgm(errormsg,
3758 sizeof(errormsg),
3759 EXEC_ASYNC,
3760 args,
3761 NULL,
3762 &rcodes,
3763 shell);
3764 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003765}
3766
Guido van Rossumd48f2521997-12-05 22:19:34 +00003767static FILE *
3768popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003769{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003770 int oldfd, tgtfd;
3771 HFILE pipeh[2];
3772 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003773
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003774 /* mode determines which of stdin or stdout is reconnected to
3775 * the pipe to the child
3776 */
3777 if (strchr(mode, 'r') != NULL) {
3778 tgt_fd = 1; /* stdout */
3779 } else if (strchr(mode, 'w')) {
3780 tgt_fd = 0; /* stdin */
3781 } else {
3782 *err = ERROR_INVALID_ACCESS;
3783 return NULL;
3784 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003785
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00003786 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003787 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3788 *err = rc;
3789 return NULL;
3790 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003791
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003792 /* prevent other threads accessing stdio */
3793 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003794
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003795 /* reconnect stdio and execute child */
3796 oldfd = dup(tgtfd);
3797 close(tgtfd);
3798 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3799 DosClose(pipeh[tgtfd]);
3800 rc = async_system(command);
3801 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003802
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003803 /* restore stdio */
3804 dup2(oldfd, tgtfd);
3805 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003806
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003807 /* allow other threads access to stdio */
3808 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003809
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003810 /* if execution of child was successful return file stream */
3811 if (rc == NO_ERROR)
3812 return fdopen(pipeh[1 - tgtfd], mode);
3813 else {
3814 DosClose(pipeh[1 - tgtfd]);
3815 *err = rc;
3816 return NULL;
3817 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003818}
3819
3820static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003821posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003822{
3823 char *name;
3824 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003825 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003826 FILE *fp;
3827 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003828 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003829 return NULL;
3830 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003831 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003832 Py_END_ALLOW_THREADS
3833 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003834 return os2_error(err);
3835
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003836 f = PyFile_FromFile(fp, name, mode, fclose);
3837 if (f != NULL)
3838 PyFile_SetBufSize(f, bufsize);
3839 return f;
3840}
3841
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003842#elif defined(PYCC_GCC)
3843
3844/* standard posix version of popen() support */
3845static PyObject *
3846posix_popen(PyObject *self, PyObject *args)
3847{
3848 char *name;
3849 char *mode = "r";
3850 int bufsize = -1;
3851 FILE *fp;
3852 PyObject *f;
3853 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3854 return NULL;
3855 Py_BEGIN_ALLOW_THREADS
3856 fp = popen(name, mode);
3857 Py_END_ALLOW_THREADS
3858 if (fp == NULL)
3859 return posix_error();
3860 f = PyFile_FromFile(fp, name, mode, pclose);
3861 if (f != NULL)
3862 PyFile_SetBufSize(f, bufsize);
3863 return f;
3864}
3865
3866/* fork() under OS/2 has lots'o'warts
3867 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3868 * most of this code is a ripoff of the win32 code, but using the
3869 * capabilities of EMX's C library routines
3870 */
3871
3872/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3873#define POPEN_1 1
3874#define POPEN_2 2
3875#define POPEN_3 3
3876#define POPEN_4 4
3877
3878static PyObject *_PyPopen(char *, int, int, int);
3879static int _PyPclose(FILE *file);
3880
3881/*
3882 * Internal dictionary mapping popen* file pointers to process handles,
3883 * for use when retrieving the process exit code. See _PyPclose() below
3884 * for more information on this dictionary's use.
3885 */
3886static PyObject *_PyPopenProcs = NULL;
3887
3888/* os2emx version of popen2()
3889 *
3890 * The result of this function is a pipe (file) connected to the
3891 * process's stdin, and a pipe connected to the process's stdout.
3892 */
3893
3894static PyObject *
3895os2emx_popen2(PyObject *self, PyObject *args)
3896{
3897 PyObject *f;
3898 int tm=0;
3899
3900 char *cmdstring;
3901 char *mode = "t";
3902 int bufsize = -1;
3903 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3904 return NULL;
3905
3906 if (*mode == 't')
3907 tm = O_TEXT;
3908 else if (*mode != 'b') {
3909 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3910 return NULL;
3911 } else
3912 tm = O_BINARY;
3913
3914 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3915
3916 return f;
3917}
3918
3919/*
3920 * Variation on os2emx.popen2
3921 *
3922 * The result of this function is 3 pipes - the process's stdin,
3923 * stdout and stderr
3924 */
3925
3926static PyObject *
3927os2emx_popen3(PyObject *self, PyObject *args)
3928{
3929 PyObject *f;
3930 int tm = 0;
3931
3932 char *cmdstring;
3933 char *mode = "t";
3934 int bufsize = -1;
3935 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3936 return NULL;
3937
3938 if (*mode == 't')
3939 tm = O_TEXT;
3940 else if (*mode != 'b') {
3941 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3942 return NULL;
3943 } else
3944 tm = O_BINARY;
3945
3946 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3947
3948 return f;
3949}
3950
3951/*
3952 * Variation on os2emx.popen2
3953 *
Tim Peters11b23062003-04-23 02:39:17 +00003954 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003955 * and stdout+stderr combined as a single pipe.
3956 */
3957
3958static PyObject *
3959os2emx_popen4(PyObject *self, PyObject *args)
3960{
3961 PyObject *f;
3962 int tm = 0;
3963
3964 char *cmdstring;
3965 char *mode = "t";
3966 int bufsize = -1;
3967 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3968 return NULL;
3969
3970 if (*mode == 't')
3971 tm = O_TEXT;
3972 else if (*mode != 'b') {
3973 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3974 return NULL;
3975 } else
3976 tm = O_BINARY;
3977
3978 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3979
3980 return f;
3981}
3982
3983/* a couple of structures for convenient handling of multiple
3984 * file handles and pipes
3985 */
3986struct file_ref
3987{
3988 int handle;
3989 int flags;
3990};
3991
3992struct pipe_ref
3993{
3994 int rd;
3995 int wr;
3996};
3997
3998/* The following code is derived from the win32 code */
3999
4000static PyObject *
4001_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4002{
4003 struct file_ref stdio[3];
4004 struct pipe_ref p_fd[3];
4005 FILE *p_s[3];
4006 int file_count, i, pipe_err, pipe_pid;
4007 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4008 PyObject *f, *p_f[3];
4009
4010 /* file modes for subsequent fdopen's on pipe handles */
4011 if (mode == O_TEXT)
4012 {
4013 rd_mode = "rt";
4014 wr_mode = "wt";
4015 }
4016 else
4017 {
4018 rd_mode = "rb";
4019 wr_mode = "wb";
4020 }
4021
4022 /* prepare shell references */
4023 if ((shell = getenv("EMXSHELL")) == NULL)
4024 if ((shell = getenv("COMSPEC")) == NULL)
4025 {
4026 errno = ENOENT;
4027 return posix_error();
4028 }
4029
4030 sh_name = _getname(shell);
4031 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4032 opt = "/c";
4033 else
4034 opt = "-c";
4035
4036 /* save current stdio fds + their flags, and set not inheritable */
4037 i = pipe_err = 0;
4038 while (pipe_err >= 0 && i < 3)
4039 {
4040 pipe_err = stdio[i].handle = dup(i);
4041 stdio[i].flags = fcntl(i, F_GETFD, 0);
4042 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4043 i++;
4044 }
4045 if (pipe_err < 0)
4046 {
4047 /* didn't get them all saved - clean up and bail out */
4048 int saved_err = errno;
4049 while (i-- > 0)
4050 {
4051 close(stdio[i].handle);
4052 }
4053 errno = saved_err;
4054 return posix_error();
4055 }
4056
4057 /* create pipe ends */
4058 file_count = 2;
4059 if (n == POPEN_3)
4060 file_count = 3;
4061 i = pipe_err = 0;
4062 while ((pipe_err == 0) && (i < file_count))
4063 pipe_err = pipe((int *)&p_fd[i++]);
4064 if (pipe_err < 0)
4065 {
4066 /* didn't get them all made - clean up and bail out */
4067 while (i-- > 0)
4068 {
4069 close(p_fd[i].wr);
4070 close(p_fd[i].rd);
4071 }
4072 errno = EPIPE;
4073 return posix_error();
4074 }
4075
4076 /* change the actual standard IO streams over temporarily,
4077 * making the retained pipe ends non-inheritable
4078 */
4079 pipe_err = 0;
4080
4081 /* - stdin */
4082 if (dup2(p_fd[0].rd, 0) == 0)
4083 {
4084 close(p_fd[0].rd);
4085 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4086 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4087 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4088 {
4089 close(p_fd[0].wr);
4090 pipe_err = -1;
4091 }
4092 }
4093 else
4094 {
4095 pipe_err = -1;
4096 }
4097
4098 /* - stdout */
4099 if (pipe_err == 0)
4100 {
4101 if (dup2(p_fd[1].wr, 1) == 1)
4102 {
4103 close(p_fd[1].wr);
4104 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4105 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4106 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4107 {
4108 close(p_fd[1].rd);
4109 pipe_err = -1;
4110 }
4111 }
4112 else
4113 {
4114 pipe_err = -1;
4115 }
4116 }
4117
4118 /* - stderr, as required */
4119 if (pipe_err == 0)
4120 switch (n)
4121 {
4122 case POPEN_3:
4123 {
4124 if (dup2(p_fd[2].wr, 2) == 2)
4125 {
4126 close(p_fd[2].wr);
4127 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4128 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4129 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4130 {
4131 close(p_fd[2].rd);
4132 pipe_err = -1;
4133 }
4134 }
4135 else
4136 {
4137 pipe_err = -1;
4138 }
4139 break;
4140 }
4141
4142 case POPEN_4:
4143 {
4144 if (dup2(1, 2) != 2)
4145 {
4146 pipe_err = -1;
4147 }
4148 break;
4149 }
4150 }
4151
4152 /* spawn the child process */
4153 if (pipe_err == 0)
4154 {
4155 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4156 if (pipe_pid == -1)
4157 {
4158 pipe_err = -1;
4159 }
4160 else
4161 {
4162 /* save the PID into the FILE structure
4163 * NOTE: this implementation doesn't actually
4164 * take advantage of this, but do it for
4165 * completeness - AIM Apr01
4166 */
4167 for (i = 0; i < file_count; i++)
4168 p_s[i]->_pid = pipe_pid;
4169 }
4170 }
4171
4172 /* reset standard IO to normal */
4173 for (i = 0; i < 3; i++)
4174 {
4175 dup2(stdio[i].handle, i);
4176 fcntl(i, F_SETFD, stdio[i].flags);
4177 close(stdio[i].handle);
4178 }
4179
4180 /* if any remnant problems, clean up and bail out */
4181 if (pipe_err < 0)
4182 {
4183 for (i = 0; i < 3; i++)
4184 {
4185 close(p_fd[i].rd);
4186 close(p_fd[i].wr);
4187 }
4188 errno = EPIPE;
4189 return posix_error_with_filename(cmdstring);
4190 }
4191
4192 /* build tuple of file objects to return */
4193 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4194 PyFile_SetBufSize(p_f[0], bufsize);
4195 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4196 PyFile_SetBufSize(p_f[1], bufsize);
4197 if (n == POPEN_3)
4198 {
4199 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4200 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004201 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004202 }
4203 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004204 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004205
4206 /*
4207 * Insert the files we've created into the process dictionary
4208 * all referencing the list with the process handle and the
4209 * initial number of files (see description below in _PyPclose).
4210 * Since if _PyPclose later tried to wait on a process when all
4211 * handles weren't closed, it could create a deadlock with the
4212 * child, we spend some energy here to try to ensure that we
4213 * either insert all file handles into the dictionary or none
4214 * at all. It's a little clumsy with the various popen modes
4215 * and variable number of files involved.
4216 */
4217 if (!_PyPopenProcs)
4218 {
4219 _PyPopenProcs = PyDict_New();
4220 }
4221
4222 if (_PyPopenProcs)
4223 {
4224 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4225 int ins_rc[3];
4226
4227 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4228 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4229
4230 procObj = PyList_New(2);
4231 pidObj = PyInt_FromLong((long) pipe_pid);
4232 intObj = PyInt_FromLong((long) file_count);
4233
4234 if (procObj && pidObj && intObj)
4235 {
4236 PyList_SetItem(procObj, 0, pidObj);
4237 PyList_SetItem(procObj, 1, intObj);
4238
4239 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4240 if (fileObj[0])
4241 {
4242 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4243 fileObj[0],
4244 procObj);
4245 }
4246 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4247 if (fileObj[1])
4248 {
4249 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4250 fileObj[1],
4251 procObj);
4252 }
4253 if (file_count >= 3)
4254 {
4255 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4256 if (fileObj[2])
4257 {
4258 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4259 fileObj[2],
4260 procObj);
4261 }
4262 }
4263
4264 if (ins_rc[0] < 0 || !fileObj[0] ||
4265 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4266 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4267 {
4268 /* Something failed - remove any dictionary
4269 * entries that did make it.
4270 */
4271 if (!ins_rc[0] && fileObj[0])
4272 {
4273 PyDict_DelItem(_PyPopenProcs,
4274 fileObj[0]);
4275 }
4276 if (!ins_rc[1] && fileObj[1])
4277 {
4278 PyDict_DelItem(_PyPopenProcs,
4279 fileObj[1]);
4280 }
4281 if (!ins_rc[2] && fileObj[2])
4282 {
4283 PyDict_DelItem(_PyPopenProcs,
4284 fileObj[2]);
4285 }
4286 }
4287 }
Tim Peters11b23062003-04-23 02:39:17 +00004288
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004289 /*
4290 * Clean up our localized references for the dictionary keys
4291 * and value since PyDict_SetItem will Py_INCREF any copies
4292 * that got placed in the dictionary.
4293 */
4294 Py_XDECREF(procObj);
4295 Py_XDECREF(fileObj[0]);
4296 Py_XDECREF(fileObj[1]);
4297 Py_XDECREF(fileObj[2]);
4298 }
4299
4300 /* Child is launched. */
4301 return f;
4302}
4303
4304/*
4305 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4306 * exit code for the child process and return as a result of the close.
4307 *
4308 * This function uses the _PyPopenProcs dictionary in order to map the
4309 * input file pointer to information about the process that was
4310 * originally created by the popen* call that created the file pointer.
4311 * The dictionary uses the file pointer as a key (with one entry
4312 * inserted for each file returned by the original popen* call) and a
4313 * single list object as the value for all files from a single call.
4314 * The list object contains the Win32 process handle at [0], and a file
4315 * count at [1], which is initialized to the total number of file
4316 * handles using that list.
4317 *
4318 * This function closes whichever handle it is passed, and decrements
4319 * the file count in the dictionary for the process handle pointed to
4320 * by this file. On the last close (when the file count reaches zero),
4321 * this function will wait for the child process and then return its
4322 * exit code as the result of the close() operation. This permits the
4323 * files to be closed in any order - it is always the close() of the
4324 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004325 *
4326 * NOTE: This function is currently called with the GIL released.
4327 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004328 */
4329
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004330static int _PyPclose(FILE *file)
4331{
4332 int result;
4333 int exit_code;
4334 int pipe_pid;
4335 PyObject *procObj, *pidObj, *intObj, *fileObj;
4336 int file_count;
4337#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004338 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004339#endif
4340
4341 /* Close the file handle first, to ensure it can't block the
4342 * child from exiting if it's the last handle.
4343 */
4344 result = fclose(file);
4345
4346#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004347 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004348#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004349 if (_PyPopenProcs)
4350 {
4351 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4352 (procObj = PyDict_GetItem(_PyPopenProcs,
4353 fileObj)) != NULL &&
4354 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4355 (intObj = PyList_GetItem(procObj,1)) != NULL)
4356 {
4357 pipe_pid = (int) PyInt_AsLong(pidObj);
4358 file_count = (int) PyInt_AsLong(intObj);
4359
4360 if (file_count > 1)
4361 {
4362 /* Still other files referencing process */
4363 file_count--;
4364 PyList_SetItem(procObj,1,
4365 PyInt_FromLong((long) file_count));
4366 }
4367 else
4368 {
4369 /* Last file for this process */
4370 if (result != EOF &&
4371 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4372 {
4373 /* extract exit status */
4374 if (WIFEXITED(exit_code))
4375 {
4376 result = WEXITSTATUS(exit_code);
4377 }
4378 else
4379 {
4380 errno = EPIPE;
4381 result = -1;
4382 }
4383 }
4384 else
4385 {
4386 /* Indicate failure - this will cause the file object
4387 * to raise an I/O error and translate the last
4388 * error code from errno. We do have a problem with
4389 * last errors that overlap the normal errno table,
4390 * but that's a consistent problem with the file object.
4391 */
4392 result = -1;
4393 }
4394 }
4395
4396 /* Remove this file pointer from dictionary */
4397 PyDict_DelItem(_PyPopenProcs, fileObj);
4398
4399 if (PyDict_Size(_PyPopenProcs) == 0)
4400 {
4401 Py_DECREF(_PyPopenProcs);
4402 _PyPopenProcs = NULL;
4403 }
4404
4405 } /* if object retrieval ok */
4406
4407 Py_XDECREF(fileObj);
4408 } /* if _PyPopenProcs */
4409
4410#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004411 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004412#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004413 return result;
4414}
4415
4416#endif /* PYCC_??? */
4417
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004418#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004419
4420/*
4421 * Portable 'popen' replacement for Win32.
4422 *
4423 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4424 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004425 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004426 */
4427
4428#include <malloc.h>
4429#include <io.h>
4430#include <fcntl.h>
4431
4432/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4433#define POPEN_1 1
4434#define POPEN_2 2
4435#define POPEN_3 3
4436#define POPEN_4 4
4437
4438static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004439static int _PyPclose(FILE *file);
4440
4441/*
4442 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004443 * for use when retrieving the process exit code. See _PyPclose() below
4444 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004445 */
4446static PyObject *_PyPopenProcs = NULL;
4447
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004448
4449/* popen that works from a GUI.
4450 *
4451 * The result of this function is a pipe (file) connected to the
4452 * processes stdin or stdout, depending on the requested mode.
4453 */
4454
4455static PyObject *
4456posix_popen(PyObject *self, PyObject *args)
4457{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004458 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004459 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004460
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004461 char *cmdstring;
4462 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004463 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004464 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004465 return NULL;
4466
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004467 if (*mode == 'r')
4468 tm = _O_RDONLY;
4469 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004470 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004471 return NULL;
4472 } else
4473 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004474
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004475 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004476 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004477 return NULL;
4478 }
4479
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004480 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004481 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004482 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004483 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004484 else
4485 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4486
4487 return f;
4488}
4489
4490/* Variation on win32pipe.popen
4491 *
4492 * The result of this function is a pipe (file) connected to the
4493 * process's stdin, and a pipe connected to the process's stdout.
4494 */
4495
4496static PyObject *
4497win32_popen2(PyObject *self, PyObject *args)
4498{
4499 PyObject *f;
4500 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004501
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004502 char *cmdstring;
4503 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004504 int bufsize = -1;
4505 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004506 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004507
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004508 if (*mode == 't')
4509 tm = _O_TEXT;
4510 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004511 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004512 return NULL;
4513 } else
4514 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004515
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004516 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004517 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004518 return NULL;
4519 }
4520
4521 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004522
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004523 return f;
4524}
4525
4526/*
4527 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004528 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004529 * The result of this function is 3 pipes - the process's stdin,
4530 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004531 */
4532
4533static PyObject *
4534win32_popen3(PyObject *self, PyObject *args)
4535{
4536 PyObject *f;
4537 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004538
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004539 char *cmdstring;
4540 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004541 int bufsize = -1;
4542 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004543 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004544
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004545 if (*mode == 't')
4546 tm = _O_TEXT;
4547 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004548 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004549 return NULL;
4550 } else
4551 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004552
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004553 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004554 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004555 return NULL;
4556 }
4557
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004558 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004559
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004560 return f;
4561}
4562
4563/*
4564 * Variation on win32pipe.popen
4565 *
Tim Peters5aa91602002-01-30 05:46:57 +00004566 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004567 * and stdout+stderr combined as a single pipe.
4568 */
4569
4570static PyObject *
4571win32_popen4(PyObject *self, PyObject *args)
4572{
4573 PyObject *f;
4574 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004575
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004576 char *cmdstring;
4577 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004578 int bufsize = -1;
4579 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004580 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004581
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004582 if (*mode == 't')
4583 tm = _O_TEXT;
4584 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004585 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004586 return NULL;
4587 } else
4588 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004589
4590 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004591 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004592 return NULL;
4593 }
4594
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004595 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004596
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004597 return f;
4598}
4599
Mark Hammond08501372001-01-31 07:30:29 +00004600static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004601_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004602 HANDLE hStdin,
4603 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004604 HANDLE hStderr,
4605 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004606{
4607 PROCESS_INFORMATION piProcInfo;
4608 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004609 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004610 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004611 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004612 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004613 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004614
4615 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004616 char *comshell;
4617
Tim Peters92e4dd82002-10-05 01:47:34 +00004618 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004619 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004620 /* x < i, so x fits into an integer */
4621 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004622
4623 /* Explicitly check if we are using COMMAND.COM. If we are
4624 * then use the w9xpopen hack.
4625 */
4626 comshell = s1 + x;
4627 while (comshell >= s1 && *comshell != '\\')
4628 --comshell;
4629 ++comshell;
4630
4631 if (GetVersion() < 0x80000000 &&
4632 _stricmp(comshell, "command.com") != 0) {
4633 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004634 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004635 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004636 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004637 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004638 }
4639 else {
4640 /*
Tim Peters402d5982001-08-27 06:37:48 +00004641 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4642 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004643 */
Mark Hammond08501372001-01-31 07:30:29 +00004644 char modulepath[_MAX_PATH];
4645 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004646 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Thomas Wouters477c8d52006-05-27 19:21:47 +00004647 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004648 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004649 x = i+1;
4650 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004651 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004652 strncat(modulepath,
4653 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004654 (sizeof(modulepath)/sizeof(modulepath[0]))
4655 -strlen(modulepath));
4656 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004657 /* Eeek - file-not-found - possibly an embedding
4658 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004659 */
Tim Peters5aa91602002-01-30 05:46:57 +00004660 strncpy(modulepath,
4661 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004662 sizeof(modulepath)/sizeof(modulepath[0]));
4663 if (modulepath[strlen(modulepath)-1] != '\\')
4664 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004665 strncat(modulepath,
4666 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004667 (sizeof(modulepath)/sizeof(modulepath[0]))
4668 -strlen(modulepath));
4669 /* No where else to look - raise an easily identifiable
4670 error, rather than leaving Windows to report
4671 "file not found" - as the user is probably blissfully
4672 unaware this shim EXE is used, and it will confuse them.
4673 (well, it confused me for a while ;-)
4674 */
4675 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004676 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004677 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004678 "for popen to work with your shell "
4679 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004680 szConsoleSpawn);
4681 return FALSE;
4682 }
4683 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004684 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004685 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004686 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004687
Tim Peters92e4dd82002-10-05 01:47:34 +00004688 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004689 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004690 /* To maintain correct argument passing semantics,
4691 we pass the command-line as it stands, and allow
4692 quoting to be applied. w9xpopen.exe will then
4693 use its argv vector, and re-quote the necessary
4694 args for the ultimate child process.
4695 */
Tim Peters75cdad52001-11-28 22:07:30 +00004696 PyOS_snprintf(
4697 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004698 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004699 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004700 s1,
4701 s3,
4702 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004703 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004704 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004705 dialog:
4706 "Your program accessed mem currently in use at xxx"
4707 and a hopeful warning about the stability of your
4708 system.
4709 Cost is Ctrl+C wont kill children, but anyone
4710 who cares can have a go!
4711 */
4712 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004713 }
4714 }
4715
4716 /* Could be an else here to try cmd.exe / command.com in the path
4717 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004718 else {
Tim Peters402d5982001-08-27 06:37:48 +00004719 PyErr_SetString(PyExc_RuntimeError,
4720 "Cannot locate a COMSPEC environment variable to "
4721 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004722 return FALSE;
4723 }
Tim Peters5aa91602002-01-30 05:46:57 +00004724
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004725 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4726 siStartInfo.cb = sizeof(STARTUPINFO);
4727 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4728 siStartInfo.hStdInput = hStdin;
4729 siStartInfo.hStdOutput = hStdout;
4730 siStartInfo.hStdError = hStderr;
4731 siStartInfo.wShowWindow = SW_HIDE;
4732
4733 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004734 s2,
4735 NULL,
4736 NULL,
4737 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004738 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004739 NULL,
4740 NULL,
4741 &siStartInfo,
4742 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004743 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004744 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004745
Mark Hammondb37a3732000-08-14 04:47:33 +00004746 /* Return process handle */
4747 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004748 return TRUE;
4749 }
Tim Peters402d5982001-08-27 06:37:48 +00004750 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004751 return FALSE;
4752}
4753
4754/* The following code is based off of KB: Q190351 */
4755
4756static PyObject *
4757_PyPopen(char *cmdstring, int mode, int n)
4758{
4759 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4760 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004761 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004762
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004763 SECURITY_ATTRIBUTES saAttr;
4764 BOOL fSuccess;
4765 int fd1, fd2, fd3;
4766 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004767 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004768 PyObject *f;
4769
4770 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4771 saAttr.bInheritHandle = TRUE;
4772 saAttr.lpSecurityDescriptor = NULL;
4773
4774 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4775 return win32_error("CreatePipe", NULL);
4776
4777 /* Create new output read handle and the input write handle. Set
4778 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004779 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004780 * being created. */
4781 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004782 GetCurrentProcess(), &hChildStdinWrDup, 0,
4783 FALSE,
4784 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004785 if (!fSuccess)
4786 return win32_error("DuplicateHandle", NULL);
4787
4788 /* Close the inheritable version of ChildStdin
4789 that we're using. */
4790 CloseHandle(hChildStdinWr);
4791
4792 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4793 return win32_error("CreatePipe", NULL);
4794
4795 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004796 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4797 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004798 if (!fSuccess)
4799 return win32_error("DuplicateHandle", NULL);
4800
4801 /* Close the inheritable version of ChildStdout
4802 that we're using. */
4803 CloseHandle(hChildStdoutRd);
4804
4805 if (n != POPEN_4) {
4806 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4807 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004808 fSuccess = DuplicateHandle(GetCurrentProcess(),
4809 hChildStderrRd,
4810 GetCurrentProcess(),
4811 &hChildStderrRdDup, 0,
4812 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004813 if (!fSuccess)
4814 return win32_error("DuplicateHandle", NULL);
4815 /* Close the inheritable version of ChildStdErr that we're using. */
4816 CloseHandle(hChildStderrRd);
4817 }
Tim Peters5aa91602002-01-30 05:46:57 +00004818
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004819 switch (n) {
4820 case POPEN_1:
4821 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4822 case _O_WRONLY | _O_TEXT:
4823 /* Case for writing to child Stdin in text mode. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00004824 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004825 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004826 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004827 PyFile_SetBufSize(f, 0);
4828 /* We don't care about these pipes anymore, so close them. */
4829 CloseHandle(hChildStdoutRdDup);
4830 CloseHandle(hChildStderrRdDup);
4831 break;
4832
4833 case _O_RDONLY | _O_TEXT:
4834 /* Case for reading from child Stdout in text mode. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00004835 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004836 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004837 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004838 PyFile_SetBufSize(f, 0);
4839 /* We don't care about these pipes anymore, so close them. */
4840 CloseHandle(hChildStdinWrDup);
4841 CloseHandle(hChildStderrRdDup);
4842 break;
4843
4844 case _O_RDONLY | _O_BINARY:
4845 /* Case for readinig from child Stdout in binary mode. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00004846 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004847 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004848 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004849 PyFile_SetBufSize(f, 0);
4850 /* We don't care about these pipes anymore, so close them. */
4851 CloseHandle(hChildStdinWrDup);
4852 CloseHandle(hChildStderrRdDup);
4853 break;
4854
4855 case _O_WRONLY | _O_BINARY:
4856 /* Case for writing to child Stdin in binary mode. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00004857 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004858 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004859 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004860 PyFile_SetBufSize(f, 0);
4861 /* We don't care about these pipes anymore, so close them. */
4862 CloseHandle(hChildStdoutRdDup);
4863 CloseHandle(hChildStderrRdDup);
4864 break;
4865 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004866 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004867 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004868
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004869 case POPEN_2:
4870 case POPEN_4:
4871 {
4872 char *m1, *m2;
4873 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004874
Tim Peters7dca21e2002-08-19 00:42:29 +00004875 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004876 m1 = "r";
4877 m2 = "w";
4878 } else {
4879 m1 = "rb";
4880 m2 = "wb";
4881 }
4882
Thomas Wouters477c8d52006-05-27 19:21:47 +00004883 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004884 f1 = _fdopen(fd1, m2);
Thomas Wouters477c8d52006-05-27 19:21:47 +00004885 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004886 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004887 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004888 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004889 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004890 PyFile_SetBufSize(p2, 0);
4891
4892 if (n != 4)
4893 CloseHandle(hChildStderrRdDup);
4894
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004895 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004896 Py_XDECREF(p1);
4897 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004898 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004899 break;
4900 }
Tim Peters5aa91602002-01-30 05:46:57 +00004901
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004902 case POPEN_3:
4903 {
4904 char *m1, *m2;
4905 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004906
Tim Peters7dca21e2002-08-19 00:42:29 +00004907 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004908 m1 = "r";
4909 m2 = "w";
4910 } else {
4911 m1 = "rb";
4912 m2 = "wb";
4913 }
4914
Thomas Wouters477c8d52006-05-27 19:21:47 +00004915 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004916 f1 = _fdopen(fd1, m2);
Thomas Wouters477c8d52006-05-27 19:21:47 +00004917 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004918 f2 = _fdopen(fd2, m1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00004919 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004920 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004921 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004922 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4923 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004924 PyFile_SetBufSize(p1, 0);
4925 PyFile_SetBufSize(p2, 0);
4926 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004927 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004928 Py_XDECREF(p1);
4929 Py_XDECREF(p2);
4930 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004931 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004932 break;
4933 }
4934 }
4935
4936 if (n == POPEN_4) {
4937 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004938 hChildStdinRd,
4939 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004940 hChildStdoutWr,
4941 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004942 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004943 }
4944 else {
4945 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004946 hChildStdinRd,
4947 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004948 hChildStderrWr,
4949 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004950 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004951 }
4952
Mark Hammondb37a3732000-08-14 04:47:33 +00004953 /*
4954 * Insert the files we've created into the process dictionary
4955 * all referencing the list with the process handle and the
4956 * initial number of files (see description below in _PyPclose).
4957 * Since if _PyPclose later tried to wait on a process when all
4958 * handles weren't closed, it could create a deadlock with the
4959 * child, we spend some energy here to try to ensure that we
4960 * either insert all file handles into the dictionary or none
4961 * at all. It's a little clumsy with the various popen modes
4962 * and variable number of files involved.
4963 */
4964 if (!_PyPopenProcs) {
4965 _PyPopenProcs = PyDict_New();
4966 }
4967
4968 if (_PyPopenProcs) {
4969 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4970 int ins_rc[3];
4971
4972 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4973 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4974
4975 procObj = PyList_New(2);
4976 hProcessObj = PyLong_FromVoidPtr(hProcess);
4977 intObj = PyInt_FromLong(file_count);
4978
4979 if (procObj && hProcessObj && intObj) {
4980 PyList_SetItem(procObj,0,hProcessObj);
4981 PyList_SetItem(procObj,1,intObj);
4982
4983 fileObj[0] = PyLong_FromVoidPtr(f1);
4984 if (fileObj[0]) {
4985 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4986 fileObj[0],
4987 procObj);
4988 }
4989 if (file_count >= 2) {
4990 fileObj[1] = PyLong_FromVoidPtr(f2);
4991 if (fileObj[1]) {
4992 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4993 fileObj[1],
4994 procObj);
4995 }
4996 }
4997 if (file_count >= 3) {
4998 fileObj[2] = PyLong_FromVoidPtr(f3);
4999 if (fileObj[2]) {
5000 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5001 fileObj[2],
5002 procObj);
5003 }
5004 }
5005
5006 if (ins_rc[0] < 0 || !fileObj[0] ||
5007 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5008 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5009 /* Something failed - remove any dictionary
5010 * entries that did make it.
5011 */
5012 if (!ins_rc[0] && fileObj[0]) {
5013 PyDict_DelItem(_PyPopenProcs,
5014 fileObj[0]);
5015 }
5016 if (!ins_rc[1] && fileObj[1]) {
5017 PyDict_DelItem(_PyPopenProcs,
5018 fileObj[1]);
5019 }
5020 if (!ins_rc[2] && fileObj[2]) {
5021 PyDict_DelItem(_PyPopenProcs,
5022 fileObj[2]);
5023 }
5024 }
5025 }
Tim Peters5aa91602002-01-30 05:46:57 +00005026
Mark Hammondb37a3732000-08-14 04:47:33 +00005027 /*
5028 * Clean up our localized references for the dictionary keys
5029 * and value since PyDict_SetItem will Py_INCREF any copies
5030 * that got placed in the dictionary.
5031 */
5032 Py_XDECREF(procObj);
5033 Py_XDECREF(fileObj[0]);
5034 Py_XDECREF(fileObj[1]);
5035 Py_XDECREF(fileObj[2]);
5036 }
5037
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005038 /* Child is launched. Close the parents copy of those pipe
5039 * handles that only the child should have open. You need to
5040 * make sure that no handles to the write end of the output pipe
5041 * are maintained in this process or else the pipe will not close
5042 * when the child process exits and the ReadFile will hang. */
5043
5044 if (!CloseHandle(hChildStdinRd))
5045 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005046
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005047 if (!CloseHandle(hChildStdoutWr))
5048 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005049
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005050 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5051 return win32_error("CloseHandle", NULL);
5052
5053 return f;
5054}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005055
5056/*
5057 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5058 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005059 *
5060 * This function uses the _PyPopenProcs dictionary in order to map the
5061 * input file pointer to information about the process that was
5062 * originally created by the popen* call that created the file pointer.
5063 * The dictionary uses the file pointer as a key (with one entry
5064 * inserted for each file returned by the original popen* call) and a
5065 * single list object as the value for all files from a single call.
5066 * The list object contains the Win32 process handle at [0], and a file
5067 * count at [1], which is initialized to the total number of file
5068 * handles using that list.
5069 *
5070 * This function closes whichever handle it is passed, and decrements
5071 * the file count in the dictionary for the process handle pointed to
5072 * by this file. On the last close (when the file count reaches zero),
5073 * this function will wait for the child process and then return its
5074 * exit code as the result of the close() operation. This permits the
5075 * files to be closed in any order - it is always the close() of the
5076 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005077 *
5078 * NOTE: This function is currently called with the GIL released.
5079 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005080 */
Tim Peters736aa322000-09-01 06:51:24 +00005081
Fredrik Lundh56055a42000-07-23 19:47:12 +00005082static int _PyPclose(FILE *file)
5083{
Fredrik Lundh20318932000-07-26 17:29:12 +00005084 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005085 DWORD exit_code;
5086 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00005087 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5088 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005089#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005090 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005091#endif
5092
Fredrik Lundh20318932000-07-26 17:29:12 +00005093 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00005094 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00005095 */
5096 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005097#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005098 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005099#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005100 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005101 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5102 (procObj = PyDict_GetItem(_PyPopenProcs,
5103 fileObj)) != NULL &&
5104 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5105 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5106
5107 hProcess = PyLong_AsVoidPtr(hProcessObj);
5108 file_count = PyInt_AsLong(intObj);
5109
5110 if (file_count > 1) {
5111 /* Still other files referencing process */
5112 file_count--;
5113 PyList_SetItem(procObj,1,
5114 PyInt_FromLong(file_count));
5115 } else {
5116 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00005117 if (result != EOF &&
5118 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5119 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00005120 /* Possible truncation here in 16-bit environments, but
5121 * real exit codes are just the lower byte in any event.
5122 */
5123 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005124 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00005125 /* Indicate failure - this will cause the file object
5126 * to raise an I/O error and translate the last Win32
5127 * error code from errno. We do have a problem with
5128 * last errors that overlap the normal errno table,
5129 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005130 */
Fredrik Lundh20318932000-07-26 17:29:12 +00005131 if (result != EOF) {
5132 /* If the error wasn't from the fclose(), then
5133 * set errno for the file object error handling.
5134 */
5135 errno = GetLastError();
5136 }
5137 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005138 }
5139
5140 /* Free up the native handle at this point */
5141 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00005142 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005143
Mark Hammondb37a3732000-08-14 04:47:33 +00005144 /* Remove this file pointer from dictionary */
5145 PyDict_DelItem(_PyPopenProcs, fileObj);
5146
5147 if (PyDict_Size(_PyPopenProcs) == 0) {
5148 Py_DECREF(_PyPopenProcs);
5149 _PyPopenProcs = NULL;
5150 }
5151
5152 } /* if object retrieval ok */
5153
5154 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005155 } /* if _PyPopenProcs */
5156
Tim Peters736aa322000-09-01 06:51:24 +00005157#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005158 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005159#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005160 return result;
5161}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005162
5163#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005164static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005165posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005166{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005167 char *name;
5168 char *mode = "r";
5169 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00005170 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005171 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005172 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00005173 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00005174 /* Strip mode of binary or text modifiers */
5175 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5176 mode = "r";
5177 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5178 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00005179 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005180 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005181 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00005182 if (fp == NULL)
5183 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005184 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005185 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005186 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005187 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005188}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005189
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005190#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005191#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005192
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005193
Guido van Rossumb6775db1994-08-01 11:34:53 +00005194#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005195PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005196"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005197Set the current process's user id.");
5198
Barry Warsaw53699e91996-12-10 23:23:01 +00005199static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005200posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005201{
5202 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005203 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005204 return NULL;
5205 if (setuid(uid) < 0)
5206 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005207 Py_INCREF(Py_None);
5208 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005209}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005210#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005211
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005212
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005213#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005214PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005215"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005216Set the current process's effective user id.");
5217
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005218static PyObject *
5219posix_seteuid (PyObject *self, PyObject *args)
5220{
5221 int euid;
5222 if (!PyArg_ParseTuple(args, "i", &euid)) {
5223 return NULL;
5224 } else if (seteuid(euid) < 0) {
5225 return posix_error();
5226 } else {
5227 Py_INCREF(Py_None);
5228 return Py_None;
5229 }
5230}
5231#endif /* HAVE_SETEUID */
5232
5233#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005234PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005235"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005236Set the current process's effective group id.");
5237
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005238static PyObject *
5239posix_setegid (PyObject *self, PyObject *args)
5240{
5241 int egid;
5242 if (!PyArg_ParseTuple(args, "i", &egid)) {
5243 return NULL;
5244 } else if (setegid(egid) < 0) {
5245 return posix_error();
5246 } else {
5247 Py_INCREF(Py_None);
5248 return Py_None;
5249 }
5250}
5251#endif /* HAVE_SETEGID */
5252
5253#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005254PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005255"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005256Set the current process's real and effective user ids.");
5257
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005258static PyObject *
5259posix_setreuid (PyObject *self, PyObject *args)
5260{
5261 int ruid, euid;
5262 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
5263 return NULL;
5264 } else if (setreuid(ruid, euid) < 0) {
5265 return posix_error();
5266 } else {
5267 Py_INCREF(Py_None);
5268 return Py_None;
5269 }
5270}
5271#endif /* HAVE_SETREUID */
5272
5273#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005274PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005275"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005276Set the current process's real and effective group ids.");
5277
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005278static PyObject *
5279posix_setregid (PyObject *self, PyObject *args)
5280{
5281 int rgid, egid;
5282 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
5283 return NULL;
5284 } else if (setregid(rgid, egid) < 0) {
5285 return posix_error();
5286 } else {
5287 Py_INCREF(Py_None);
5288 return Py_None;
5289 }
5290}
5291#endif /* HAVE_SETREGID */
5292
Guido van Rossumb6775db1994-08-01 11:34:53 +00005293#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005294PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005295"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005296Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005297
Barry Warsaw53699e91996-12-10 23:23:01 +00005298static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005299posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005300{
5301 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005302 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005303 return NULL;
5304 if (setgid(gid) < 0)
5305 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005306 Py_INCREF(Py_None);
5307 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005308}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005309#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005310
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005311#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005312PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005313"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005314Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005315
5316static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00005317posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005318{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005319 int i, len;
5320 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005321
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005322 if (!PySequence_Check(groups)) {
5323 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5324 return NULL;
5325 }
5326 len = PySequence_Size(groups);
5327 if (len > MAX_GROUPS) {
5328 PyErr_SetString(PyExc_ValueError, "too many groups");
5329 return NULL;
5330 }
5331 for(i = 0; i < len; i++) {
5332 PyObject *elem;
5333 elem = PySequence_GetItem(groups, i);
5334 if (!elem)
5335 return NULL;
5336 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005337 if (!PyLong_Check(elem)) {
5338 PyErr_SetString(PyExc_TypeError,
5339 "groups must be integers");
5340 Py_DECREF(elem);
5341 return NULL;
5342 } else {
5343 unsigned long x = PyLong_AsUnsignedLong(elem);
5344 if (PyErr_Occurred()) {
5345 PyErr_SetString(PyExc_TypeError,
5346 "group id too big");
5347 Py_DECREF(elem);
5348 return NULL;
5349 }
5350 grouplist[i] = x;
5351 /* read back the value to see if it fitted in gid_t */
5352 if (grouplist[i] != x) {
5353 PyErr_SetString(PyExc_TypeError,
5354 "group id too big");
5355 Py_DECREF(elem);
5356 return NULL;
5357 }
5358 }
5359 } else {
5360 long x = PyInt_AsLong(elem);
5361 grouplist[i] = x;
5362 if (grouplist[i] != x) {
5363 PyErr_SetString(PyExc_TypeError,
5364 "group id too big");
5365 Py_DECREF(elem);
5366 return NULL;
5367 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005368 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005369 Py_DECREF(elem);
5370 }
5371
5372 if (setgroups(len, grouplist) < 0)
5373 return posix_error();
5374 Py_INCREF(Py_None);
5375 return Py_None;
5376}
5377#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005378
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005379#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
5380static PyObject *
5381wait_helper(int pid, int status, struct rusage *ru)
5382{
5383 PyObject *result;
5384 static PyObject *struct_rusage;
5385
5386 if (pid == -1)
5387 return posix_error();
5388
5389 if (struct_rusage == NULL) {
5390 PyObject *m = PyImport_ImportModule("resource");
5391 if (m == NULL)
5392 return NULL;
5393 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5394 Py_DECREF(m);
5395 if (struct_rusage == NULL)
5396 return NULL;
5397 }
5398
5399 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5400 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5401 if (!result)
5402 return NULL;
5403
5404#ifndef doubletime
5405#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5406#endif
5407
5408 PyStructSequence_SET_ITEM(result, 0,
5409 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5410 PyStructSequence_SET_ITEM(result, 1,
5411 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5412#define SET_INT(result, index, value)\
5413 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5414 SET_INT(result, 2, ru->ru_maxrss);
5415 SET_INT(result, 3, ru->ru_ixrss);
5416 SET_INT(result, 4, ru->ru_idrss);
5417 SET_INT(result, 5, ru->ru_isrss);
5418 SET_INT(result, 6, ru->ru_minflt);
5419 SET_INT(result, 7, ru->ru_majflt);
5420 SET_INT(result, 8, ru->ru_nswap);
5421 SET_INT(result, 9, ru->ru_inblock);
5422 SET_INT(result, 10, ru->ru_oublock);
5423 SET_INT(result, 11, ru->ru_msgsnd);
5424 SET_INT(result, 12, ru->ru_msgrcv);
5425 SET_INT(result, 13, ru->ru_nsignals);
5426 SET_INT(result, 14, ru->ru_nvcsw);
5427 SET_INT(result, 15, ru->ru_nivcsw);
5428#undef SET_INT
5429
5430 if (PyErr_Occurred()) {
5431 Py_DECREF(result);
5432 return NULL;
5433 }
5434
5435 return Py_BuildValue("iiN", pid, status, result);
5436}
5437#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
5438
5439#ifdef HAVE_WAIT3
5440PyDoc_STRVAR(posix_wait3__doc__,
5441"wait3(options) -> (pid, status, rusage)\n\n\
5442Wait for completion of a child process.");
5443
5444static PyObject *
5445posix_wait3(PyObject *self, PyObject *args)
5446{
5447 int pid, options;
5448 struct rusage ru;
5449 WAIT_TYPE status;
5450 WAIT_STATUS_INT(status) = 0;
5451
5452 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5453 return NULL;
5454
5455 Py_BEGIN_ALLOW_THREADS
5456 pid = wait3(&status, options, &ru);
5457 Py_END_ALLOW_THREADS
5458
5459 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
5460}
5461#endif /* HAVE_WAIT3 */
5462
5463#ifdef HAVE_WAIT4
5464PyDoc_STRVAR(posix_wait4__doc__,
5465"wait4(pid, options) -> (pid, status, rusage)\n\n\
5466Wait for completion of a given child process.");
5467
5468static PyObject *
5469posix_wait4(PyObject *self, PyObject *args)
5470{
5471 int pid, options;
5472 struct rusage ru;
5473 WAIT_TYPE status;
5474 WAIT_STATUS_INT(status) = 0;
5475
5476 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5477 return NULL;
5478
5479 Py_BEGIN_ALLOW_THREADS
5480 pid = wait4(pid, &status, options, &ru);
5481 Py_END_ALLOW_THREADS
5482
5483 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
5484}
5485#endif /* HAVE_WAIT4 */
5486
Guido van Rossumb6775db1994-08-01 11:34:53 +00005487#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005488PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005489"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005490Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005491
Barry Warsaw53699e91996-12-10 23:23:01 +00005492static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005493posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005494{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005495 int pid, options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005496 WAIT_TYPE status;
5497 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005498
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005499 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005500 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005501 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005502 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005503 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005504 if (pid == -1)
5505 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005506
5507 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005508}
5509
Tim Petersab034fa2002-02-01 11:27:43 +00005510#elif defined(HAVE_CWAIT)
5511
5512/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005513PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005514"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005515"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005516
5517static PyObject *
5518posix_waitpid(PyObject *self, PyObject *args)
5519{
Thomas Wouters477c8d52006-05-27 19:21:47 +00005520 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005521 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005522
5523 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5524 return NULL;
5525 Py_BEGIN_ALLOW_THREADS
5526 pid = _cwait(&status, pid, options);
5527 Py_END_ALLOW_THREADS
5528 if (pid == -1)
5529 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005530
5531 /* shift the status left a byte so this is more like the POSIX waitpid */
5532 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005533}
5534#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005535
Guido van Rossumad0ee831995-03-01 10:34:45 +00005536#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005537PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005538"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005539Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005540
Barry Warsaw53699e91996-12-10 23:23:01 +00005541static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005542posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005543{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005544 int pid;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005545 WAIT_TYPE status;
5546 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005547
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005548 Py_BEGIN_ALLOW_THREADS
5549 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005550 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005551 if (pid == -1)
5552 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005553
5554 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005555}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005556#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005557
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005558
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005559PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005560"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005561Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005562
Barry Warsaw53699e91996-12-10 23:23:01 +00005563static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005564posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005565{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005566#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005567 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005568#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005569#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005570 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005571#else
5572 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5573#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005574#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005575}
5576
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005577
Guido van Rossumb6775db1994-08-01 11:34:53 +00005578#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005579PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005580"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005581Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005582
Barry Warsaw53699e91996-12-10 23:23:01 +00005583static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005584posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005585{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005586 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005587 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005588 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005589 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005590 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005591 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005592 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005593 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005594 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005595 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00005596 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005597}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005598#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005599
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005600
Guido van Rossumb6775db1994-08-01 11:34:53 +00005601#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005602PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005603"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005604Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005605
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005606static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005607posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005608{
Thomas Wouters477c8d52006-05-27 19:21:47 +00005609 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005610}
5611#endif /* HAVE_SYMLINK */
5612
5613
5614#ifdef HAVE_TIMES
5615#ifndef HZ
5616#define HZ 60 /* Universal constant :-) */
5617#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005618
Guido van Rossumd48f2521997-12-05 22:19:34 +00005619#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5620static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005621system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005622{
5623 ULONG value = 0;
5624
5625 Py_BEGIN_ALLOW_THREADS
5626 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5627 Py_END_ALLOW_THREADS
5628
5629 return value;
5630}
5631
5632static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005633posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005634{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005635 /* Currently Only Uptime is Provided -- Others Later */
5636 return Py_BuildValue("ddddd",
5637 (double)0 /* t.tms_utime / HZ */,
5638 (double)0 /* t.tms_stime / HZ */,
5639 (double)0 /* t.tms_cutime / HZ */,
5640 (double)0 /* t.tms_cstime / HZ */,
5641 (double)system_uptime() / 1000);
5642}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005643#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005644static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005645posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005646{
5647 struct tms t;
5648 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005649 errno = 0;
5650 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005651 if (c == (clock_t) -1)
5652 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005653 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005654 (double)t.tms_utime / HZ,
5655 (double)t.tms_stime / HZ,
5656 (double)t.tms_cutime / HZ,
5657 (double)t.tms_cstime / HZ,
5658 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005659}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005660#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005661#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005662
5663
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005664#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005665#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005666static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005667posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005668{
5669 FILETIME create, exit, kernel, user;
5670 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005671 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005672 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5673 /* The fields of a FILETIME structure are the hi and lo part
5674 of a 64-bit value expressed in 100 nanosecond units.
5675 1e7 is one second in such units; 1e-7 the inverse.
5676 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5677 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005678 return Py_BuildValue(
5679 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005680 (double)(kernel.dwHighDateTime*429.4967296 +
5681 kernel.dwLowDateTime*1e-7),
5682 (double)(user.dwHighDateTime*429.4967296 +
5683 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005684 (double)0,
5685 (double)0,
5686 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005687}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005688#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005689
5690#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005691PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005692"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005693Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005694#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005695
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005696
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005697#ifdef HAVE_GETSID
5698PyDoc_STRVAR(posix_getsid__doc__,
5699"getsid(pid) -> sid\n\n\
5700Call the system call getsid().");
5701
5702static PyObject *
5703posix_getsid(PyObject *self, PyObject *args)
5704{
5705 int pid, sid;
5706 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5707 return NULL;
5708 sid = getsid(pid);
5709 if (sid < 0)
5710 return posix_error();
5711 return PyInt_FromLong((long)sid);
5712}
5713#endif /* HAVE_GETSID */
5714
5715
Guido van Rossumb6775db1994-08-01 11:34:53 +00005716#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005717PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005718"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005719Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005720
Barry Warsaw53699e91996-12-10 23:23:01 +00005721static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005722posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005723{
Guido van Rossum687dd131993-05-17 08:34:16 +00005724 if (setsid() < 0)
5725 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005726 Py_INCREF(Py_None);
5727 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005728}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005729#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005730
Guido van Rossumb6775db1994-08-01 11:34:53 +00005731#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005732PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005733"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005734Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005735
Barry Warsaw53699e91996-12-10 23:23:01 +00005736static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005737posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005738{
5739 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005740 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005741 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005742 if (setpgid(pid, pgrp) < 0)
5743 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005744 Py_INCREF(Py_None);
5745 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005746}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005747#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005748
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005749
Guido van Rossumb6775db1994-08-01 11:34:53 +00005750#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005751PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005752"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005753Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005754
Barry Warsaw53699e91996-12-10 23:23:01 +00005755static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005756posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005757{
5758 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005759 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005760 return NULL;
5761 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005762 if (pgid < 0)
5763 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005764 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005765}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005766#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005767
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005768
Guido van Rossumb6775db1994-08-01 11:34:53 +00005769#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005770PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005771"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005772Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005773
Barry Warsaw53699e91996-12-10 23:23:01 +00005774static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005775posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005776{
5777 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005778 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005779 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005780 if (tcsetpgrp(fd, pgid) < 0)
5781 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005782 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005783 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005784}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005785#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005786
Guido van Rossum687dd131993-05-17 08:34:16 +00005787/* Functions acting on file descriptors */
5788
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005789PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005790"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005791Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005792
Barry Warsaw53699e91996-12-10 23:23:01 +00005793static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005794posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005795{
Mark Hammondef8b6542001-05-13 08:04:26 +00005796 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005797 int flag;
5798 int mode = 0777;
5799 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005800
5801#ifdef MS_WINDOWS
5802 if (unicode_file_names()) {
5803 PyUnicodeObject *po;
5804 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5805 Py_BEGIN_ALLOW_THREADS
5806 /* PyUnicode_AS_UNICODE OK without thread
5807 lock as it is a simple dereference. */
5808 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5809 Py_END_ALLOW_THREADS
5810 if (fd < 0)
5811 return posix_error();
5812 return PyInt_FromLong((long)fd);
5813 }
5814 /* Drop the argument parsing error as narrow strings
5815 are also valid. */
5816 PyErr_Clear();
5817 }
5818#endif
5819
Tim Peters5aa91602002-01-30 05:46:57 +00005820 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005821 Py_FileSystemDefaultEncoding, &file,
5822 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005823 return NULL;
5824
Barry Warsaw53699e91996-12-10 23:23:01 +00005825 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005826 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005827 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005828 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005829 return posix_error_with_allocated_filename(file);
5830 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005831 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005832}
5833
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005834
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005835PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005836"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005837Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005838
Barry Warsaw53699e91996-12-10 23:23:01 +00005839static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005840posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005841{
5842 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005843 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005844 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005845 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005846 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005847 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005848 if (res < 0)
5849 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005850 Py_INCREF(Py_None);
5851 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005852}
5853
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005854
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005855PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005856"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005857Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005858
Barry Warsaw53699e91996-12-10 23:23:01 +00005859static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005860posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005861{
5862 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005863 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005864 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005865 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005866 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005867 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005868 if (fd < 0)
5869 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005870 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005871}
5872
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005873
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005874PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005875"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005876Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005877
Barry Warsaw53699e91996-12-10 23:23:01 +00005878static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005879posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005880{
5881 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005882 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005883 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005884 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005885 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005886 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005887 if (res < 0)
5888 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005889 Py_INCREF(Py_None);
5890 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005891}
5892
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005893
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005894PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005895"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005896Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005897
Barry Warsaw53699e91996-12-10 23:23:01 +00005898static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005899posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005900{
5901 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005902#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005903 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005904#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005905 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005906#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005907 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005908 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005909 return NULL;
5910#ifdef SEEK_SET
5911 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5912 switch (how) {
5913 case 0: how = SEEK_SET; break;
5914 case 1: how = SEEK_CUR; break;
5915 case 2: how = SEEK_END; break;
5916 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005917#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005918
5919#if !defined(HAVE_LARGEFILE_SUPPORT)
5920 pos = PyInt_AsLong(posobj);
5921#else
5922 pos = PyLong_Check(posobj) ?
5923 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5924#endif
5925 if (PyErr_Occurred())
5926 return NULL;
5927
Barry Warsaw53699e91996-12-10 23:23:01 +00005928 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005929#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005930 res = _lseeki64(fd, pos, how);
5931#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005932 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005933#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005934 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005935 if (res < 0)
5936 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005937
5938#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005939 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005940#else
5941 return PyLong_FromLongLong(res);
5942#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005943}
5944
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005945
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005946PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005947"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005948Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005949
Barry Warsaw53699e91996-12-10 23:23:01 +00005950static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005951posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005952{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005953 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005954 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005955 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005956 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005957 if (size < 0) {
5958 errno = EINVAL;
5959 return posix_error();
5960 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005961 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005962 if (buffer == NULL)
5963 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005964 Py_BEGIN_ALLOW_THREADS
5965 n = read(fd, PyString_AsString(buffer), size);
5966 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005967 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005968 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005969 return posix_error();
5970 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005971 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005972 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005973 return buffer;
5974}
5975
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005976
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005977PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005978"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005979Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005980
Barry Warsaw53699e91996-12-10 23:23:01 +00005981static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005982posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005983{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005984 int fd;
5985 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00005986 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005987
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005988 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005989 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005990 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005991 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005992 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005993 if (size < 0)
5994 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005995 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005996}
5997
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005998
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005999PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006000"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006001Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006002
Barry Warsaw53699e91996-12-10 23:23:01 +00006003static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006004posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006005{
6006 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00006007 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00006008 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006009 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006010 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006011#ifdef __VMS
6012 /* on OpenVMS we must ensure that all bytes are written to the file */
6013 fsync(fd);
6014#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006015 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00006016 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00006017 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00006018 if (res != 0) {
6019#ifdef MS_WINDOWS
6020 return win32_error("fstat", NULL);
6021#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006022 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006023#endif
6024 }
Tim Peters5aa91602002-01-30 05:46:57 +00006025
Martin v. Löwis14694662006-02-03 12:54:16 +00006026 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006027}
6028
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006029
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006030PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006031"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006032Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006033
Barry Warsaw53699e91996-12-10 23:23:01 +00006034static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006035posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006036{
Guido van Rossum687dd131993-05-17 08:34:16 +00006037 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006038 char *mode = "r";
6039 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00006040 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00006041 PyObject *f;
6042 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00006043 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006044
Thomas Heller1f043e22002-11-07 16:00:59 +00006045 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
6046 PyErr_Format(PyExc_ValueError,
6047 "invalid file mode '%s'", mode);
6048 return NULL;
6049 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006050 Py_BEGIN_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006051#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
6052 if (mode[0] == 'a') {
6053 /* try to make sure the O_APPEND flag is set */
6054 int flags;
6055 flags = fcntl(fd, F_GETFL);
6056 if (flags != -1)
6057 fcntl(fd, F_SETFL, flags | O_APPEND);
6058 fp = fdopen(fd, mode);
6059 if (fp == NULL && flags != -1)
6060 /* restore old mode if fdopen failed */
6061 fcntl(fd, F_SETFL, flags);
6062 } else {
6063 fp = fdopen(fd, mode);
6064 }
6065#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006066 fp = fdopen(fd, mode);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006067#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006068 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006069 if (fp == NULL)
6070 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00006071 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006072 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00006073 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006074 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006075}
6076
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006077PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006078"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006079Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006080connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006081
6082static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006083posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006084{
6085 int fd;
6086 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6087 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006088 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006089}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006090
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006091#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006092PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006093"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006094Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006095
Barry Warsaw53699e91996-12-10 23:23:01 +00006096static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006097posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006098{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006099#if defined(PYOS_OS2)
6100 HFILE read, write;
6101 APIRET rc;
6102
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006103 Py_BEGIN_ALLOW_THREADS
6104 rc = DosCreatePipe( &read, &write, 4096);
6105 Py_END_ALLOW_THREADS
6106 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006107 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006108
6109 return Py_BuildValue("(ii)", read, write);
6110#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006111#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00006112 int fds[2];
6113 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00006114 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006115 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00006116 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006117 if (res != 0)
6118 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006119 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006120#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00006121 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006122 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00006123 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00006124 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006125 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00006126 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00006127 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006128 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00006129 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6130 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006131 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006132#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006133#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006134}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006135#endif /* HAVE_PIPE */
6136
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006137
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006138#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006139PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006140"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006141Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006142
Barry Warsaw53699e91996-12-10 23:23:01 +00006143static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006144posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006145{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006146 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006147 int mode = 0666;
6148 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006149 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006150 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006151 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006152 res = mkfifo(filename, mode);
6153 Py_END_ALLOW_THREADS
6154 if (res < 0)
6155 return posix_error();
6156 Py_INCREF(Py_None);
6157 return Py_None;
6158}
6159#endif
6160
6161
Neal Norwitz11690112002-07-30 01:08:28 +00006162#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006163PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006164"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006165Create a filesystem node (file, device special file or named pipe)\n\
6166named filename. mode specifies both the permissions to use and the\n\
6167type of node to be created, being combined (bitwise OR) with one of\n\
6168S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006169device defines the newly created device special file (probably using\n\
6170os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006171
6172
6173static PyObject *
6174posix_mknod(PyObject *self, PyObject *args)
6175{
6176 char *filename;
6177 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006178 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006179 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00006180 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006181 return NULL;
6182 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006183 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00006184 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006185 if (res < 0)
6186 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006187 Py_INCREF(Py_None);
6188 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006189}
6190#endif
6191
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006192#ifdef HAVE_DEVICE_MACROS
6193PyDoc_STRVAR(posix_major__doc__,
6194"major(device) -> major number\n\
6195Extracts a device major number from a raw device number.");
6196
6197static PyObject *
6198posix_major(PyObject *self, PyObject *args)
6199{
6200 int device;
6201 if (!PyArg_ParseTuple(args, "i:major", &device))
6202 return NULL;
6203 return PyInt_FromLong((long)major(device));
6204}
6205
6206PyDoc_STRVAR(posix_minor__doc__,
6207"minor(device) -> minor number\n\
6208Extracts a device minor number from a raw device number.");
6209
6210static PyObject *
6211posix_minor(PyObject *self, PyObject *args)
6212{
6213 int device;
6214 if (!PyArg_ParseTuple(args, "i:minor", &device))
6215 return NULL;
6216 return PyInt_FromLong((long)minor(device));
6217}
6218
6219PyDoc_STRVAR(posix_makedev__doc__,
6220"makedev(major, minor) -> device number\n\
6221Composes a raw device number from the major and minor device numbers.");
6222
6223static PyObject *
6224posix_makedev(PyObject *self, PyObject *args)
6225{
6226 int major, minor;
6227 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6228 return NULL;
6229 return PyInt_FromLong((long)makedev(major, minor));
6230}
6231#endif /* device macros */
6232
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006233
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006234#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006235PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006236"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006237Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006238
Barry Warsaw53699e91996-12-10 23:23:01 +00006239static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006240posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006241{
6242 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006243 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006244 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006245 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006246
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006247 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006248 return NULL;
6249
6250#if !defined(HAVE_LARGEFILE_SUPPORT)
6251 length = PyInt_AsLong(lenobj);
6252#else
6253 length = PyLong_Check(lenobj) ?
6254 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6255#endif
6256 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006257 return NULL;
6258
Barry Warsaw53699e91996-12-10 23:23:01 +00006259 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006260 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006261 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006262 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006263 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006264 return NULL;
6265 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006266 Py_INCREF(Py_None);
6267 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006268}
6269#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006270
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006271#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006272PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006273"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006274Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006275
Fred Drake762e2061999-08-26 17:23:54 +00006276/* Save putenv() parameters as values here, so we can collect them when they
6277 * get re-set with another call for the same key. */
6278static PyObject *posix_putenv_garbage;
6279
Tim Peters5aa91602002-01-30 05:46:57 +00006280static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006281posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006282{
6283 char *s1, *s2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006284 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006285 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006286 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006287
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006288 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006289 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006290
6291#if defined(PYOS_OS2)
6292 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6293 APIRET rc;
6294
Guido van Rossumd48f2521997-12-05 22:19:34 +00006295 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6296 if (rc != NO_ERROR)
6297 return os2_error(rc);
6298
6299 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6300 APIRET rc;
6301
Guido van Rossumd48f2521997-12-05 22:19:34 +00006302 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6303 if (rc != NO_ERROR)
6304 return os2_error(rc);
6305 } else {
6306#endif
6307
Fred Drake762e2061999-08-26 17:23:54 +00006308 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006309 len = strlen(s1) + strlen(s2) + 2;
6310 /* len includes space for a trailing \0; the size arg to
6311 PyString_FromStringAndSize does not count that */
6312 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006313 if (newstr == NULL)
6314 return PyErr_NoMemory();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006315 newenv = PyString_AS_STRING(newstr);
6316 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6317 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006318 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006319 posix_error();
6320 return NULL;
6321 }
Fred Drake762e2061999-08-26 17:23:54 +00006322 /* Install the first arg and newstr in posix_putenv_garbage;
6323 * this will cause previous value to be collected. This has to
6324 * happen after the real putenv() call because the old value
6325 * was still accessible until then. */
6326 if (PyDict_SetItem(posix_putenv_garbage,
6327 PyTuple_GET_ITEM(args, 0), newstr)) {
6328 /* really not much we can do; just leak */
6329 PyErr_Clear();
6330 }
6331 else {
6332 Py_DECREF(newstr);
6333 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006334
6335#if defined(PYOS_OS2)
6336 }
6337#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006338 Py_INCREF(Py_None);
6339 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006340}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006341#endif /* putenv */
6342
Guido van Rossumc524d952001-10-19 01:31:59 +00006343#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006344PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006345"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006346Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006347
6348static PyObject *
6349posix_unsetenv(PyObject *self, PyObject *args)
6350{
6351 char *s1;
6352
6353 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6354 return NULL;
6355
6356 unsetenv(s1);
6357
6358 /* Remove the key from posix_putenv_garbage;
6359 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006360 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006361 * old value was still accessible until then.
6362 */
6363 if (PyDict_DelItem(posix_putenv_garbage,
6364 PyTuple_GET_ITEM(args, 0))) {
6365 /* really not much we can do; just leak */
6366 PyErr_Clear();
6367 }
6368
6369 Py_INCREF(Py_None);
6370 return Py_None;
6371}
6372#endif /* unsetenv */
6373
Guido van Rossumb6a47161997-09-15 22:54:34 +00006374#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006375PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006376"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006377Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006378
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006379static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006380posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006381{
6382 int code;
6383 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006384 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006385 return NULL;
6386 message = strerror(code);
6387 if (message == NULL) {
6388 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006389 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006390 return NULL;
6391 }
6392 return PyString_FromString(message);
6393}
6394#endif /* strerror */
6395
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006396
Guido van Rossumc9641791998-08-04 15:26:23 +00006397#ifdef HAVE_SYS_WAIT_H
6398
Fred Drake106c1a02002-04-23 15:58:02 +00006399#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006400PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006401"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006402Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006403
6404static PyObject *
6405posix_WCOREDUMP(PyObject *self, PyObject *args)
6406{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006407 WAIT_TYPE status;
6408 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006409
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006410 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006411 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006412
6413 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006414}
6415#endif /* WCOREDUMP */
6416
6417#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006418PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006419"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006420Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006421job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006422
6423static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006424posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006425{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006426 WAIT_TYPE status;
6427 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006428
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006429 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006430 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006431
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006432 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006433}
6434#endif /* WIFCONTINUED */
6435
Guido van Rossumc9641791998-08-04 15:26:23 +00006436#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006437PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006438"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006439Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006440
6441static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006442posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006443{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006444 WAIT_TYPE status;
6445 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006446
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006447 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006448 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006449
Fred Drake106c1a02002-04-23 15:58:02 +00006450 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006451}
6452#endif /* WIFSTOPPED */
6453
6454#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006455PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006456"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006457Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006458
6459static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006460posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006461{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006462 WAIT_TYPE status;
6463 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006464
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006465 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006466 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006467
Fred Drake106c1a02002-04-23 15:58:02 +00006468 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006469}
6470#endif /* WIFSIGNALED */
6471
6472#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006473PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006474"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006475Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006476system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006477
6478static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006479posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006480{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006481 WAIT_TYPE status;
6482 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006483
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006484 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006485 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006486
Fred Drake106c1a02002-04-23 15:58:02 +00006487 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006488}
6489#endif /* WIFEXITED */
6490
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006491#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006492PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006493"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006494Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006495
6496static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006497posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006498{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006499 WAIT_TYPE status;
6500 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006501
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006502 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006503 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006504
Guido van Rossumc9641791998-08-04 15:26:23 +00006505 return Py_BuildValue("i", WEXITSTATUS(status));
6506}
6507#endif /* WEXITSTATUS */
6508
6509#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006510PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006511"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006512Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006513value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006514
6515static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006516posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006517{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006518 WAIT_TYPE status;
6519 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006520
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006521 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006522 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006523
Guido van Rossumc9641791998-08-04 15:26:23 +00006524 return Py_BuildValue("i", WTERMSIG(status));
6525}
6526#endif /* WTERMSIG */
6527
6528#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006529PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006530"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006531Return the signal that stopped the process that provided\n\
6532the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006533
6534static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006535posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006536{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006537 WAIT_TYPE status;
6538 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006539
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006540 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006541 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006542
Guido van Rossumc9641791998-08-04 15:26:23 +00006543 return Py_BuildValue("i", WSTOPSIG(status));
6544}
6545#endif /* WSTOPSIG */
6546
6547#endif /* HAVE_SYS_WAIT_H */
6548
6549
Thomas Wouters477c8d52006-05-27 19:21:47 +00006550#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006551#ifdef _SCO_DS
6552/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6553 needed definitions in sys/statvfs.h */
6554#define _SVID3
6555#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006556#include <sys/statvfs.h>
6557
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006558static PyObject*
6559_pystatvfs_fromstructstatvfs(struct statvfs st) {
6560 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6561 if (v == NULL)
6562 return NULL;
6563
6564#if !defined(HAVE_LARGEFILE_SUPPORT)
6565 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6566 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6567 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6568 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6569 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6570 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6571 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6572 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6573 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6574 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6575#else
6576 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6577 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006578 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006579 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006580 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006581 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006582 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006583 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006584 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006585 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006586 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006587 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006588 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006589 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006590 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6591 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6592#endif
6593
6594 return v;
6595}
6596
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006597PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006598"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006599Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006600
6601static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006602posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006603{
6604 int fd, res;
6605 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006606
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006607 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006608 return NULL;
6609 Py_BEGIN_ALLOW_THREADS
6610 res = fstatvfs(fd, &st);
6611 Py_END_ALLOW_THREADS
6612 if (res != 0)
6613 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006614
6615 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006616}
Thomas Wouters477c8d52006-05-27 19:21:47 +00006617#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006618
6619
Thomas Wouters477c8d52006-05-27 19:21:47 +00006620#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006621#include <sys/statvfs.h>
6622
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006623PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006624"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006625Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006626
6627static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006628posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006629{
6630 char *path;
6631 int res;
6632 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006633 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006634 return NULL;
6635 Py_BEGIN_ALLOW_THREADS
6636 res = statvfs(path, &st);
6637 Py_END_ALLOW_THREADS
6638 if (res != 0)
6639 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006640
6641 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006642}
6643#endif /* HAVE_STATVFS */
6644
6645
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006646#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006647PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006648"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006649Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006650The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006651or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006652
6653static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006654posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006655{
6656 PyObject *result = NULL;
6657 char *dir = NULL;
6658 char *pfx = NULL;
6659 char *name;
6660
6661 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6662 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006663
6664 if (PyErr_Warn(PyExc_RuntimeWarning,
6665 "tempnam is a potential security risk to your program") < 0)
6666 return NULL;
6667
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006668#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006669 name = _tempnam(dir, pfx);
6670#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006671 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006672#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006673 if (name == NULL)
6674 return PyErr_NoMemory();
6675 result = PyString_FromString(name);
6676 free(name);
6677 return result;
6678}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006679#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006680
6681
6682#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006683PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006684"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006685Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006686
6687static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006688posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006689{
6690 FILE *fp;
6691
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006692 fp = tmpfile();
6693 if (fp == NULL)
6694 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006695 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006696}
6697#endif
6698
6699
6700#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006701PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006702"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006703Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006704
6705static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006706posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006707{
6708 char buffer[L_tmpnam];
6709 char *name;
6710
Skip Montanaro95618b52001-08-18 18:52:10 +00006711 if (PyErr_Warn(PyExc_RuntimeWarning,
6712 "tmpnam is a potential security risk to your program") < 0)
6713 return NULL;
6714
Greg Wardb48bc172000-03-01 21:51:56 +00006715#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006716 name = tmpnam_r(buffer);
6717#else
6718 name = tmpnam(buffer);
6719#endif
6720 if (name == NULL) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006721 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006722#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006723 "unexpected NULL from tmpnam_r"
6724#else
6725 "unexpected NULL from tmpnam"
6726#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006727 );
6728 PyErr_SetObject(PyExc_OSError, err);
6729 Py_XDECREF(err);
6730 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006731 }
6732 return PyString_FromString(buffer);
6733}
6734#endif
6735
6736
Fred Drakec9680921999-12-13 16:37:25 +00006737/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6738 * It maps strings representing configuration variable names to
6739 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006740 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006741 * rarely-used constants. There are three separate tables that use
6742 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006743 *
6744 * This code is always included, even if none of the interfaces that
6745 * need it are included. The #if hackery needed to avoid it would be
6746 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006747 */
6748struct constdef {
6749 char *name;
6750 long value;
6751};
6752
Fred Drake12c6e2d1999-12-14 21:25:03 +00006753static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006754conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6755 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006756{
6757 if (PyInt_Check(arg)) {
6758 *valuep = PyInt_AS_LONG(arg);
6759 return 1;
6760 }
6761 if (PyString_Check(arg)) {
6762 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006763 size_t lo = 0;
6764 size_t mid;
6765 size_t hi = tablesize;
6766 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006767 char *confname = PyString_AS_STRING(arg);
6768 while (lo < hi) {
6769 mid = (lo + hi) / 2;
6770 cmp = strcmp(confname, table[mid].name);
6771 if (cmp < 0)
6772 hi = mid;
6773 else if (cmp > 0)
6774 lo = mid + 1;
6775 else {
6776 *valuep = table[mid].value;
6777 return 1;
6778 }
6779 }
6780 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6781 }
6782 else
6783 PyErr_SetString(PyExc_TypeError,
6784 "configuration names must be strings or integers");
6785 return 0;
6786}
6787
6788
6789#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6790static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006791#ifdef _PC_ABI_AIO_XFER_MAX
6792 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6793#endif
6794#ifdef _PC_ABI_ASYNC_IO
6795 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6796#endif
Fred Drakec9680921999-12-13 16:37:25 +00006797#ifdef _PC_ASYNC_IO
6798 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6799#endif
6800#ifdef _PC_CHOWN_RESTRICTED
6801 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6802#endif
6803#ifdef _PC_FILESIZEBITS
6804 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6805#endif
6806#ifdef _PC_LAST
6807 {"PC_LAST", _PC_LAST},
6808#endif
6809#ifdef _PC_LINK_MAX
6810 {"PC_LINK_MAX", _PC_LINK_MAX},
6811#endif
6812#ifdef _PC_MAX_CANON
6813 {"PC_MAX_CANON", _PC_MAX_CANON},
6814#endif
6815#ifdef _PC_MAX_INPUT
6816 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6817#endif
6818#ifdef _PC_NAME_MAX
6819 {"PC_NAME_MAX", _PC_NAME_MAX},
6820#endif
6821#ifdef _PC_NO_TRUNC
6822 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6823#endif
6824#ifdef _PC_PATH_MAX
6825 {"PC_PATH_MAX", _PC_PATH_MAX},
6826#endif
6827#ifdef _PC_PIPE_BUF
6828 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6829#endif
6830#ifdef _PC_PRIO_IO
6831 {"PC_PRIO_IO", _PC_PRIO_IO},
6832#endif
6833#ifdef _PC_SOCK_MAXBUF
6834 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6835#endif
6836#ifdef _PC_SYNC_IO
6837 {"PC_SYNC_IO", _PC_SYNC_IO},
6838#endif
6839#ifdef _PC_VDISABLE
6840 {"PC_VDISABLE", _PC_VDISABLE},
6841#endif
6842};
6843
Fred Drakec9680921999-12-13 16:37:25 +00006844static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006845conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006846{
6847 return conv_confname(arg, valuep, posix_constants_pathconf,
6848 sizeof(posix_constants_pathconf)
6849 / sizeof(struct constdef));
6850}
6851#endif
6852
6853#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006854PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006855"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006856Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006857If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006858
6859static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006860posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006861{
6862 PyObject *result = NULL;
6863 int name, fd;
6864
Fred Drake12c6e2d1999-12-14 21:25:03 +00006865 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6866 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006867 long limit;
6868
6869 errno = 0;
6870 limit = fpathconf(fd, name);
6871 if (limit == -1 && errno != 0)
6872 posix_error();
6873 else
6874 result = PyInt_FromLong(limit);
6875 }
6876 return result;
6877}
6878#endif
6879
6880
6881#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006882PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006883"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006884Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006885If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006886
6887static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006888posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006889{
6890 PyObject *result = NULL;
6891 int name;
6892 char *path;
6893
6894 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6895 conv_path_confname, &name)) {
6896 long limit;
6897
6898 errno = 0;
6899 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006900 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006901 if (errno == EINVAL)
6902 /* could be a path or name problem */
6903 posix_error();
6904 else
6905 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006906 }
Fred Drakec9680921999-12-13 16:37:25 +00006907 else
6908 result = PyInt_FromLong(limit);
6909 }
6910 return result;
6911}
6912#endif
6913
6914#ifdef HAVE_CONFSTR
6915static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006916#ifdef _CS_ARCHITECTURE
6917 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6918#endif
6919#ifdef _CS_HOSTNAME
6920 {"CS_HOSTNAME", _CS_HOSTNAME},
6921#endif
6922#ifdef _CS_HW_PROVIDER
6923 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6924#endif
6925#ifdef _CS_HW_SERIAL
6926 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6927#endif
6928#ifdef _CS_INITTAB_NAME
6929 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6930#endif
Fred Drakec9680921999-12-13 16:37:25 +00006931#ifdef _CS_LFS64_CFLAGS
6932 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6933#endif
6934#ifdef _CS_LFS64_LDFLAGS
6935 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6936#endif
6937#ifdef _CS_LFS64_LIBS
6938 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6939#endif
6940#ifdef _CS_LFS64_LINTFLAGS
6941 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6942#endif
6943#ifdef _CS_LFS_CFLAGS
6944 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6945#endif
6946#ifdef _CS_LFS_LDFLAGS
6947 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6948#endif
6949#ifdef _CS_LFS_LIBS
6950 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6951#endif
6952#ifdef _CS_LFS_LINTFLAGS
6953 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6954#endif
Fred Draked86ed291999-12-15 15:34:33 +00006955#ifdef _CS_MACHINE
6956 {"CS_MACHINE", _CS_MACHINE},
6957#endif
Fred Drakec9680921999-12-13 16:37:25 +00006958#ifdef _CS_PATH
6959 {"CS_PATH", _CS_PATH},
6960#endif
Fred Draked86ed291999-12-15 15:34:33 +00006961#ifdef _CS_RELEASE
6962 {"CS_RELEASE", _CS_RELEASE},
6963#endif
6964#ifdef _CS_SRPC_DOMAIN
6965 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6966#endif
6967#ifdef _CS_SYSNAME
6968 {"CS_SYSNAME", _CS_SYSNAME},
6969#endif
6970#ifdef _CS_VERSION
6971 {"CS_VERSION", _CS_VERSION},
6972#endif
Fred Drakec9680921999-12-13 16:37:25 +00006973#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6974 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6975#endif
6976#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6977 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6978#endif
6979#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6980 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6981#endif
6982#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6983 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6984#endif
6985#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6986 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6987#endif
6988#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6989 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6990#endif
6991#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6992 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6993#endif
6994#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6995 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6996#endif
6997#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6998 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6999#endif
7000#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7001 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7002#endif
7003#ifdef _CS_XBS5_LP64_OFF64_LIBS
7004 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7005#endif
7006#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7007 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7008#endif
7009#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7010 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7011#endif
7012#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7013 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7014#endif
7015#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7016 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7017#endif
7018#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7019 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7020#endif
Fred Draked86ed291999-12-15 15:34:33 +00007021#ifdef _MIPS_CS_AVAIL_PROCESSORS
7022 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7023#endif
7024#ifdef _MIPS_CS_BASE
7025 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7026#endif
7027#ifdef _MIPS_CS_HOSTID
7028 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7029#endif
7030#ifdef _MIPS_CS_HW_NAME
7031 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7032#endif
7033#ifdef _MIPS_CS_NUM_PROCESSORS
7034 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7035#endif
7036#ifdef _MIPS_CS_OSREL_MAJ
7037 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7038#endif
7039#ifdef _MIPS_CS_OSREL_MIN
7040 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7041#endif
7042#ifdef _MIPS_CS_OSREL_PATCH
7043 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7044#endif
7045#ifdef _MIPS_CS_OS_NAME
7046 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7047#endif
7048#ifdef _MIPS_CS_OS_PROVIDER
7049 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7050#endif
7051#ifdef _MIPS_CS_PROCESSORS
7052 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7053#endif
7054#ifdef _MIPS_CS_SERIAL
7055 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7056#endif
7057#ifdef _MIPS_CS_VENDOR
7058 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7059#endif
Fred Drakec9680921999-12-13 16:37:25 +00007060};
7061
7062static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007063conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007064{
7065 return conv_confname(arg, valuep, posix_constants_confstr,
7066 sizeof(posix_constants_confstr)
7067 / sizeof(struct constdef));
7068}
7069
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007070PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007071"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007072Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007073
7074static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007075posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007076{
7077 PyObject *result = NULL;
7078 int name;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007079 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007080
7081 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007082 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007083
Fred Drakec9680921999-12-13 16:37:25 +00007084 errno = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007085 len = confstr(name, buffer, sizeof(buffer));
7086 if (len == 0) {
7087 if (errno) {
7088 posix_error();
7089 }
7090 else {
7091 result = Py_None;
7092 Py_INCREF(Py_None);
7093 }
Fred Drakec9680921999-12-13 16:37:25 +00007094 }
7095 else {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007096 if ((unsigned int)len >= sizeof(buffer)) {
7097 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007098 if (result != NULL)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007099 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00007100 }
7101 else
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007102 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007103 }
7104 }
7105 return result;
7106}
7107#endif
7108
7109
7110#ifdef HAVE_SYSCONF
7111static struct constdef posix_constants_sysconf[] = {
7112#ifdef _SC_2_CHAR_TERM
7113 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7114#endif
7115#ifdef _SC_2_C_BIND
7116 {"SC_2_C_BIND", _SC_2_C_BIND},
7117#endif
7118#ifdef _SC_2_C_DEV
7119 {"SC_2_C_DEV", _SC_2_C_DEV},
7120#endif
7121#ifdef _SC_2_C_VERSION
7122 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7123#endif
7124#ifdef _SC_2_FORT_DEV
7125 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7126#endif
7127#ifdef _SC_2_FORT_RUN
7128 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7129#endif
7130#ifdef _SC_2_LOCALEDEF
7131 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7132#endif
7133#ifdef _SC_2_SW_DEV
7134 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7135#endif
7136#ifdef _SC_2_UPE
7137 {"SC_2_UPE", _SC_2_UPE},
7138#endif
7139#ifdef _SC_2_VERSION
7140 {"SC_2_VERSION", _SC_2_VERSION},
7141#endif
Fred Draked86ed291999-12-15 15:34:33 +00007142#ifdef _SC_ABI_ASYNCHRONOUS_IO
7143 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7144#endif
7145#ifdef _SC_ACL
7146 {"SC_ACL", _SC_ACL},
7147#endif
Fred Drakec9680921999-12-13 16:37:25 +00007148#ifdef _SC_AIO_LISTIO_MAX
7149 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7150#endif
Fred Drakec9680921999-12-13 16:37:25 +00007151#ifdef _SC_AIO_MAX
7152 {"SC_AIO_MAX", _SC_AIO_MAX},
7153#endif
7154#ifdef _SC_AIO_PRIO_DELTA_MAX
7155 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7156#endif
7157#ifdef _SC_ARG_MAX
7158 {"SC_ARG_MAX", _SC_ARG_MAX},
7159#endif
7160#ifdef _SC_ASYNCHRONOUS_IO
7161 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7162#endif
7163#ifdef _SC_ATEXIT_MAX
7164 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7165#endif
Fred Draked86ed291999-12-15 15:34:33 +00007166#ifdef _SC_AUDIT
7167 {"SC_AUDIT", _SC_AUDIT},
7168#endif
Fred Drakec9680921999-12-13 16:37:25 +00007169#ifdef _SC_AVPHYS_PAGES
7170 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7171#endif
7172#ifdef _SC_BC_BASE_MAX
7173 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7174#endif
7175#ifdef _SC_BC_DIM_MAX
7176 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7177#endif
7178#ifdef _SC_BC_SCALE_MAX
7179 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7180#endif
7181#ifdef _SC_BC_STRING_MAX
7182 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7183#endif
Fred Draked86ed291999-12-15 15:34:33 +00007184#ifdef _SC_CAP
7185 {"SC_CAP", _SC_CAP},
7186#endif
Fred Drakec9680921999-12-13 16:37:25 +00007187#ifdef _SC_CHARCLASS_NAME_MAX
7188 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7189#endif
7190#ifdef _SC_CHAR_BIT
7191 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7192#endif
7193#ifdef _SC_CHAR_MAX
7194 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7195#endif
7196#ifdef _SC_CHAR_MIN
7197 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7198#endif
7199#ifdef _SC_CHILD_MAX
7200 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7201#endif
7202#ifdef _SC_CLK_TCK
7203 {"SC_CLK_TCK", _SC_CLK_TCK},
7204#endif
7205#ifdef _SC_COHER_BLKSZ
7206 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7207#endif
7208#ifdef _SC_COLL_WEIGHTS_MAX
7209 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7210#endif
7211#ifdef _SC_DCACHE_ASSOC
7212 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7213#endif
7214#ifdef _SC_DCACHE_BLKSZ
7215 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7216#endif
7217#ifdef _SC_DCACHE_LINESZ
7218 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7219#endif
7220#ifdef _SC_DCACHE_SZ
7221 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7222#endif
7223#ifdef _SC_DCACHE_TBLKSZ
7224 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7225#endif
7226#ifdef _SC_DELAYTIMER_MAX
7227 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7228#endif
7229#ifdef _SC_EQUIV_CLASS_MAX
7230 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7231#endif
7232#ifdef _SC_EXPR_NEST_MAX
7233 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7234#endif
7235#ifdef _SC_FSYNC
7236 {"SC_FSYNC", _SC_FSYNC},
7237#endif
7238#ifdef _SC_GETGR_R_SIZE_MAX
7239 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7240#endif
7241#ifdef _SC_GETPW_R_SIZE_MAX
7242 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7243#endif
7244#ifdef _SC_ICACHE_ASSOC
7245 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7246#endif
7247#ifdef _SC_ICACHE_BLKSZ
7248 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7249#endif
7250#ifdef _SC_ICACHE_LINESZ
7251 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7252#endif
7253#ifdef _SC_ICACHE_SZ
7254 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7255#endif
Fred Draked86ed291999-12-15 15:34:33 +00007256#ifdef _SC_INF
7257 {"SC_INF", _SC_INF},
7258#endif
Fred Drakec9680921999-12-13 16:37:25 +00007259#ifdef _SC_INT_MAX
7260 {"SC_INT_MAX", _SC_INT_MAX},
7261#endif
7262#ifdef _SC_INT_MIN
7263 {"SC_INT_MIN", _SC_INT_MIN},
7264#endif
7265#ifdef _SC_IOV_MAX
7266 {"SC_IOV_MAX", _SC_IOV_MAX},
7267#endif
Fred Draked86ed291999-12-15 15:34:33 +00007268#ifdef _SC_IP_SECOPTS
7269 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7270#endif
Fred Drakec9680921999-12-13 16:37:25 +00007271#ifdef _SC_JOB_CONTROL
7272 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7273#endif
Fred Draked86ed291999-12-15 15:34:33 +00007274#ifdef _SC_KERN_POINTERS
7275 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7276#endif
7277#ifdef _SC_KERN_SIM
7278 {"SC_KERN_SIM", _SC_KERN_SIM},
7279#endif
Fred Drakec9680921999-12-13 16:37:25 +00007280#ifdef _SC_LINE_MAX
7281 {"SC_LINE_MAX", _SC_LINE_MAX},
7282#endif
7283#ifdef _SC_LOGIN_NAME_MAX
7284 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7285#endif
7286#ifdef _SC_LOGNAME_MAX
7287 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7288#endif
7289#ifdef _SC_LONG_BIT
7290 {"SC_LONG_BIT", _SC_LONG_BIT},
7291#endif
Fred Draked86ed291999-12-15 15:34:33 +00007292#ifdef _SC_MAC
7293 {"SC_MAC", _SC_MAC},
7294#endif
Fred Drakec9680921999-12-13 16:37:25 +00007295#ifdef _SC_MAPPED_FILES
7296 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7297#endif
7298#ifdef _SC_MAXPID
7299 {"SC_MAXPID", _SC_MAXPID},
7300#endif
7301#ifdef _SC_MB_LEN_MAX
7302 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7303#endif
7304#ifdef _SC_MEMLOCK
7305 {"SC_MEMLOCK", _SC_MEMLOCK},
7306#endif
7307#ifdef _SC_MEMLOCK_RANGE
7308 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7309#endif
7310#ifdef _SC_MEMORY_PROTECTION
7311 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7312#endif
7313#ifdef _SC_MESSAGE_PASSING
7314 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7315#endif
Fred Draked86ed291999-12-15 15:34:33 +00007316#ifdef _SC_MMAP_FIXED_ALIGNMENT
7317 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7318#endif
Fred Drakec9680921999-12-13 16:37:25 +00007319#ifdef _SC_MQ_OPEN_MAX
7320 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7321#endif
7322#ifdef _SC_MQ_PRIO_MAX
7323 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7324#endif
Fred Draked86ed291999-12-15 15:34:33 +00007325#ifdef _SC_NACLS_MAX
7326 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7327#endif
Fred Drakec9680921999-12-13 16:37:25 +00007328#ifdef _SC_NGROUPS_MAX
7329 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7330#endif
7331#ifdef _SC_NL_ARGMAX
7332 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7333#endif
7334#ifdef _SC_NL_LANGMAX
7335 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7336#endif
7337#ifdef _SC_NL_MSGMAX
7338 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7339#endif
7340#ifdef _SC_NL_NMAX
7341 {"SC_NL_NMAX", _SC_NL_NMAX},
7342#endif
7343#ifdef _SC_NL_SETMAX
7344 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7345#endif
7346#ifdef _SC_NL_TEXTMAX
7347 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7348#endif
7349#ifdef _SC_NPROCESSORS_CONF
7350 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7351#endif
7352#ifdef _SC_NPROCESSORS_ONLN
7353 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7354#endif
Fred Draked86ed291999-12-15 15:34:33 +00007355#ifdef _SC_NPROC_CONF
7356 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7357#endif
7358#ifdef _SC_NPROC_ONLN
7359 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7360#endif
Fred Drakec9680921999-12-13 16:37:25 +00007361#ifdef _SC_NZERO
7362 {"SC_NZERO", _SC_NZERO},
7363#endif
7364#ifdef _SC_OPEN_MAX
7365 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7366#endif
7367#ifdef _SC_PAGESIZE
7368 {"SC_PAGESIZE", _SC_PAGESIZE},
7369#endif
7370#ifdef _SC_PAGE_SIZE
7371 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7372#endif
7373#ifdef _SC_PASS_MAX
7374 {"SC_PASS_MAX", _SC_PASS_MAX},
7375#endif
7376#ifdef _SC_PHYS_PAGES
7377 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7378#endif
7379#ifdef _SC_PII
7380 {"SC_PII", _SC_PII},
7381#endif
7382#ifdef _SC_PII_INTERNET
7383 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7384#endif
7385#ifdef _SC_PII_INTERNET_DGRAM
7386 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7387#endif
7388#ifdef _SC_PII_INTERNET_STREAM
7389 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7390#endif
7391#ifdef _SC_PII_OSI
7392 {"SC_PII_OSI", _SC_PII_OSI},
7393#endif
7394#ifdef _SC_PII_OSI_CLTS
7395 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7396#endif
7397#ifdef _SC_PII_OSI_COTS
7398 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7399#endif
7400#ifdef _SC_PII_OSI_M
7401 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7402#endif
7403#ifdef _SC_PII_SOCKET
7404 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7405#endif
7406#ifdef _SC_PII_XTI
7407 {"SC_PII_XTI", _SC_PII_XTI},
7408#endif
7409#ifdef _SC_POLL
7410 {"SC_POLL", _SC_POLL},
7411#endif
7412#ifdef _SC_PRIORITIZED_IO
7413 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7414#endif
7415#ifdef _SC_PRIORITY_SCHEDULING
7416 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7417#endif
7418#ifdef _SC_REALTIME_SIGNALS
7419 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7420#endif
7421#ifdef _SC_RE_DUP_MAX
7422 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7423#endif
7424#ifdef _SC_RTSIG_MAX
7425 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7426#endif
7427#ifdef _SC_SAVED_IDS
7428 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7429#endif
7430#ifdef _SC_SCHAR_MAX
7431 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7432#endif
7433#ifdef _SC_SCHAR_MIN
7434 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7435#endif
7436#ifdef _SC_SELECT
7437 {"SC_SELECT", _SC_SELECT},
7438#endif
7439#ifdef _SC_SEMAPHORES
7440 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7441#endif
7442#ifdef _SC_SEM_NSEMS_MAX
7443 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7444#endif
7445#ifdef _SC_SEM_VALUE_MAX
7446 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7447#endif
7448#ifdef _SC_SHARED_MEMORY_OBJECTS
7449 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7450#endif
7451#ifdef _SC_SHRT_MAX
7452 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7453#endif
7454#ifdef _SC_SHRT_MIN
7455 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7456#endif
7457#ifdef _SC_SIGQUEUE_MAX
7458 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7459#endif
7460#ifdef _SC_SIGRT_MAX
7461 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7462#endif
7463#ifdef _SC_SIGRT_MIN
7464 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7465#endif
Fred Draked86ed291999-12-15 15:34:33 +00007466#ifdef _SC_SOFTPOWER
7467 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7468#endif
Fred Drakec9680921999-12-13 16:37:25 +00007469#ifdef _SC_SPLIT_CACHE
7470 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7471#endif
7472#ifdef _SC_SSIZE_MAX
7473 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7474#endif
7475#ifdef _SC_STACK_PROT
7476 {"SC_STACK_PROT", _SC_STACK_PROT},
7477#endif
7478#ifdef _SC_STREAM_MAX
7479 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7480#endif
7481#ifdef _SC_SYNCHRONIZED_IO
7482 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7483#endif
7484#ifdef _SC_THREADS
7485 {"SC_THREADS", _SC_THREADS},
7486#endif
7487#ifdef _SC_THREAD_ATTR_STACKADDR
7488 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7489#endif
7490#ifdef _SC_THREAD_ATTR_STACKSIZE
7491 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7492#endif
7493#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7494 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7495#endif
7496#ifdef _SC_THREAD_KEYS_MAX
7497 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7498#endif
7499#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7500 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7501#endif
7502#ifdef _SC_THREAD_PRIO_INHERIT
7503 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7504#endif
7505#ifdef _SC_THREAD_PRIO_PROTECT
7506 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7507#endif
7508#ifdef _SC_THREAD_PROCESS_SHARED
7509 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7510#endif
7511#ifdef _SC_THREAD_SAFE_FUNCTIONS
7512 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7513#endif
7514#ifdef _SC_THREAD_STACK_MIN
7515 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7516#endif
7517#ifdef _SC_THREAD_THREADS_MAX
7518 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7519#endif
7520#ifdef _SC_TIMERS
7521 {"SC_TIMERS", _SC_TIMERS},
7522#endif
7523#ifdef _SC_TIMER_MAX
7524 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7525#endif
7526#ifdef _SC_TTY_NAME_MAX
7527 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7528#endif
7529#ifdef _SC_TZNAME_MAX
7530 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7531#endif
7532#ifdef _SC_T_IOV_MAX
7533 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7534#endif
7535#ifdef _SC_UCHAR_MAX
7536 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7537#endif
7538#ifdef _SC_UINT_MAX
7539 {"SC_UINT_MAX", _SC_UINT_MAX},
7540#endif
7541#ifdef _SC_UIO_MAXIOV
7542 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7543#endif
7544#ifdef _SC_ULONG_MAX
7545 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7546#endif
7547#ifdef _SC_USHRT_MAX
7548 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7549#endif
7550#ifdef _SC_VERSION
7551 {"SC_VERSION", _SC_VERSION},
7552#endif
7553#ifdef _SC_WORD_BIT
7554 {"SC_WORD_BIT", _SC_WORD_BIT},
7555#endif
7556#ifdef _SC_XBS5_ILP32_OFF32
7557 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7558#endif
7559#ifdef _SC_XBS5_ILP32_OFFBIG
7560 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7561#endif
7562#ifdef _SC_XBS5_LP64_OFF64
7563 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7564#endif
7565#ifdef _SC_XBS5_LPBIG_OFFBIG
7566 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7567#endif
7568#ifdef _SC_XOPEN_CRYPT
7569 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7570#endif
7571#ifdef _SC_XOPEN_ENH_I18N
7572 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7573#endif
7574#ifdef _SC_XOPEN_LEGACY
7575 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7576#endif
7577#ifdef _SC_XOPEN_REALTIME
7578 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7579#endif
7580#ifdef _SC_XOPEN_REALTIME_THREADS
7581 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7582#endif
7583#ifdef _SC_XOPEN_SHM
7584 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7585#endif
7586#ifdef _SC_XOPEN_UNIX
7587 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7588#endif
7589#ifdef _SC_XOPEN_VERSION
7590 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7591#endif
7592#ifdef _SC_XOPEN_XCU_VERSION
7593 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7594#endif
7595#ifdef _SC_XOPEN_XPG2
7596 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7597#endif
7598#ifdef _SC_XOPEN_XPG3
7599 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7600#endif
7601#ifdef _SC_XOPEN_XPG4
7602 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7603#endif
7604};
7605
7606static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007607conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007608{
7609 return conv_confname(arg, valuep, posix_constants_sysconf,
7610 sizeof(posix_constants_sysconf)
7611 / sizeof(struct constdef));
7612}
7613
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007614PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007615"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007616Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007617
7618static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007619posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007620{
7621 PyObject *result = NULL;
7622 int name;
7623
7624 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7625 int value;
7626
7627 errno = 0;
7628 value = sysconf(name);
7629 if (value == -1 && errno != 0)
7630 posix_error();
7631 else
7632 result = PyInt_FromLong(value);
7633 }
7634 return result;
7635}
7636#endif
7637
7638
Fred Drakebec628d1999-12-15 18:31:10 +00007639/* This code is used to ensure that the tables of configuration value names
7640 * are in sorted order as required by conv_confname(), and also to build the
7641 * the exported dictionaries that are used to publish information about the
7642 * names available on the host platform.
7643 *
7644 * Sorting the table at runtime ensures that the table is properly ordered
7645 * when used, even for platforms we're not able to test on. It also makes
7646 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007647 */
Fred Drakebec628d1999-12-15 18:31:10 +00007648
7649static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007650cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007651{
7652 const struct constdef *c1 =
7653 (const struct constdef *) v1;
7654 const struct constdef *c2 =
7655 (const struct constdef *) v2;
7656
7657 return strcmp(c1->name, c2->name);
7658}
7659
7660static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007661setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007662 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007663{
Fred Drakebec628d1999-12-15 18:31:10 +00007664 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007665 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007666
7667 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7668 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007669 if (d == NULL)
7670 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007671
Barry Warsaw3155db32000-04-13 15:20:40 +00007672 for (i=0; i < tablesize; ++i) {
7673 PyObject *o = PyInt_FromLong(table[i].value);
7674 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7675 Py_XDECREF(o);
7676 Py_DECREF(d);
7677 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007678 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007679 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007680 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007681 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007682}
7683
Fred Drakebec628d1999-12-15 18:31:10 +00007684/* Return -1 on failure, 0 on success. */
7685static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007686setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007687{
7688#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007689 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007690 sizeof(posix_constants_pathconf)
7691 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007692 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007693 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007694#endif
7695#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007696 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007697 sizeof(posix_constants_confstr)
7698 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007699 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007700 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007701#endif
7702#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007703 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007704 sizeof(posix_constants_sysconf)
7705 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007706 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007707 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007708#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007709 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007710}
Fred Draked86ed291999-12-15 15:34:33 +00007711
7712
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007713PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007714"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007715Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007716in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007717
7718static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007719posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007720{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007721 abort();
7722 /*NOTREACHED*/
7723 Py_FatalError("abort() called from Python code didn't abort!");
7724 return NULL;
7725}
Fred Drakebec628d1999-12-15 18:31:10 +00007726
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007727#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007728PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007729"startfile(filepath [, operation]) - Start a file with its associated\n\
7730application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007731\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007732When \"operation\" is not specified or \"open\", this acts like\n\
7733double-clicking the file in Explorer, or giving the file name as an\n\
7734argument to the DOS \"start\" command: the file is opened with whatever\n\
7735application (if any) its extension is associated.\n\
7736When another \"operation\" is given, it specifies what should be done with\n\
7737the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007738\n\
7739startfile returns as soon as the associated application is launched.\n\
7740There is no option to wait for the application to close, and no way\n\
7741to retrieve the application's exit status.\n\
7742\n\
7743The filepath is relative to the current directory. If you want to use\n\
7744an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007745the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007746
7747static PyObject *
7748win32_startfile(PyObject *self, PyObject *args)
7749{
7750 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00007751 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007752 HINSTANCE rc;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007753#ifdef Py_WIN_WIDE_FILENAMES
7754 if (unicode_file_names()) {
7755 PyObject *unipath, *woperation = NULL;
7756 if (!PyArg_ParseTuple(args, "U|s:startfile",
7757 &unipath, &operation)) {
7758 PyErr_Clear();
7759 goto normal;
7760 }
7761
7762
7763 if (operation) {
7764 woperation = PyUnicode_DecodeASCII(operation,
7765 strlen(operation), NULL);
7766 if (!woperation) {
7767 PyErr_Clear();
7768 operation = NULL;
7769 goto normal;
7770 }
7771 }
7772
7773 Py_BEGIN_ALLOW_THREADS
7774 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
7775 PyUnicode_AS_UNICODE(unipath),
7776 NULL, NULL, SW_SHOWNORMAL);
7777 Py_END_ALLOW_THREADS
7778
7779 Py_XDECREF(woperation);
7780 if (rc <= (HINSTANCE)32) {
7781 PyObject *errval = win32_error_unicode("startfile",
7782 PyUnicode_AS_UNICODE(unipath));
7783 return errval;
7784 }
7785 Py_INCREF(Py_None);
7786 return Py_None;
7787 }
7788#endif
7789
7790normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00007791 if (!PyArg_ParseTuple(args, "et|s:startfile",
7792 Py_FileSystemDefaultEncoding, &filepath,
7793 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00007794 return NULL;
7795 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00007796 rc = ShellExecute((HWND)0, operation, filepath,
7797 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007798 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00007799 if (rc <= (HINSTANCE)32) {
7800 PyObject *errval = win32_error("startfile", filepath);
7801 PyMem_Free(filepath);
7802 return errval;
7803 }
7804 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007805 Py_INCREF(Py_None);
7806 return Py_None;
7807}
7808#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007809
Martin v. Löwis438b5342002-12-27 10:16:42 +00007810#ifdef HAVE_GETLOADAVG
7811PyDoc_STRVAR(posix_getloadavg__doc__,
7812"getloadavg() -> (float, float, float)\n\n\
7813Return the number of processes in the system run queue averaged over\n\
7814the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7815was unobtainable");
7816
7817static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007818posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007819{
7820 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007821 if (getloadavg(loadavg, 3)!=3) {
7822 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7823 return NULL;
7824 } else
7825 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7826}
7827#endif
7828
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007829#ifdef MS_WINDOWS
7830
7831PyDoc_STRVAR(win32_urandom__doc__,
7832"urandom(n) -> str\n\n\
7833Return a string of n random bytes suitable for cryptographic use.");
7834
7835typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7836 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7837 DWORD dwFlags );
7838typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7839 BYTE *pbBuffer );
7840
7841static CRYPTGENRANDOM pCryptGenRandom = NULL;
7842static HCRYPTPROV hCryptProv = 0;
7843
Tim Peters4ad82172004-08-30 17:02:04 +00007844static PyObject*
7845win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007846{
Tim Petersd3115382004-08-30 17:36:46 +00007847 int howMany;
7848 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007849
Tim Peters4ad82172004-08-30 17:02:04 +00007850 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00007851 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00007852 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00007853 if (howMany < 0)
7854 return PyErr_Format(PyExc_ValueError,
7855 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007856
Tim Peters4ad82172004-08-30 17:02:04 +00007857 if (hCryptProv == 0) {
7858 HINSTANCE hAdvAPI32 = NULL;
7859 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007860
Tim Peters4ad82172004-08-30 17:02:04 +00007861 /* Obtain handle to the DLL containing CryptoAPI
7862 This should not fail */
7863 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7864 if(hAdvAPI32 == NULL)
7865 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007866
Tim Peters4ad82172004-08-30 17:02:04 +00007867 /* Obtain pointers to the CryptoAPI functions
7868 This will fail on some early versions of Win95 */
7869 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7870 hAdvAPI32,
7871 "CryptAcquireContextA");
7872 if (pCryptAcquireContext == NULL)
7873 return PyErr_Format(PyExc_NotImplementedError,
7874 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007875
Tim Peters4ad82172004-08-30 17:02:04 +00007876 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7877 hAdvAPI32, "CryptGenRandom");
7878 if (pCryptAcquireContext == NULL)
7879 return PyErr_Format(PyExc_NotImplementedError,
7880 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007881
Tim Peters4ad82172004-08-30 17:02:04 +00007882 /* Acquire context */
7883 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7884 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7885 return win32_error("CryptAcquireContext", NULL);
7886 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007887
Tim Peters4ad82172004-08-30 17:02:04 +00007888 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00007889 result = PyString_FromStringAndSize(NULL, howMany);
7890 if (result != NULL) {
7891 /* Get random data */
7892 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7893 PyString_AS_STRING(result))) {
7894 Py_DECREF(result);
7895 return win32_error("CryptGenRandom", NULL);
7896 }
Tim Peters4ad82172004-08-30 17:02:04 +00007897 }
Tim Petersd3115382004-08-30 17:36:46 +00007898 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007899}
7900#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007901
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007902#ifdef __VMS
7903/* Use openssl random routine */
7904#include <openssl/rand.h>
7905PyDoc_STRVAR(vms_urandom__doc__,
7906"urandom(n) -> str\n\n\
7907Return a string of n random bytes suitable for cryptographic use.");
7908
7909static PyObject*
7910vms_urandom(PyObject *self, PyObject *args)
7911{
7912 int howMany;
7913 PyObject* result;
7914
7915 /* Read arguments */
7916 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7917 return NULL;
7918 if (howMany < 0)
7919 return PyErr_Format(PyExc_ValueError,
7920 "negative argument not allowed");
7921
7922 /* Allocate bytes */
7923 result = PyString_FromStringAndSize(NULL, howMany);
7924 if (result != NULL) {
7925 /* Get random data */
7926 if (RAND_pseudo_bytes((unsigned char*)
7927 PyString_AS_STRING(result),
7928 howMany) < 0) {
7929 Py_DECREF(result);
7930 return PyErr_Format(PyExc_ValueError,
7931 "RAND_pseudo_bytes");
7932 }
7933 }
7934 return result;
7935}
7936#endif
7937
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007938static PyMethodDef posix_methods[] = {
7939 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7940#ifdef HAVE_TTYNAME
7941 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7942#endif
7943 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7944 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007945#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007946 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007947#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007948#ifdef HAVE_LCHOWN
7949 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7950#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007951#ifdef HAVE_CHROOT
7952 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7953#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007954#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007955 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007956#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007957#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007958 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007959#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007960 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007961#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007962#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007963#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007964 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007965#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007966 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7967 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7968 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007969#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007970 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007971#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007972#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007973 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007974#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007975 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7976 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7977 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007978 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007979#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007980 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007981#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007982#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007983 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007984#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007985 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007986#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007987 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007988#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007989 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7990 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7991 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007992#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007993 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007994#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007995 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007996#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007997 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7998 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007999#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008000#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008001 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8002 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008003#if defined(PYOS_OS2)
8004 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8005 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8006#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008007#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008008#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00008009 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008010#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008011#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00008012 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008013#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008014#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00008015 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008016#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008017#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00008018 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008019#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008020#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008021 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008022#endif /* HAVE_GETEGID */
8023#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008024 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008025#endif /* HAVE_GETEUID */
8026#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008027 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008028#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008029#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00008030 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008031#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008032 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008033#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008034 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008035#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008036#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00008037 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008038#endif /* HAVE_GETPPID */
8039#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008040 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008041#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008042#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00008043 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008044#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008045#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008046 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008047#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008048#ifdef HAVE_KILLPG
8049 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8050#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008051#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008052 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008053#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008054#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008055 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008056#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008057 {"popen2", win32_popen2, METH_VARARGS},
8058 {"popen3", win32_popen3, METH_VARARGS},
8059 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00008060 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008061#else
8062#if defined(PYOS_OS2) && defined(PYCC_GCC)
8063 {"popen2", os2emx_popen2, METH_VARARGS},
8064 {"popen3", os2emx_popen3, METH_VARARGS},
8065 {"popen4", os2emx_popen4, METH_VARARGS},
8066#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008067#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008068#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008069#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008070 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008071#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008072#ifdef HAVE_SETEUID
8073 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8074#endif /* HAVE_SETEUID */
8075#ifdef HAVE_SETEGID
8076 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8077#endif /* HAVE_SETEGID */
8078#ifdef HAVE_SETREUID
8079 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8080#endif /* HAVE_SETREUID */
8081#ifdef HAVE_SETREGID
8082 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8083#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008084#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008085 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008086#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008087#ifdef HAVE_SETGROUPS
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00008088 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008089#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008090#ifdef HAVE_GETPGID
8091 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8092#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008093#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008094 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008095#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008096#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00008097 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008098#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008099#ifdef HAVE_WAIT3
8100 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8101#endif /* HAVE_WAIT3 */
8102#ifdef HAVE_WAIT4
8103 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8104#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008105#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008106 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008107#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008108#ifdef HAVE_GETSID
8109 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8110#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008111#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00008112 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008113#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008114#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008115 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008116#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008117#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008118 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008119#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008120#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008121 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008122#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008123 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8124 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8125 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8126 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8127 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8128 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8129 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8130 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8131 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00008132 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008133#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00008134 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008135#endif
8136#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008137 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008138#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008139#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008140 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8141#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008142#ifdef HAVE_DEVICE_MACROS
8143 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8144 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8145 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8146#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008147#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008148 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008149#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008150#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008151 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008152#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008153#ifdef HAVE_UNSETENV
8154 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8155#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00008156#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008157 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00008158#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00008159#ifdef HAVE_FCHDIR
8160 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8161#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008162#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008163 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008164#endif
8165#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008166 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008167#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008168#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008169#ifdef WCOREDUMP
8170 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8171#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008172#ifdef WIFCONTINUED
8173 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8174#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008175#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008176 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008177#endif /* WIFSTOPPED */
8178#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008179 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008180#endif /* WIFSIGNALED */
8181#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008182 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008183#endif /* WIFEXITED */
8184#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008185 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008186#endif /* WEXITSTATUS */
8187#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008188 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008189#endif /* WTERMSIG */
8190#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008191 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008192#endif /* WSTOPSIG */
8193#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008194#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008195 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008196#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00008197#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008198 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008199#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008200#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00008201 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008202#endif
8203#ifdef HAVE_TEMPNAM
8204 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8205#endif
8206#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00008207 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008208#endif
Fred Drakec9680921999-12-13 16:37:25 +00008209#ifdef HAVE_CONFSTR
8210 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8211#endif
8212#ifdef HAVE_SYSCONF
8213 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8214#endif
8215#ifdef HAVE_FPATHCONF
8216 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8217#endif
8218#ifdef HAVE_PATHCONF
8219 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8220#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008221 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008222#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00008223 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8224#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008225#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00008226 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008227#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008228 #ifdef MS_WINDOWS
8229 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8230 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008231 #ifdef __VMS
8232 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8233 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008234 {NULL, NULL} /* Sentinel */
8235};
8236
8237
Barry Warsaw4a342091996-12-19 23:50:02 +00008238static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008239ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008240{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008241 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008242}
8243
Guido van Rossumd48f2521997-12-05 22:19:34 +00008244#if defined(PYOS_OS2)
8245/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008246static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008247{
8248 APIRET rc;
8249 ULONG values[QSV_MAX+1];
8250 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008251 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008252
8253 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008254 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008255 Py_END_ALLOW_THREADS
8256
8257 if (rc != NO_ERROR) {
8258 os2_error(rc);
8259 return -1;
8260 }
8261
Fred Drake4d1e64b2002-04-15 19:40:07 +00008262 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8263 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8264 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8265 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8266 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8267 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8268 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008269
8270 switch (values[QSV_VERSION_MINOR]) {
8271 case 0: ver = "2.00"; break;
8272 case 10: ver = "2.10"; break;
8273 case 11: ver = "2.11"; break;
8274 case 30: ver = "3.00"; break;
8275 case 40: ver = "4.00"; break;
8276 case 50: ver = "5.00"; break;
8277 default:
Tim Peters885d4572001-11-28 20:27:42 +00008278 PyOS_snprintf(tmp, sizeof(tmp),
8279 "%d-%d", values[QSV_VERSION_MAJOR],
8280 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008281 ver = &tmp[0];
8282 }
8283
8284 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008285 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008286 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008287
8288 /* Add Indicator of Which Drive was Used to Boot the System */
8289 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8290 tmp[1] = ':';
8291 tmp[2] = '\0';
8292
Fred Drake4d1e64b2002-04-15 19:40:07 +00008293 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008294}
8295#endif
8296
Barry Warsaw4a342091996-12-19 23:50:02 +00008297static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008298all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008299{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008300#ifdef F_OK
8301 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008302#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008303#ifdef R_OK
8304 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008305#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008306#ifdef W_OK
8307 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008308#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008309#ifdef X_OK
8310 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008311#endif
Fred Drakec9680921999-12-13 16:37:25 +00008312#ifdef NGROUPS_MAX
8313 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8314#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008315#ifdef TMP_MAX
8316 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8317#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008318#ifdef WCONTINUED
8319 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8320#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008321#ifdef WNOHANG
8322 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008323#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008324#ifdef WUNTRACED
8325 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8326#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008327#ifdef O_RDONLY
8328 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8329#endif
8330#ifdef O_WRONLY
8331 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8332#endif
8333#ifdef O_RDWR
8334 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8335#endif
8336#ifdef O_NDELAY
8337 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8338#endif
8339#ifdef O_NONBLOCK
8340 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8341#endif
8342#ifdef O_APPEND
8343 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8344#endif
8345#ifdef O_DSYNC
8346 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8347#endif
8348#ifdef O_RSYNC
8349 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8350#endif
8351#ifdef O_SYNC
8352 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8353#endif
8354#ifdef O_NOCTTY
8355 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8356#endif
8357#ifdef O_CREAT
8358 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8359#endif
8360#ifdef O_EXCL
8361 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8362#endif
8363#ifdef O_TRUNC
8364 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8365#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008366#ifdef O_BINARY
8367 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8368#endif
8369#ifdef O_TEXT
8370 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8371#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008372#ifdef O_LARGEFILE
8373 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8374#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008375#ifdef O_SHLOCK
8376 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8377#endif
8378#ifdef O_EXLOCK
8379 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8380#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008381
Tim Peters5aa91602002-01-30 05:46:57 +00008382/* MS Windows */
8383#ifdef O_NOINHERIT
8384 /* Don't inherit in child processes. */
8385 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8386#endif
8387#ifdef _O_SHORT_LIVED
8388 /* Optimize for short life (keep in memory). */
8389 /* MS forgot to define this one with a non-underscore form too. */
8390 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8391#endif
8392#ifdef O_TEMPORARY
8393 /* Automatically delete when last handle is closed. */
8394 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8395#endif
8396#ifdef O_RANDOM
8397 /* Optimize for random access. */
8398 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8399#endif
8400#ifdef O_SEQUENTIAL
8401 /* Optimize for sequential access. */
8402 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8403#endif
8404
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008405/* GNU extensions. */
8406#ifdef O_DIRECT
8407 /* Direct disk access. */
8408 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8409#endif
8410#ifdef O_DIRECTORY
8411 /* Must be a directory. */
8412 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8413#endif
8414#ifdef O_NOFOLLOW
8415 /* Do not follow links. */
8416 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8417#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008418
Barry Warsaw5676bd12003-01-07 20:57:09 +00008419 /* These come from sysexits.h */
8420#ifdef EX_OK
8421 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008422#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008423#ifdef EX_USAGE
8424 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008425#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008426#ifdef EX_DATAERR
8427 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008428#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008429#ifdef EX_NOINPUT
8430 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008431#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008432#ifdef EX_NOUSER
8433 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008434#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008435#ifdef EX_NOHOST
8436 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008437#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008438#ifdef EX_UNAVAILABLE
8439 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008440#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008441#ifdef EX_SOFTWARE
8442 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008443#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008444#ifdef EX_OSERR
8445 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008446#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008447#ifdef EX_OSFILE
8448 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008449#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008450#ifdef EX_CANTCREAT
8451 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008452#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008453#ifdef EX_IOERR
8454 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008455#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008456#ifdef EX_TEMPFAIL
8457 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008458#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008459#ifdef EX_PROTOCOL
8460 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008461#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008462#ifdef EX_NOPERM
8463 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008464#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008465#ifdef EX_CONFIG
8466 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008467#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008468#ifdef EX_NOTFOUND
8469 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008470#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008471
Guido van Rossum246bc171999-02-01 23:54:31 +00008472#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008473#if defined(PYOS_OS2) && defined(PYCC_GCC)
8474 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8475 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8476 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8477 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8478 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8479 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8480 if (ins(d, "P_PM", (long)P_PM)) return -1;
8481 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8482 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8483 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8484 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8485 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8486 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8487 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8488 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8489 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8490 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8491 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8492 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8493 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8494#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008495 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8496 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8497 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8498 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8499 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008500#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008501#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008502
Guido van Rossumd48f2521997-12-05 22:19:34 +00008503#if defined(PYOS_OS2)
8504 if (insertvalues(d)) return -1;
8505#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008506 return 0;
8507}
8508
8509
Tim Peters5aa91602002-01-30 05:46:57 +00008510#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008511#define INITFUNC initnt
8512#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008513
8514#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008515#define INITFUNC initos2
8516#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008517
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008518#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008519#define INITFUNC initposix
8520#define MODNAME "posix"
8521#endif
8522
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008523PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008524INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008525{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008526 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008527
Fred Drake4d1e64b2002-04-15 19:40:07 +00008528 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008529 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008530 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008531 if (m == NULL)
8532 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008533
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008534 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008535 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008536 Py_XINCREF(v);
8537 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008538 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008539 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008540
Fred Drake4d1e64b2002-04-15 19:40:07 +00008541 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008542 return;
8543
Fred Drake4d1e64b2002-04-15 19:40:07 +00008544 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008545 return;
8546
Fred Drake4d1e64b2002-04-15 19:40:07 +00008547 Py_INCREF(PyExc_OSError);
8548 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008549
Guido van Rossumb3d39562000-01-31 18:41:26 +00008550#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008551 if (posix_putenv_garbage == NULL)
8552 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008553#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008554
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008555 if (!initialized) {
8556 stat_result_desc.name = MODNAME ".stat_result";
8557 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8558 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8559 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8560 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8561 structseq_new = StatResultType.tp_new;
8562 StatResultType.tp_new = statresult_new;
8563
8564 statvfs_result_desc.name = MODNAME ".statvfs_result";
8565 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
8566 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008567 Py_INCREF((PyObject*) &StatResultType);
8568 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008569 Py_INCREF((PyObject*) &StatVFSResultType);
8570 PyModule_AddObject(m, "statvfs_result",
8571 (PyObject*) &StatVFSResultType);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008572 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008573
8574#ifdef __APPLE__
8575 /*
8576 * Step 2 of weak-linking support on Mac OS X.
8577 *
8578 * The code below removes functions that are not available on the
8579 * currently active platform.
8580 *
8581 * This block allow one to use a python binary that was build on
8582 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8583 * OSX 10.4.
8584 */
8585#ifdef HAVE_FSTATVFS
8586 if (fstatvfs == NULL) {
8587 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8588 return;
8589 }
8590 }
8591#endif /* HAVE_FSTATVFS */
8592
8593#ifdef HAVE_STATVFS
8594 if (statvfs == NULL) {
8595 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8596 return;
8597 }
8598 }
8599#endif /* HAVE_STATVFS */
8600
8601# ifdef HAVE_LCHOWN
8602 if (lchown == NULL) {
8603 if (PyObject_DelAttrString(m, "lchown") == -1) {
8604 return;
8605 }
8606 }
8607#endif /* HAVE_LCHOWN */
8608
8609
8610#endif /* __APPLE__ */
8611
Guido van Rossumb6775db1994-08-01 11:34:53 +00008612}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008613
8614#ifdef __cplusplus
8615}
8616#endif
8617