blob: 1900656ff3234ff35fe049a6d30cb825e886e34f [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
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000048#if defined(PYOS_OS2)
49#define INCL_DOS
50#define INCL_DOSERRORS
51#define INCL_DOSPROCESS
52#define INCL_NOPMAPI
53#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000054#if defined(PYCC_GCC)
55#include <ctype.h>
56#include <io.h>
57#include <stdio.h>
58#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000059#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000060#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000061#endif
62
Thomas Wouters0e3f5912006-08-11 14:57:12 +000063#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000064#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000065#endif /* HAVE_SYS_TYPES_H */
66
67#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000068#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000069#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000070
Guido van Rossum36bc6801995-06-14 22:54:23 +000071#ifdef HAVE_SYS_WAIT_H
72#include <sys/wait.h> /* For WNOHANG */
73#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000074
Thomas Wouters0e3f5912006-08-11 14:57:12 +000075#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000076#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000077#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000078
Guido van Rossumb6775db1994-08-01 11:34:53 +000079#ifdef HAVE_FCNTL_H
80#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000081#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000082
Guido van Rossuma6535fd2001-10-18 19:44:10 +000083#ifdef HAVE_GRP_H
84#include <grp.h>
85#endif
86
Barry Warsaw5676bd12003-01-07 20:57:09 +000087#ifdef HAVE_SYSEXITS_H
88#include <sysexits.h>
89#endif /* HAVE_SYSEXITS_H */
90
Anthony Baxter8a560de2004-10-13 15:30:56 +000091#ifdef HAVE_SYS_LOADAVG_H
92#include <sys/loadavg.h>
93#endif
94
Guido van Rossuma4916fa1996-05-23 22:58:55 +000095/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000096/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000097#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000098#include <process.h>
99#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000100#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000101#define HAVE_GETCWD 1
102#define HAVE_OPENDIR 1
103#define HAVE_SYSTEM 1
104#if defined(__OS2__)
105#define HAVE_EXECV 1
106#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000107#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000108#include <process.h>
109#else
110#ifdef __BORLANDC__ /* Borland compiler */
111#define HAVE_EXECV 1
112#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000113#define HAVE_OPENDIR 1
114#define HAVE_PIPE 1
115#define HAVE_POPEN 1
116#define HAVE_SYSTEM 1
117#define HAVE_WAIT 1
118#else
119#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000120#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000121#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000122#define HAVE_EXECV 1
123#define HAVE_PIPE 1
124#define HAVE_POPEN 1
125#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000126#define HAVE_CWAIT 1
Tim Peters11b23062003-04-23 02:39:17 +0000127#define HAVE_FSYNC 1
128#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000129#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000130#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
131/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000132#else /* all other compilers */
133/* Unix functions that the configure script doesn't check for */
134#define HAVE_EXECV 1
135#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000136#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
137#define HAVE_FORK1 1
138#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000139#define HAVE_GETCWD 1
140#define HAVE_GETEGID 1
141#define HAVE_GETEUID 1
142#define HAVE_GETGID 1
143#define HAVE_GETPPID 1
144#define HAVE_GETUID 1
145#define HAVE_KILL 1
146#define HAVE_OPENDIR 1
147#define HAVE_PIPE 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000148#ifndef __rtems__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000149#define HAVE_POPEN 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000150#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000151#define HAVE_SYSTEM 1
152#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000153#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000154#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#endif /* _MSC_VER */
156#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000157#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000158#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000159
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000161
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000162#if defined(__sgi)&&_COMPILER_VERSION>=700
163/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
164 (default) */
165extern char *ctermid_r(char *);
166#endif
167
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000168#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000169#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000170extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000171#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000172#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000173extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000174#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000175extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000176#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000177#endif
178#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000179extern int chdir(char *);
180extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000181#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000182extern int chdir(const char *);
183extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000184#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000185#ifdef __BORLANDC__
186extern int chmod(const char *, int);
187#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000188extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000189#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000190extern int chown(const char *, uid_t, gid_t);
191extern char *getcwd(char *, int);
192extern char *strerror(int);
193extern int link(const char *, const char *);
194extern int rename(const char *, const char *);
195extern int stat(const char *, struct stat *);
196extern int unlink(const char *);
197extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000199extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000200#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000201#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000202extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000203#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000204#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000205
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000206#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000207
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#ifdef HAVE_UTIME_H
209#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000210#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000212#ifdef HAVE_SYS_UTIME_H
213#include <sys/utime.h>
214#define HAVE_UTIME_H /* pretend we do for the rest of this file */
215#endif /* HAVE_SYS_UTIME_H */
216
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217#ifdef HAVE_SYS_TIMES_H
218#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000219#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000220
221#ifdef HAVE_SYS_PARAM_H
222#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000223#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224
225#ifdef HAVE_SYS_UTSNAME_H
226#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000227#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000229#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000230#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000231#define NAMLEN(dirent) strlen((dirent)->d_name)
232#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000233#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000234#include <direct.h>
235#define NAMLEN(dirent) strlen((dirent)->d_name)
236#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000237#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000238#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000239#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000240#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000242#endif
243#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000245#endif
246#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000248#endif
249#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000250
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000251#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000252#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000253#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000254#endif
255#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000257#endif
258#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000259#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000260#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000261#include "osdefs.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000263#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000264#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000265#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000266#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267
Guido van Rossumd48f2521997-12-05 22:19:34 +0000268#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000269#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000270#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000271
Tim Petersbc2e10e2002-03-03 23:17:02 +0000272#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000273#if defined(PATH_MAX) && PATH_MAX > 1024
274#define MAXPATHLEN PATH_MAX
275#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000276#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000277#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000278#endif /* MAXPATHLEN */
279
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000280#ifdef UNION_WAIT
281/* Emulate some macros on systems that have a union instead of macros */
282
283#ifndef WIFEXITED
284#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
285#endif
286
287#ifndef WEXITSTATUS
288#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
289#endif
290
291#ifndef WTERMSIG
292#define WTERMSIG(u_wait) ((u_wait).w_termsig)
293#endif
294
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000295#define WAIT_TYPE union wait
296#define WAIT_STATUS_INT(s) (s.w_status)
297
298#else /* !UNION_WAIT */
299#define WAIT_TYPE int
300#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000301#endif /* UNION_WAIT */
302
Greg Wardb48bc172000-03-01 21:51:56 +0000303/* Don't use the "_r" form if we don't need it (also, won't have a
304 prototype for it, at least on Solaris -- maybe others as well?). */
305#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
306#define USE_CTERMID_R
307#endif
308
309#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
310#define USE_TMPNAM_R
311#endif
312
Fred Drake699f3522000-06-29 21:12:41 +0000313/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000314#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000315#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000316# define STAT win32_stat
317# define FSTAT win32_fstat
318# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000319#else
320# define STAT stat
321# define FSTAT fstat
322# define STRUCT_STAT struct stat
323#endif
324
Tim Peters11b23062003-04-23 02:39:17 +0000325#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000326#include <sys/mkdev.h>
327#else
328#if defined(MAJOR_IN_SYSMACROS)
329#include <sys/sysmacros.h>
330#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000331#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
332#include <sys/mkdev.h>
333#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000334#endif
Fred Drake699f3522000-06-29 21:12:41 +0000335
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000336/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000337#ifdef WITH_NEXT_FRAMEWORK
338/* On Darwin/MacOSX a shared library or framework has no access to
339** environ directly, we must obtain it with _NSGetEnviron().
340*/
341#include <crt_externs.h>
342static char **environ;
343#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000344extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000345#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000346
Barry Warsaw53699e91996-12-10 23:23:01 +0000347static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000348convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000349{
Barry Warsaw53699e91996-12-10 23:23:01 +0000350 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000351 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000352 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000353 if (d == NULL)
354 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000355#ifdef WITH_NEXT_FRAMEWORK
356 if (environ == NULL)
357 environ = *_NSGetEnviron();
358#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000359 if (environ == NULL)
360 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000361 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000362 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000363 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000364 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000365 char *p = strchr(*e, '=');
366 if (p == NULL)
367 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000368 k = PyString_FromStringAndSize(*e, (int)(p-*e));
369 if (k == NULL) {
370 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000371 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000372 }
373 v = PyString_FromString(p+1);
374 if (v == NULL) {
375 PyErr_Clear();
376 Py_DECREF(k);
377 continue;
378 }
379 if (PyDict_GetItem(d, k) == NULL) {
380 if (PyDict_SetItem(d, k, v) != 0)
381 PyErr_Clear();
382 }
383 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000384 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000385 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000386#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000387 {
388 APIRET rc;
389 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
390
391 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000392 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000393 PyObject *v = PyString_FromString(buffer);
394 PyDict_SetItemString(d, "BEGINLIBPATH", v);
395 Py_DECREF(v);
396 }
397 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
398 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
399 PyObject *v = PyString_FromString(buffer);
400 PyDict_SetItemString(d, "ENDLIBPATH", v);
401 Py_DECREF(v);
402 }
403 }
404#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000405 return d;
406}
407
408
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000409/* Set a POSIX-specific error from errno, and return NULL */
410
Barry Warsawd58d7641998-07-23 16:14:40 +0000411static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000412posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000413{
Barry Warsawca74da41999-02-09 19:31:45 +0000414 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000415}
Barry Warsawd58d7641998-07-23 16:14:40 +0000416static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000417posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000418{
Barry Warsawca74da41999-02-09 19:31:45 +0000419 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000420}
421
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000422#ifdef Py_WIN_WIDE_FILENAMES
423static PyObject *
424posix_error_with_unicode_filename(Py_UNICODE* name)
425{
426 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
427}
428#endif /* Py_WIN_WIDE_FILENAMES */
429
430
Mark Hammondef8b6542001-05-13 08:04:26 +0000431static PyObject *
432posix_error_with_allocated_filename(char* name)
433{
434 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
435 PyMem_Free(name);
436 return rc;
437}
438
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000439#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000440static PyObject *
441win32_error(char* function, char* filename)
442{
Mark Hammond33a6da92000-08-15 00:46:38 +0000443 /* XXX We should pass the function name along in the future.
444 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000445 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000446 Windows error object, which is non-trivial.
447 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000448 errno = GetLastError();
449 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000450 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000451 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000452 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000453}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000454
455#ifdef Py_WIN_WIDE_FILENAMES
456static PyObject *
457win32_error_unicode(char* function, Py_UNICODE* filename)
458{
459 /* XXX - see win32_error for comments on 'function' */
460 errno = GetLastError();
461 if (filename)
462 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
463 else
464 return PyErr_SetFromWindowsErr(errno);
465}
466
467static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
468{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000469}
470
471/* Function suitable for O& conversion */
472static int
473convert_to_unicode(PyObject *arg, void* _param)
474{
475 PyObject **param = (PyObject**)_param;
476 if (PyUnicode_CheckExact(arg)) {
477 Py_INCREF(arg);
478 *param = arg;
479 }
480 else if (PyUnicode_Check(arg)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000481 /* For a Unicode subtype that's not a Unicode object,
482 return a true Unicode object with the same data. */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000483 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(arg),
484 PyUnicode_GET_SIZE(arg));
485 return *param != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000486 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000487 else
488 *param = PyUnicode_FromEncodedObject(arg,
489 Py_FileSystemDefaultEncoding,
490 "strict");
491 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000492}
493
494#endif /* Py_WIN_WIDE_FILENAMES */
495
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000496#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000497
Guido van Rossumd48f2521997-12-05 22:19:34 +0000498#if defined(PYOS_OS2)
499/**********************************************************************
500 * Helper Function to Trim and Format OS/2 Messages
501 **********************************************************************/
502 static void
503os2_formatmsg(char *msgbuf, int msglen, char *reason)
504{
505 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
506
507 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
508 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
509
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000510 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000511 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
512 }
513
514 /* Add Optional Reason Text */
515 if (reason) {
516 strcat(msgbuf, " : ");
517 strcat(msgbuf, reason);
518 }
519}
520
521/**********************************************************************
522 * Decode an OS/2 Operating System Error Code
523 *
524 * A convenience function to lookup an OS/2 error code and return a
525 * text message we can use to raise a Python exception.
526 *
527 * Notes:
528 * The messages for errors returned from the OS/2 kernel reside in
529 * the file OSO001.MSG in the \OS2 directory hierarchy.
530 *
531 **********************************************************************/
532 static char *
533os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
534{
535 APIRET rc;
536 ULONG msglen;
537
538 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
539 Py_BEGIN_ALLOW_THREADS
540 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
541 errorcode, "oso001.msg", &msglen);
542 Py_END_ALLOW_THREADS
543
544 if (rc == NO_ERROR)
545 os2_formatmsg(msgbuf, msglen, reason);
546 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000547 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000548 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000549
550 return msgbuf;
551}
552
553/* Set an OS/2-specific error and return NULL. OS/2 kernel
554 errors are not in a global variable e.g. 'errno' nor are
555 they congruent with posix error numbers. */
556
557static PyObject * os2_error(int code)
558{
559 char text[1024];
560 PyObject *v;
561
562 os2_strerror(text, sizeof(text), code, "");
563
564 v = Py_BuildValue("(is)", code, text);
565 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000566 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000567 Py_DECREF(v);
568 }
569 return NULL; /* Signal to Python that an Exception is Pending */
570}
571
572#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000573
574/* POSIX generic methods */
575
Barry Warsaw53699e91996-12-10 23:23:01 +0000576static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000577posix_fildes(PyObject *fdobj, int (*func)(int))
578{
579 int fd;
580 int res;
581 fd = PyObject_AsFileDescriptor(fdobj);
582 if (fd < 0)
583 return NULL;
584 Py_BEGIN_ALLOW_THREADS
585 res = (*func)(fd);
586 Py_END_ALLOW_THREADS
587 if (res < 0)
588 return posix_error();
589 Py_INCREF(Py_None);
590 return Py_None;
591}
Guido van Rossum21142a01999-01-08 21:05:37 +0000592
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000593#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000594static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000595unicode_file_names(void)
596{
597 static int canusewide = -1;
598 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000599 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000600 the Windows NT family. */
601 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
602 }
603 return canusewide;
604}
605#endif
Tim Peters11b23062003-04-23 02:39:17 +0000606
Guido van Rossum21142a01999-01-08 21:05:37 +0000607static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000608posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000609{
Mark Hammondef8b6542001-05-13 08:04:26 +0000610 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000611 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000612 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000613 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000614 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000615 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000616 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000617 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000618 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000619 return posix_error_with_allocated_filename(path1);
620 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000621 Py_INCREF(Py_None);
622 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000623}
624
Barry Warsaw53699e91996-12-10 23:23:01 +0000625static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000626posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000627 char *format,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000628 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000629{
Mark Hammondef8b6542001-05-13 08:04:26 +0000630 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000631 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000632 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000633 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000634 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000635 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000636 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000637 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000638 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000639 PyMem_Free(path1);
640 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000641 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000642 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000643 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000644 Py_INCREF(Py_None);
645 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000646}
647
Thomas Wouters477c8d52006-05-27 19:21:47 +0000648#ifdef Py_WIN_WIDE_FILENAMES
649static PyObject*
650win32_1str(PyObject* args, char* func,
651 char* format, BOOL (__stdcall *funcA)(LPCSTR),
652 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
653{
654 PyObject *uni;
655 char *ansi;
656 BOOL result;
657 if (unicode_file_names()) {
658 if (!PyArg_ParseTuple(args, wformat, &uni))
659 PyErr_Clear();
660 else {
661 Py_BEGIN_ALLOW_THREADS
662 result = funcW(PyUnicode_AsUnicode(uni));
663 Py_END_ALLOW_THREADS
664 if (!result)
665 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
666 Py_INCREF(Py_None);
667 return Py_None;
668 }
669 }
670 if (!PyArg_ParseTuple(args, format, &ansi))
671 return NULL;
672 Py_BEGIN_ALLOW_THREADS
673 result = funcA(ansi);
674 Py_END_ALLOW_THREADS
675 if (!result)
676 return win32_error(func, ansi);
677 Py_INCREF(Py_None);
678 return Py_None;
679
680}
681
682/* This is a reimplementation of the C library's chdir function,
683 but one that produces Win32 errors instead of DOS error codes.
684 chdir is essentially a wrapper around SetCurrentDirectory; however,
685 it also needs to set "magic" environment variables indicating
686 the per-drive current directory, which are of the form =<drive>: */
687BOOL __stdcall
688win32_chdir(LPCSTR path)
689{
690 char new_path[MAX_PATH+1];
691 int result;
692 char env[4] = "=x:";
693
694 if(!SetCurrentDirectoryA(path))
695 return FALSE;
696 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
697 if (!result)
698 return FALSE;
699 /* In the ANSI API, there should not be any paths longer
700 than MAX_PATH. */
701 assert(result <= MAX_PATH+1);
702 if (strncmp(new_path, "\\\\", 2) == 0 ||
703 strncmp(new_path, "//", 2) == 0)
704 /* UNC path, nothing to do. */
705 return TRUE;
706 env[1] = new_path[0];
707 return SetEnvironmentVariableA(env, new_path);
708}
709
710/* The Unicode version differs from the ANSI version
711 since the current directory might exceed MAX_PATH characters */
712BOOL __stdcall
713win32_wchdir(LPCWSTR path)
714{
715 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
716 int result;
717 wchar_t env[4] = L"=x:";
718
719 if(!SetCurrentDirectoryW(path))
720 return FALSE;
721 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
722 if (!result)
723 return FALSE;
724 if (result > MAX_PATH+1) {
725 new_path = malloc(result);
726 if (!new_path) {
727 SetLastError(ERROR_OUTOFMEMORY);
728 return FALSE;
729 }
730 }
731 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
732 wcsncmp(new_path, L"//", 2) == 0)
733 /* UNC path, nothing to do. */
734 return TRUE;
735 env[1] = new_path[0];
736 result = SetEnvironmentVariableW(env, new_path);
737 if (new_path != _new_path)
738 free(new_path);
739 return result;
740}
741#endif
742
Martin v. Löwis14694662006-02-03 12:54:16 +0000743#ifdef MS_WINDOWS
744/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
745 - time stamps are restricted to second resolution
746 - file modification times suffer from forth-and-back conversions between
747 UTC and local time
748 Therefore, we implement our own stat, based on the Win32 API directly.
749*/
750#define HAVE_STAT_NSEC 1
751
752struct win32_stat{
753 int st_dev;
754 __int64 st_ino;
755 unsigned short st_mode;
756 int st_nlink;
757 int st_uid;
758 int st_gid;
759 int st_rdev;
760 __int64 st_size;
761 int st_atime;
762 int st_atime_nsec;
763 int st_mtime;
764 int st_mtime_nsec;
765 int st_ctime;
766 int st_ctime_nsec;
767};
768
769static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
770
771static void
772FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
773{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000774 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
775 /* Cannot simply cast and dereference in_ptr,
776 since it might not be aligned properly */
777 __int64 in;
778 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000779 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
780 /* XXX Win32 supports time stamps past 2038; we currently don't */
781 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
782}
783
Thomas Wouters477c8d52006-05-27 19:21:47 +0000784static void
785time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
786{
787 /* XXX endianness */
788 __int64 out;
789 out = time_in + secs_between_epochs;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000790 out = out * 10000000 + nsec_in / 100;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000791 memcpy(out_ptr, &out, sizeof(out));
792}
793
Martin v. Löwis14694662006-02-03 12:54:16 +0000794/* Below, we *know* that ugo+r is 0444 */
795#if _S_IREAD != 0400
796#error Unsupported C library
797#endif
798static int
799attributes_to_mode(DWORD attr)
800{
801 int m = 0;
802 if (attr & FILE_ATTRIBUTE_DIRECTORY)
803 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
804 else
805 m |= _S_IFREG;
806 if (attr & FILE_ATTRIBUTE_READONLY)
807 m |= 0444;
808 else
809 m |= 0666;
810 return m;
811}
812
813static int
814attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
815{
816 memset(result, 0, sizeof(*result));
817 result->st_mode = attributes_to_mode(info->dwFileAttributes);
818 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
819 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
820 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
821 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
822
823 return 0;
824}
825
Thomas Wouters89f507f2006-12-13 04:49:30 +0000826/* Emulate GetFileAttributesEx[AW] on Windows 95 */
827static int checked = 0;
828static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
829static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
830static void
831check_gfax()
832{
833 HINSTANCE hKernel32;
834 if (checked)
835 return;
836 checked = 1;
837 hKernel32 = GetModuleHandle("KERNEL32");
838 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
839 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
840}
841
Guido van Rossumd8faa362007-04-27 19:54:29 +0000842static BOOL
843attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
844{
845 HANDLE hFindFile;
846 WIN32_FIND_DATAA FileData;
847 hFindFile = FindFirstFileA(pszFile, &FileData);
848 if (hFindFile == INVALID_HANDLE_VALUE)
849 return FALSE;
850 FindClose(hFindFile);
851 pfad->dwFileAttributes = FileData.dwFileAttributes;
852 pfad->ftCreationTime = FileData.ftCreationTime;
853 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
854 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
855 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
856 pfad->nFileSizeLow = FileData.nFileSizeLow;
857 return TRUE;
858}
859
860static BOOL
861attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
862{
863 HANDLE hFindFile;
864 WIN32_FIND_DATAW FileData;
865 hFindFile = FindFirstFileW(pszFile, &FileData);
866 if (hFindFile == INVALID_HANDLE_VALUE)
867 return FALSE;
868 FindClose(hFindFile);
869 pfad->dwFileAttributes = FileData.dwFileAttributes;
870 pfad->ftCreationTime = FileData.ftCreationTime;
871 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
872 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
873 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
874 pfad->nFileSizeLow = FileData.nFileSizeLow;
875 return TRUE;
876}
877
Thomas Wouters89f507f2006-12-13 04:49:30 +0000878static BOOL WINAPI
879Py_GetFileAttributesExA(LPCSTR pszFile,
880 GET_FILEEX_INFO_LEVELS level,
881 LPVOID pv)
882{
883 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000884 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
885 /* First try to use the system's implementation, if that is
886 available and either succeeds to gives an error other than
887 that it isn't implemented. */
888 check_gfax();
889 if (gfaxa) {
890 result = gfaxa(pszFile, level, pv);
891 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
892 return result;
893 }
894 /* It's either not present, or not implemented.
895 Emulate using FindFirstFile. */
896 if (level != GetFileExInfoStandard) {
897 SetLastError(ERROR_INVALID_PARAMETER);
898 return FALSE;
899 }
900 /* Use GetFileAttributes to validate that the file name
901 does not contain wildcards (which FindFirstFile would
902 accept). */
903 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
904 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000905 return attributes_from_dir(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +0000906}
907
908static BOOL WINAPI
909Py_GetFileAttributesExW(LPCWSTR pszFile,
910 GET_FILEEX_INFO_LEVELS level,
911 LPVOID pv)
912{
913 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000914 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
915 /* First try to use the system's implementation, if that is
916 available and either succeeds to gives an error other than
917 that it isn't implemented. */
918 check_gfax();
919 if (gfaxa) {
920 result = gfaxw(pszFile, level, pv);
921 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
922 return result;
923 }
924 /* It's either not present, or not implemented.
925 Emulate using FindFirstFile. */
926 if (level != GetFileExInfoStandard) {
927 SetLastError(ERROR_INVALID_PARAMETER);
928 return FALSE;
929 }
930 /* Use GetFileAttributes to validate that the file name
931 does not contain wildcards (which FindFirstFile would
932 accept). */
933 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
934 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000935 return attributes_from_dir_w(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +0000936}
937
Martin v. Löwis14694662006-02-03 12:54:16 +0000938static int
939win32_stat(const char* path, struct win32_stat *result)
940{
941 WIN32_FILE_ATTRIBUTE_DATA info;
942 int code;
943 char *dot;
944 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +0000945 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +0000946 if (GetLastError() != ERROR_SHARING_VIOLATION) {
947 /* Protocol violation: we explicitly clear errno, instead of
948 setting it to a POSIX error. Callers should use GetLastError. */
949 errno = 0;
950 return -1;
951 } else {
952 /* Could not get attributes on open file. Fall back to
953 reading the directory. */
954 if (!attributes_from_dir(path, &info)) {
955 /* Very strange. This should not fail now */
956 errno = 0;
957 return -1;
958 }
959 }
Martin v. Löwis14694662006-02-03 12:54:16 +0000960 }
961 code = attribute_data_to_stat(&info, result);
962 if (code != 0)
963 return code;
964 /* Set S_IFEXEC if it is an .exe, .bat, ... */
965 dot = strrchr(path, '.');
966 if (dot) {
967 if (stricmp(dot, ".bat") == 0 ||
968 stricmp(dot, ".cmd") == 0 ||
969 stricmp(dot, ".exe") == 0 ||
970 stricmp(dot, ".com") == 0)
971 result->st_mode |= 0111;
972 }
973 return code;
974}
975
976static int
977win32_wstat(const wchar_t* path, struct win32_stat *result)
978{
979 int code;
980 const wchar_t *dot;
981 WIN32_FILE_ATTRIBUTE_DATA info;
982 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +0000983 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +0000984 if (GetLastError() != ERROR_SHARING_VIOLATION) {
985 /* Protocol violation: we explicitly clear errno, instead of
986 setting it to a POSIX error. Callers should use GetLastError. */
987 errno = 0;
988 return -1;
989 } else {
990 /* Could not get attributes on open file. Fall back to
991 reading the directory. */
992 if (!attributes_from_dir_w(path, &info)) {
993 /* Very strange. This should not fail now */
994 errno = 0;
995 return -1;
996 }
997 }
Martin v. Löwis14694662006-02-03 12:54:16 +0000998 }
999 code = attribute_data_to_stat(&info, result);
1000 if (code < 0)
1001 return code;
1002 /* Set IFEXEC if it is an .exe, .bat, ... */
1003 dot = wcsrchr(path, '.');
1004 if (dot) {
1005 if (_wcsicmp(dot, L".bat") == 0 ||
1006 _wcsicmp(dot, L".cmd") == 0 ||
1007 _wcsicmp(dot, L".exe") == 0 ||
1008 _wcsicmp(dot, L".com") == 0)
1009 result->st_mode |= 0111;
1010 }
1011 return code;
1012}
1013
1014static int
1015win32_fstat(int file_number, struct win32_stat *result)
1016{
1017 BY_HANDLE_FILE_INFORMATION info;
1018 HANDLE h;
1019 int type;
1020
1021 h = (HANDLE)_get_osfhandle(file_number);
1022
1023 /* Protocol violation: we explicitly clear errno, instead of
1024 setting it to a POSIX error. Callers should use GetLastError. */
1025 errno = 0;
1026
1027 if (h == INVALID_HANDLE_VALUE) {
1028 /* This is really a C library error (invalid file handle).
1029 We set the Win32 error to the closes one matching. */
1030 SetLastError(ERROR_INVALID_HANDLE);
1031 return -1;
1032 }
1033 memset(result, 0, sizeof(*result));
1034
1035 type = GetFileType(h);
1036 if (type == FILE_TYPE_UNKNOWN) {
1037 DWORD error = GetLastError();
1038 if (error != 0) {
1039 return -1;
1040 }
1041 /* else: valid but unknown file */
1042 }
1043
1044 if (type != FILE_TYPE_DISK) {
1045 if (type == FILE_TYPE_CHAR)
1046 result->st_mode = _S_IFCHR;
1047 else if (type == FILE_TYPE_PIPE)
1048 result->st_mode = _S_IFIFO;
1049 return 0;
1050 }
1051
1052 if (!GetFileInformationByHandle(h, &info)) {
1053 return -1;
1054 }
1055
1056 /* similar to stat() */
1057 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1058 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1059 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1060 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1061 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1062 /* specific to fstat() */
1063 result->st_nlink = info.nNumberOfLinks;
1064 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1065 return 0;
1066}
1067
1068#endif /* MS_WINDOWS */
1069
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001070PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001071"stat_result: Result from stat or lstat.\n\n\
1072This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001073 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001074or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1075\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001076Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1077or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001078\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001079See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001080
1081static PyStructSequence_Field stat_result_fields[] = {
1082 {"st_mode", "protection bits"},
1083 {"st_ino", "inode"},
1084 {"st_dev", "device"},
1085 {"st_nlink", "number of hard links"},
1086 {"st_uid", "user ID of owner"},
1087 {"st_gid", "group ID of owner"},
1088 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001089 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1090 {NULL, "integer time of last access"},
1091 {NULL, "integer time of last modification"},
1092 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001093 {"st_atime", "time of last access"},
1094 {"st_mtime", "time of last modification"},
1095 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001096#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001097 {"st_blksize", "blocksize for filesystem I/O"},
1098#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001099#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001100 {"st_blocks", "number of blocks allocated"},
1101#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001102#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001103 {"st_rdev", "device type (if inode device)"},
1104#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001105#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1106 {"st_flags", "user defined flags for file"},
1107#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001108#ifdef HAVE_STRUCT_STAT_ST_GEN
1109 {"st_gen", "generation number"},
1110#endif
1111#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1112 {"st_birthtime", "time of creation"},
1113#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001114 {0}
1115};
1116
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001117#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001118#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001119#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001120#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001121#endif
1122
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001123#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001124#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1125#else
1126#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1127#endif
1128
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001129#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001130#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1131#else
1132#define ST_RDEV_IDX ST_BLOCKS_IDX
1133#endif
1134
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001135#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1136#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1137#else
1138#define ST_FLAGS_IDX ST_RDEV_IDX
1139#endif
1140
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001141#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001142#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001143#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001144#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001145#endif
1146
1147#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1148#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1149#else
1150#define ST_BIRTHTIME_IDX ST_GEN_IDX
1151#endif
1152
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001153static PyStructSequence_Desc stat_result_desc = {
1154 "stat_result", /* name */
1155 stat_result__doc__, /* doc */
1156 stat_result_fields,
1157 10
1158};
1159
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001160PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001161"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1162This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001163 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001164or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001165\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001166See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001167
1168static PyStructSequence_Field statvfs_result_fields[] = {
1169 {"f_bsize", },
1170 {"f_frsize", },
1171 {"f_blocks", },
1172 {"f_bfree", },
1173 {"f_bavail", },
1174 {"f_files", },
1175 {"f_ffree", },
1176 {"f_favail", },
1177 {"f_flag", },
1178 {"f_namemax",},
1179 {0}
1180};
1181
1182static PyStructSequence_Desc statvfs_result_desc = {
1183 "statvfs_result", /* name */
1184 statvfs_result__doc__, /* doc */
1185 statvfs_result_fields,
1186 10
1187};
1188
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001189static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001190static PyTypeObject StatResultType;
1191static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001192static newfunc structseq_new;
1193
1194static PyObject *
1195statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1196{
1197 PyStructSequence *result;
1198 int i;
1199
1200 result = (PyStructSequence*)structseq_new(type, args, kwds);
1201 if (!result)
1202 return NULL;
1203 /* If we have been initialized from a tuple,
1204 st_?time might be set to None. Initialize it
1205 from the int slots. */
1206 for (i = 7; i <= 9; i++) {
1207 if (result->ob_item[i+3] == Py_None) {
1208 Py_DECREF(Py_None);
1209 Py_INCREF(result->ob_item[i]);
1210 result->ob_item[i+3] = result->ob_item[i];
1211 }
1212 }
1213 return (PyObject*)result;
1214}
1215
1216
1217
1218/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001219static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001220
1221PyDoc_STRVAR(stat_float_times__doc__,
1222"stat_float_times([newval]) -> oldval\n\n\
1223Determine whether os.[lf]stat represents time stamps as float objects.\n\
1224If newval is True, future calls to stat() return floats, if it is False,\n\
1225future calls return ints. \n\
1226If newval is omitted, return the current setting.\n");
1227
1228static PyObject*
1229stat_float_times(PyObject* self, PyObject *args)
1230{
1231 int newval = -1;
1232 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1233 return NULL;
1234 if (newval == -1)
1235 /* Return old value */
1236 return PyBool_FromLong(_stat_float_times);
1237 _stat_float_times = newval;
1238 Py_INCREF(Py_None);
1239 return Py_None;
1240}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001241
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001242static void
1243fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1244{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001245 PyObject *fval,*ival;
1246#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001247 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001248#else
1249 ival = PyInt_FromLong((long)sec);
1250#endif
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001251 if (!ival)
1252 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001253 if (_stat_float_times) {
1254 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1255 } else {
1256 fval = ival;
1257 Py_INCREF(fval);
1258 }
1259 PyStructSequence_SET_ITEM(v, index, ival);
1260 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001261}
1262
Tim Peters5aa91602002-01-30 05:46:57 +00001263/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001264 (used by posix_stat() and posix_fstat()) */
1265static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001266_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001267{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001268 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001269 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001270 if (v == NULL)
1271 return NULL;
1272
Martin v. Löwis14694662006-02-03 12:54:16 +00001273 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001274#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001275 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001276 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001277#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001278 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001279#endif
1280#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001281 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001282 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001283#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001284 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001285#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001286 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1287 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1288 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001289#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001290 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001291 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001292#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001293 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001294#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001295
Martin v. Löwis14694662006-02-03 12:54:16 +00001296#if defined(HAVE_STAT_TV_NSEC)
1297 ansec = st->st_atim.tv_nsec;
1298 mnsec = st->st_mtim.tv_nsec;
1299 cnsec = st->st_ctim.tv_nsec;
1300#elif defined(HAVE_STAT_TV_NSEC2)
1301 ansec = st->st_atimespec.tv_nsec;
1302 mnsec = st->st_mtimespec.tv_nsec;
1303 cnsec = st->st_ctimespec.tv_nsec;
1304#elif defined(HAVE_STAT_NSEC)
1305 ansec = st->st_atime_nsec;
1306 mnsec = st->st_mtime_nsec;
1307 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001308#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001309 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001310#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001311 fill_time(v, 7, st->st_atime, ansec);
1312 fill_time(v, 8, st->st_mtime, mnsec);
1313 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001314
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001315#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001316 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001317 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001318#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001319#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001320 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001321 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001322#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001323#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001324 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001325 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001326#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001327#ifdef HAVE_STRUCT_STAT_ST_GEN
1328 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001329 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001330#endif
1331#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1332 {
1333 PyObject *val;
1334 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001335 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001336#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001337 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001338#else
1339 bnsec = 0;
1340#endif
1341 if (_stat_float_times) {
1342 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1343 } else {
1344 val = PyInt_FromLong((long)bsec);
1345 }
1346 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1347 val);
1348 }
1349#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001350#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1351 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001352 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001353#endif
Fred Drake699f3522000-06-29 21:12:41 +00001354
1355 if (PyErr_Occurred()) {
1356 Py_DECREF(v);
1357 return NULL;
1358 }
1359
1360 return v;
1361}
1362
Martin v. Löwisd8948722004-06-02 09:57:56 +00001363#ifdef MS_WINDOWS
1364
1365/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1366 where / can be used in place of \ and the trailing slash is optional.
1367 Both SERVER and SHARE must have at least one character.
1368*/
1369
1370#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1371#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001372#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001373#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001374#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001375
Tim Peters4ad82172004-08-30 17:02:04 +00001376static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001377IsUNCRootA(char *path, int pathlen)
1378{
1379 #define ISSLASH ISSLASHA
1380
1381 int i, share;
1382
1383 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1384 /* minimum UNCRoot is \\x\y */
1385 return FALSE;
1386 for (i = 2; i < pathlen ; i++)
1387 if (ISSLASH(path[i])) break;
1388 if (i == 2 || i == pathlen)
1389 /* do not allow \\\SHARE or \\SERVER */
1390 return FALSE;
1391 share = i+1;
1392 for (i = share; i < pathlen; i++)
1393 if (ISSLASH(path[i])) break;
1394 return (i != share && (i == pathlen || i == pathlen-1));
1395
1396 #undef ISSLASH
1397}
1398
1399#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001400static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001401IsUNCRootW(Py_UNICODE *path, int pathlen)
1402{
1403 #define ISSLASH ISSLASHW
1404
1405 int i, share;
1406
1407 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1408 /* minimum UNCRoot is \\x\y */
1409 return FALSE;
1410 for (i = 2; i < pathlen ; i++)
1411 if (ISSLASH(path[i])) break;
1412 if (i == 2 || i == pathlen)
1413 /* do not allow \\\SHARE or \\SERVER */
1414 return FALSE;
1415 share = i+1;
1416 for (i = share; i < pathlen; i++)
1417 if (ISSLASH(path[i])) break;
1418 return (i != share && (i == pathlen || i == pathlen-1));
1419
1420 #undef ISSLASH
1421}
1422#endif /* Py_WIN_WIDE_FILENAMES */
1423#endif /* MS_WINDOWS */
1424
Barry Warsaw53699e91996-12-10 23:23:01 +00001425static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001426posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001427 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001428#ifdef __VMS
1429 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1430#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001431 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001432#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001433 char *wformat,
1434 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001435{
Fred Drake699f3522000-06-29 21:12:41 +00001436 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001437 char *path = NULL; /* pass this to stat; do not free() it */
1438 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001439 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001440 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001441
1442#ifdef Py_WIN_WIDE_FILENAMES
1443 /* If on wide-character-capable OS see if argument
1444 is Unicode and if so use wide API. */
1445 if (unicode_file_names()) {
1446 PyUnicodeObject *po;
1447 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001448 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1449
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001450 Py_BEGIN_ALLOW_THREADS
1451 /* PyUnicode_AS_UNICODE result OK without
1452 thread lock as it is a simple dereference. */
1453 res = wstatfunc(wpath, &st);
1454 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001455
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001456 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001457 return win32_error_unicode("stat", wpath);
1458 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001459 }
1460 /* Drop the argument parsing error as narrow strings
1461 are also valid. */
1462 PyErr_Clear();
1463 }
1464#endif
1465
Tim Peters5aa91602002-01-30 05:46:57 +00001466 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001467 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001468 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001469 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001470
Barry Warsaw53699e91996-12-10 23:23:01 +00001471 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001472 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001473 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001474
1475 if (res != 0) {
1476#ifdef MS_WINDOWS
1477 result = win32_error("stat", pathfree);
1478#else
1479 result = posix_error_with_filename(pathfree);
1480#endif
1481 }
1482 else
1483 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001484
Tim Peters500bd032001-12-19 19:05:01 +00001485 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001486 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001487}
1488
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001489/* POSIX methods */
1490
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001491PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001492"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001493Use the real uid/gid to test for access to a path. Note that most\n\
1494operations will use the effective uid/gid, therefore this routine can\n\
1495be used in a suid/sgid environment to test if the invoking user has the\n\
1496specified access to the path. The mode argument can be F_OK to test\n\
1497existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001498
1499static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001500posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001501{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001502 char *path;
1503 int mode;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001504
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001505#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001506 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001507 if (unicode_file_names()) {
1508 PyUnicodeObject *po;
1509 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1510 Py_BEGIN_ALLOW_THREADS
1511 /* PyUnicode_AS_UNICODE OK without thread lock as
1512 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001513 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001514 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001515 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001516 }
1517 /* Drop the argument parsing error as narrow strings
1518 are also valid. */
1519 PyErr_Clear();
1520 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001521 if (!PyArg_ParseTuple(args, "eti:access",
1522 Py_FileSystemDefaultEncoding, &path, &mode))
1523 return 0;
1524 Py_BEGIN_ALLOW_THREADS
1525 attr = GetFileAttributesA(path);
1526 Py_END_ALLOW_THREADS
1527 PyMem_Free(path);
1528finish:
1529 if (attr == 0xFFFFFFFF)
1530 /* File does not exist, or cannot read attributes */
1531 return PyBool_FromLong(0);
1532 /* Access is possible if either write access wasn't requested, or
1533 the file isn't read-only. */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001534 return PyBool_FromLong(!(mode & 2) || !(attr & FILE_ATTRIBUTE_READONLY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001535#else
1536 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001537 if (!PyArg_ParseTuple(args, "eti:access",
1538 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001539 return NULL;
1540 Py_BEGIN_ALLOW_THREADS
1541 res = access(path, mode);
1542 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001543 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001544 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001545#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001546}
1547
Guido van Rossumd371ff11999-01-25 16:12:23 +00001548#ifndef F_OK
1549#define F_OK 0
1550#endif
1551#ifndef R_OK
1552#define R_OK 4
1553#endif
1554#ifndef W_OK
1555#define W_OK 2
1556#endif
1557#ifndef X_OK
1558#define X_OK 1
1559#endif
1560
1561#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001562PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001563"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001564Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001565
1566static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001567posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001568{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001569 int id;
1570 char *ret;
1571
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001572 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001573 return NULL;
1574
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001575#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001576 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001577 if (id == 0) {
1578 ret = ttyname();
1579 }
1580 else {
1581 ret = NULL;
1582 }
1583#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001584 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001585#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001586 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001587 return posix_error();
1588 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001589}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001590#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001591
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001592#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001593PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001594"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001595Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001596
1597static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001598posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001599{
1600 char *ret;
1601 char buffer[L_ctermid];
1602
Greg Wardb48bc172000-03-01 21:51:56 +00001603#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001604 ret = ctermid_r(buffer);
1605#else
1606 ret = ctermid(buffer);
1607#endif
1608 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001609 return posix_error();
1610 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001611}
1612#endif
1613
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001614PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001615"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001616Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001617
Barry Warsaw53699e91996-12-10 23:23:01 +00001618static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001619posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001620{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001621#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001622 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001623#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001624 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001625#elif defined(__VMS)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001626 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001627#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001628 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001629#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001630}
1631
Fred Drake4d1e64b2002-04-15 19:40:07 +00001632#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001633PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001634"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001635Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001636opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001637
1638static PyObject *
1639posix_fchdir(PyObject *self, PyObject *fdobj)
1640{
1641 return posix_fildes(fdobj, fchdir);
1642}
1643#endif /* HAVE_FCHDIR */
1644
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001645
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001646PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001647"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001648Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001649
Barry Warsaw53699e91996-12-10 23:23:01 +00001650static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001651posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001652{
Mark Hammondef8b6542001-05-13 08:04:26 +00001653 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001654 int i;
1655 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001656#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001657 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001658 if (unicode_file_names()) {
1659 PyUnicodeObject *po;
1660 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1661 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001662 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1663 if (attr != 0xFFFFFFFF) {
1664 if (i & _S_IWRITE)
1665 attr &= ~FILE_ATTRIBUTE_READONLY;
1666 else
1667 attr |= FILE_ATTRIBUTE_READONLY;
1668 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1669 }
1670 else
1671 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001672 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001673 if (!res)
1674 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001675 PyUnicode_AS_UNICODE(po));
1676 Py_INCREF(Py_None);
1677 return Py_None;
1678 }
1679 /* Drop the argument parsing error as narrow strings
1680 are also valid. */
1681 PyErr_Clear();
1682 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001683 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1684 &path, &i))
1685 return NULL;
1686 Py_BEGIN_ALLOW_THREADS
1687 attr = GetFileAttributesA(path);
1688 if (attr != 0xFFFFFFFF) {
1689 if (i & _S_IWRITE)
1690 attr &= ~FILE_ATTRIBUTE_READONLY;
1691 else
1692 attr |= FILE_ATTRIBUTE_READONLY;
1693 res = SetFileAttributesA(path, attr);
1694 }
1695 else
1696 res = 0;
1697 Py_END_ALLOW_THREADS
1698 if (!res) {
1699 win32_error("chmod", path);
1700 PyMem_Free(path);
1701 return NULL;
1702 }
1703 PyMem_Free(path);
1704 Py_INCREF(Py_None);
1705 return Py_None;
1706#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001707 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001708 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001709 return NULL;
1710 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001711 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001712 Py_END_ALLOW_THREADS
1713 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001714 return posix_error_with_allocated_filename(path);
1715 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001716 Py_INCREF(Py_None);
1717 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001718#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001719}
1720
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001721
Thomas Wouterscf297e42007-02-23 15:07:44 +00001722#ifdef HAVE_CHFLAGS
1723PyDoc_STRVAR(posix_chflags__doc__,
1724"chflags(path, flags)\n\n\
1725Set file flags.");
1726
1727static PyObject *
1728posix_chflags(PyObject *self, PyObject *args)
1729{
1730 char *path;
1731 unsigned long flags;
1732 int res;
1733 if (!PyArg_ParseTuple(args, "etk:chflags",
1734 Py_FileSystemDefaultEncoding, &path, &flags))
1735 return NULL;
1736 Py_BEGIN_ALLOW_THREADS
1737 res = chflags(path, flags);
1738 Py_END_ALLOW_THREADS
1739 if (res < 0)
1740 return posix_error_with_allocated_filename(path);
1741 PyMem_Free(path);
1742 Py_INCREF(Py_None);
1743 return Py_None;
1744}
1745#endif /* HAVE_CHFLAGS */
1746
1747#ifdef HAVE_LCHFLAGS
1748PyDoc_STRVAR(posix_lchflags__doc__,
1749"lchflags(path, flags)\n\n\
1750Set file flags.\n\
1751This function will not follow symbolic links.");
1752
1753static PyObject *
1754posix_lchflags(PyObject *self, PyObject *args)
1755{
1756 char *path;
1757 unsigned long flags;
1758 int res;
1759 if (!PyArg_ParseTuple(args, "etk:lchflags",
1760 Py_FileSystemDefaultEncoding, &path, &flags))
1761 return NULL;
1762 Py_BEGIN_ALLOW_THREADS
1763 res = lchflags(path, flags);
1764 Py_END_ALLOW_THREADS
1765 if (res < 0)
1766 return posix_error_with_allocated_filename(path);
1767 PyMem_Free(path);
1768 Py_INCREF(Py_None);
1769 return Py_None;
1770}
1771#endif /* HAVE_LCHFLAGS */
1772
Martin v. Löwis244edc82001-10-04 22:44:26 +00001773#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001774PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001775"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001776Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001777
1778static PyObject *
1779posix_chroot(PyObject *self, PyObject *args)
1780{
Thomas Wouters477c8d52006-05-27 19:21:47 +00001781 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001782}
1783#endif
1784
Guido van Rossum21142a01999-01-08 21:05:37 +00001785#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001786PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001787"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001788force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001789
1790static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001791posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001792{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001793 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001794}
1795#endif /* HAVE_FSYNC */
1796
1797#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001798
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001799#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001800extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1801#endif
1802
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001803PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001804"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001805force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001806 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001807
1808static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001809posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001810{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001811 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001812}
1813#endif /* HAVE_FDATASYNC */
1814
1815
Fredrik Lundh10723342000-07-10 16:38:09 +00001816#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001817PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001818"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001819Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001820
Barry Warsaw53699e91996-12-10 23:23:01 +00001821static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001822posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001823{
Mark Hammondef8b6542001-05-13 08:04:26 +00001824 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001825 int uid, gid;
1826 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001827 if (!PyArg_ParseTuple(args, "etii:chown",
1828 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001829 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001830 return NULL;
1831 Py_BEGIN_ALLOW_THREADS
1832 res = chown(path, (uid_t) uid, (gid_t) gid);
1833 Py_END_ALLOW_THREADS
1834 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001835 return posix_error_with_allocated_filename(path);
1836 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001837 Py_INCREF(Py_None);
1838 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001839}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001840#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001841
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001842#ifdef HAVE_LCHOWN
1843PyDoc_STRVAR(posix_lchown__doc__,
1844"lchown(path, uid, gid)\n\n\
1845Change the owner and group id of path to the numeric uid and gid.\n\
1846This function will not follow symbolic links.");
1847
1848static PyObject *
1849posix_lchown(PyObject *self, PyObject *args)
1850{
1851 char *path = NULL;
1852 int uid, gid;
1853 int res;
1854 if (!PyArg_ParseTuple(args, "etii:lchown",
1855 Py_FileSystemDefaultEncoding, &path,
1856 &uid, &gid))
1857 return NULL;
1858 Py_BEGIN_ALLOW_THREADS
1859 res = lchown(path, (uid_t) uid, (gid_t) gid);
1860 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001861 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001862 return posix_error_with_allocated_filename(path);
1863 PyMem_Free(path);
1864 Py_INCREF(Py_None);
1865 return Py_None;
1866}
1867#endif /* HAVE_LCHOWN */
1868
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001869
Guido van Rossum36bc6801995-06-14 22:54:23 +00001870#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001871PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001872"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001873Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001874
Barry Warsaw53699e91996-12-10 23:23:01 +00001875static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001876posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001877{
1878 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001879 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001880
Barry Warsaw53699e91996-12-10 23:23:01 +00001881 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001882#if defined(PYOS_OS2) && defined(PYCC_GCC)
1883 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001884#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001885 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001886#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001887 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001888 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001889 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001890 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001891}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001892
1893PyDoc_STRVAR(posix_getcwdu__doc__,
1894"getcwdu() -> path\n\n\
1895Return a unicode string representing the current working directory.");
1896
1897static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001898posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001899{
1900 char buf[1026];
1901 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001902
1903#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001904 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001905 if (unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001906 wchar_t wbuf[1026];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001907 wchar_t *wbuf2 = wbuf;
1908 PyObject *resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001909 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001910 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
1911 /* If the buffer is large enough, len does not include the
1912 terminating \0. If the buffer is too small, len includes
1913 the space needed for the terminator. */
1914 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
1915 wbuf2 = malloc(len * sizeof(wchar_t));
1916 if (wbuf2)
1917 len = GetCurrentDirectoryW(len, wbuf2);
1918 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001919 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001920 if (!wbuf2) {
1921 PyErr_NoMemory();
1922 return NULL;
1923 }
1924 if (!len) {
1925 if (wbuf2 != wbuf) free(wbuf2);
1926 return win32_error("getcwdu", NULL);
1927 }
1928 resobj = PyUnicode_FromWideChar(wbuf2, len);
1929 if (wbuf2 != wbuf) free(wbuf2);
1930 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001931 }
1932#endif
1933
1934 Py_BEGIN_ALLOW_THREADS
1935#if defined(PYOS_OS2) && defined(PYCC_GCC)
1936 res = _getcwd2(buf, sizeof buf);
1937#else
1938 res = getcwd(buf, sizeof buf);
1939#endif
1940 Py_END_ALLOW_THREADS
1941 if (res == NULL)
1942 return posix_error();
1943 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1944}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001945#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001946
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001947
Guido van Rossumb6775db1994-08-01 11:34:53 +00001948#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001949PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001950"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001951Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001952
Barry Warsaw53699e91996-12-10 23:23:01 +00001953static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001954posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001955{
Thomas Wouters477c8d52006-05-27 19:21:47 +00001956 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001957}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001958#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001959
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001960
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001961PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001962"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001963Return a list containing the names of the entries in the directory.\n\
1964\n\
1965 path: path of directory to list\n\
1966\n\
1967The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001968entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001969
Barry Warsaw53699e91996-12-10 23:23:01 +00001970static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001971posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001972{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001973 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001974 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001975#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001976
Barry Warsaw53699e91996-12-10 23:23:01 +00001977 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001978 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001979 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001980 WIN32_FIND_DATA FileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001981 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00001982 char *bufptr = namebuf;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001983 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001984
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001985#ifdef Py_WIN_WIDE_FILENAMES
1986 /* If on wide-character-capable OS see if argument
1987 is Unicode and if so use wide API. */
1988 if (unicode_file_names()) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001989 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001990 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1991 WIN32_FIND_DATAW wFileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001992 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001993 Py_UNICODE wch;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001994 /* Overallocate for \\*.*\0 */
1995 len = PyUnicode_GET_SIZE(po);
1996 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
1997 if (!wnamebuf) {
1998 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001999 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002000 }
2001 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2002 wch = len > 0 ? wnamebuf[len-1] : '\0';
2003 if (wch != L'/' && wch != L'\\' && wch != L':')
2004 wnamebuf[len++] = L'\\';
2005 wcscpy(wnamebuf + len, L"*.*");
2006 if ((d = PyList_New(0)) == NULL) {
2007 free(wnamebuf);
2008 return NULL;
2009 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002010 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2011 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002012 int error = GetLastError();
2013 if (error == ERROR_FILE_NOT_FOUND) {
2014 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002015 return d;
2016 }
2017 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002018 win32_error_unicode("FindFirstFileW", wnamebuf);
2019 free(wnamebuf);
2020 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002021 }
2022 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002023 /* Skip over . and .. */
2024 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2025 wcscmp(wFileData.cFileName, L"..") != 0) {
2026 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2027 if (v == NULL) {
2028 Py_DECREF(d);
2029 d = NULL;
2030 break;
2031 }
2032 if (PyList_Append(d, v) != 0) {
2033 Py_DECREF(v);
2034 Py_DECREF(d);
2035 d = NULL;
2036 break;
2037 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002038 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002039 }
Georg Brandl622927b2006-03-07 12:48:03 +00002040 Py_BEGIN_ALLOW_THREADS
2041 result = FindNextFileW(hFindFile, &wFileData);
2042 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002043 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2044 it got to the end of the directory. */
2045 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2046 Py_DECREF(d);
2047 win32_error_unicode("FindNextFileW", wnamebuf);
2048 FindClose(hFindFile);
2049 free(wnamebuf);
2050 return NULL;
2051 }
Georg Brandl622927b2006-03-07 12:48:03 +00002052 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002053
2054 if (FindClose(hFindFile) == FALSE) {
2055 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002056 win32_error_unicode("FindClose", wnamebuf);
2057 free(wnamebuf);
2058 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002059 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002060 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002061 return d;
2062 }
2063 /* Drop the argument parsing error as narrow strings
2064 are also valid. */
2065 PyErr_Clear();
2066 }
2067#endif
2068
Tim Peters5aa91602002-01-30 05:46:57 +00002069 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002070 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002071 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002072 if (len > 0) {
2073 char ch = namebuf[len-1];
2074 if (ch != SEP && ch != ALTSEP && ch != ':')
2075 namebuf[len++] = '/';
2076 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002077 strcpy(namebuf + len, "*.*");
2078
Barry Warsaw53699e91996-12-10 23:23:01 +00002079 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002080 return NULL;
2081
2082 hFindFile = FindFirstFile(namebuf, &FileData);
2083 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002084 int error = GetLastError();
2085 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002086 return d;
2087 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002088 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002089 }
2090 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002091 /* Skip over . and .. */
2092 if (strcmp(FileData.cFileName, ".") != 0 &&
2093 strcmp(FileData.cFileName, "..") != 0) {
2094 v = PyString_FromString(FileData.cFileName);
2095 if (v == NULL) {
2096 Py_DECREF(d);
2097 d = NULL;
2098 break;
2099 }
2100 if (PyList_Append(d, v) != 0) {
2101 Py_DECREF(v);
2102 Py_DECREF(d);
2103 d = NULL;
2104 break;
2105 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002106 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002107 }
Georg Brandl622927b2006-03-07 12:48:03 +00002108 Py_BEGIN_ALLOW_THREADS
2109 result = FindNextFile(hFindFile, &FileData);
2110 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002111 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2112 it got to the end of the directory. */
2113 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2114 Py_DECREF(d);
2115 win32_error("FindNextFile", namebuf);
2116 FindClose(hFindFile);
2117 return NULL;
2118 }
Georg Brandl622927b2006-03-07 12:48:03 +00002119 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002120
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002121 if (FindClose(hFindFile) == FALSE) {
2122 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002123 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002124 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002125
2126 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002127
Tim Peters0bb44a42000-09-15 07:44:49 +00002128#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002129
2130#ifndef MAX_PATH
2131#define MAX_PATH CCHMAXPATH
2132#endif
2133 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002134 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002135 PyObject *d, *v;
2136 char namebuf[MAX_PATH+5];
2137 HDIR hdir = 1;
2138 ULONG srchcnt = 1;
2139 FILEFINDBUF3 ep;
2140 APIRET rc;
2141
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002142 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002143 return NULL;
2144 if (len >= MAX_PATH) {
2145 PyErr_SetString(PyExc_ValueError, "path too long");
2146 return NULL;
2147 }
2148 strcpy(namebuf, name);
2149 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002150 if (*pt == ALTSEP)
2151 *pt = SEP;
2152 if (namebuf[len-1] != SEP)
2153 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002154 strcpy(namebuf + len, "*.*");
2155
2156 if ((d = PyList_New(0)) == NULL)
2157 return NULL;
2158
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002159 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2160 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002161 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002162 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2163 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2164 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002165
2166 if (rc != NO_ERROR) {
2167 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002168 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002169 }
2170
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002171 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002172 do {
2173 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002174 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002175 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002176
2177 strcpy(namebuf, ep.achName);
2178
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002179 /* Leave Case of Name Alone -- In Native Form */
2180 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002181
2182 v = PyString_FromString(namebuf);
2183 if (v == NULL) {
2184 Py_DECREF(d);
2185 d = NULL;
2186 break;
2187 }
2188 if (PyList_Append(d, v) != 0) {
2189 Py_DECREF(v);
2190 Py_DECREF(d);
2191 d = NULL;
2192 break;
2193 }
2194 Py_DECREF(v);
2195 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2196 }
2197
2198 return d;
2199#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002200
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002201 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002202 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002203 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002204 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002205 int arg_is_unicode = 1;
2206
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002207 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002208 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2209 arg_is_unicode = 0;
2210 PyErr_Clear();
2211 }
2212 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002213 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002214 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002215 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002216 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002217 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002218 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002219 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002220 return NULL;
2221 }
Georg Brandl622927b2006-03-07 12:48:03 +00002222 for (;;) {
2223 Py_BEGIN_ALLOW_THREADS
2224 ep = readdir(dirp);
2225 Py_END_ALLOW_THREADS
2226 if (ep == NULL)
2227 break;
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002228 if (ep->d_name[0] == '.' &&
2229 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002230 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002231 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00002232 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002233 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002234 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002235 d = NULL;
2236 break;
2237 }
Just van Rossum96b1c902003-03-03 17:32:15 +00002238 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002239 PyObject *w;
2240
2241 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002242 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002243 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002244 if (w != NULL) {
2245 Py_DECREF(v);
2246 v = w;
2247 }
2248 else {
2249 /* fall back to the original byte string, as
2250 discussed in patch #683592 */
2251 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002252 }
Just van Rossum46c97842003-02-25 21:42:15 +00002253 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002254 if (PyList_Append(d, v) != 0) {
2255 Py_DECREF(v);
2256 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002257 d = NULL;
2258 break;
2259 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002260 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002261 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002262 if (errno != 0 && d != NULL) {
2263 /* readdir() returned NULL and set errno */
2264 closedir(dirp);
2265 Py_DECREF(d);
2266 return posix_error_with_allocated_filename(name);
2267 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002268 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002269 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002270
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002271 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002272
Tim Peters0bb44a42000-09-15 07:44:49 +00002273#endif /* which OS */
2274} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002275
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002276#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002277/* A helper function for abspath on win32 */
2278static PyObject *
2279posix__getfullpathname(PyObject *self, PyObject *args)
2280{
2281 /* assume encoded strings wont more than double no of chars */
2282 char inbuf[MAX_PATH*2];
2283 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002284 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002285 char outbuf[MAX_PATH*2];
2286 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002287#ifdef Py_WIN_WIDE_FILENAMES
2288 if (unicode_file_names()) {
2289 PyUnicodeObject *po;
2290 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2291 Py_UNICODE woutbuf[MAX_PATH*2];
2292 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00002293 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002294 sizeof(woutbuf)/sizeof(woutbuf[0]),
2295 woutbuf, &wtemp))
2296 return win32_error("GetFullPathName", "");
2297 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
2298 }
2299 /* Drop the argument parsing error as narrow strings
2300 are also valid. */
2301 PyErr_Clear();
2302 }
2303#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002304 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2305 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002306 &insize))
2307 return NULL;
2308 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2309 outbuf, &temp))
2310 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002311 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2312 return PyUnicode_Decode(outbuf, strlen(outbuf),
2313 Py_FileSystemDefaultEncoding, NULL);
2314 }
Mark Hammondef8b6542001-05-13 08:04:26 +00002315 return PyString_FromString(outbuf);
2316} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002317#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002318
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002319PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002320"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002321Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002322
Barry Warsaw53699e91996-12-10 23:23:01 +00002323static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002324posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002325{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002326 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002327 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002328 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002329
2330#ifdef Py_WIN_WIDE_FILENAMES
2331 if (unicode_file_names()) {
2332 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002333 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002334 Py_BEGIN_ALLOW_THREADS
2335 /* PyUnicode_AS_UNICODE OK without thread lock as
2336 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002337 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002338 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002339 if (!res)
2340 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002341 Py_INCREF(Py_None);
2342 return Py_None;
2343 }
2344 /* Drop the argument parsing error as narrow strings
2345 are also valid. */
2346 PyErr_Clear();
2347 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002348 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2349 Py_FileSystemDefaultEncoding, &path, &mode))
2350 return NULL;
2351 Py_BEGIN_ALLOW_THREADS
2352 /* PyUnicode_AS_UNICODE OK without thread lock as
2353 it is a simple dereference. */
2354 res = CreateDirectoryA(path, NULL);
2355 Py_END_ALLOW_THREADS
2356 if (!res) {
2357 win32_error("mkdir", path);
2358 PyMem_Free(path);
2359 return NULL;
2360 }
2361 PyMem_Free(path);
2362 Py_INCREF(Py_None);
2363 return Py_None;
2364#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002365
Tim Peters5aa91602002-01-30 05:46:57 +00002366 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002367 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002368 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002369 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002370#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002371 res = mkdir(path);
2372#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002373 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002374#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002375 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002376 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002377 return posix_error_with_allocated_filename(path);
2378 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002379 Py_INCREF(Py_None);
2380 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002381#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002382}
2383
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002384
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002385/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2386#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002387#include <sys/resource.h>
2388#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002389
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002390
2391#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002392PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002393"nice(inc) -> new_priority\n\n\
2394Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002395
Barry Warsaw53699e91996-12-10 23:23:01 +00002396static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002397posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002398{
2399 int increment, value;
2400
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002401 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002402 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002403
2404 /* There are two flavours of 'nice': one that returns the new
2405 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002406 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2407 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002408
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002409 If we are of the nice family that returns the new priority, we
2410 need to clear errno before the call, and check if errno is filled
2411 before calling posix_error() on a returnvalue of -1, because the
2412 -1 may be the actual new priority! */
2413
2414 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002415 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002416#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002417 if (value == 0)
2418 value = getpriority(PRIO_PROCESS, 0);
2419#endif
2420 if (value == -1 && errno != 0)
2421 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002422 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002423 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002424}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002425#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002426
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002427PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002428"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002429Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002430
Barry Warsaw53699e91996-12-10 23:23:01 +00002431static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002432posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002433{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002434#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002435 PyObject *o1, *o2;
2436 char *p1, *p2;
2437 BOOL result;
2438 if (unicode_file_names()) {
2439 if (!PyArg_ParseTuple(args, "O&O&:rename",
2440 convert_to_unicode, &o1,
2441 convert_to_unicode, &o2))
2442 PyErr_Clear();
2443 else {
2444 Py_BEGIN_ALLOW_THREADS
2445 result = MoveFileW(PyUnicode_AsUnicode(o1),
2446 PyUnicode_AsUnicode(o2));
2447 Py_END_ALLOW_THREADS
2448 Py_DECREF(o1);
2449 Py_DECREF(o2);
2450 if (!result)
2451 return win32_error("rename", NULL);
2452 Py_INCREF(Py_None);
2453 return Py_None;
2454 }
2455 }
2456 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2457 return NULL;
2458 Py_BEGIN_ALLOW_THREADS
2459 result = MoveFileA(p1, p2);
2460 Py_END_ALLOW_THREADS
2461 if (!result)
2462 return win32_error("rename", NULL);
2463 Py_INCREF(Py_None);
2464 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002465#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002466 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002467#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002468}
2469
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002470
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002471PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002472"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002473Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002474
Barry Warsaw53699e91996-12-10 23:23:01 +00002475static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002476posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002477{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002478#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002479 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002480#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002481 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002482#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002483}
2484
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002485
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002486PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002487"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002488Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002489
Barry Warsaw53699e91996-12-10 23:23:01 +00002490static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002491posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002492{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002493#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002494 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002495#else
2496 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2497#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002498}
2499
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002500
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002501#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002502PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002503"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002504Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002505
Barry Warsaw53699e91996-12-10 23:23:01 +00002506static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002507posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002508{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002509 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002510 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002511 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002512 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002513 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002514 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002515 Py_END_ALLOW_THREADS
2516 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002517}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002518#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002519
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002520
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002521PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002522"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002523Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002524
Barry Warsaw53699e91996-12-10 23:23:01 +00002525static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002526posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002527{
2528 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002529 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002530 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002531 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002532 if (i < 0)
2533 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002534 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002535}
2536
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002537
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002538PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002539"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002540Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002541
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002542PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002543"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002544Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002545
Barry Warsaw53699e91996-12-10 23:23:01 +00002546static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002547posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002548{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002549#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002550 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002551#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002552 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002553#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002554}
2555
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002556
Guido van Rossumb6775db1994-08-01 11:34:53 +00002557#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002558PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002559"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002560Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002561
Barry Warsaw53699e91996-12-10 23:23:01 +00002562static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002563posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002564{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002565 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002566 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002567
Barry Warsaw53699e91996-12-10 23:23:01 +00002568 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002569 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002570 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002571 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002572 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002573 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002574 u.sysname,
2575 u.nodename,
2576 u.release,
2577 u.version,
2578 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002579}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002580#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002581
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002582static int
2583extract_time(PyObject *t, long* sec, long* usec)
2584{
2585 long intval;
2586 if (PyFloat_Check(t)) {
2587 double tval = PyFloat_AsDouble(t);
2588 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2589 if (!intobj)
2590 return -1;
2591 intval = PyInt_AsLong(intobj);
2592 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002593 if (intval == -1 && PyErr_Occurred())
2594 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002595 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002596 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002597 if (*usec < 0)
2598 /* If rounding gave us a negative number,
2599 truncate. */
2600 *usec = 0;
2601 return 0;
2602 }
2603 intval = PyInt_AsLong(t);
2604 if (intval == -1 && PyErr_Occurred())
2605 return -1;
2606 *sec = intval;
2607 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002608 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002609}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002610
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002611PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002612"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002613utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002614Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002615second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002616
Barry Warsaw53699e91996-12-10 23:23:01 +00002617static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002618posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002619{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002620#ifdef Py_WIN_WIDE_FILENAMES
2621 PyObject *arg;
2622 PyUnicodeObject *obwpath;
2623 wchar_t *wpath = NULL;
2624 char *apath = NULL;
2625 HANDLE hFile;
2626 long atimesec, mtimesec, ausec, musec;
2627 FILETIME atime, mtime;
2628 PyObject *result = NULL;
2629
2630 if (unicode_file_names()) {
2631 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2632 wpath = PyUnicode_AS_UNICODE(obwpath);
2633 Py_BEGIN_ALLOW_THREADS
2634 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002635 NULL, OPEN_EXISTING,
2636 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002637 Py_END_ALLOW_THREADS
2638 if (hFile == INVALID_HANDLE_VALUE)
2639 return win32_error_unicode("utime", wpath);
2640 } else
2641 /* Drop the argument parsing error as narrow strings
2642 are also valid. */
2643 PyErr_Clear();
2644 }
2645 if (!wpath) {
2646 if (!PyArg_ParseTuple(args, "etO:utime",
2647 Py_FileSystemDefaultEncoding, &apath, &arg))
2648 return NULL;
2649 Py_BEGIN_ALLOW_THREADS
2650 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002651 NULL, OPEN_EXISTING,
2652 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002653 Py_END_ALLOW_THREADS
2654 if (hFile == INVALID_HANDLE_VALUE) {
2655 win32_error("utime", apath);
2656 PyMem_Free(apath);
2657 return NULL;
2658 }
2659 PyMem_Free(apath);
2660 }
2661
2662 if (arg == Py_None) {
2663 SYSTEMTIME now;
2664 GetSystemTime(&now);
2665 if (!SystemTimeToFileTime(&now, &mtime) ||
2666 !SystemTimeToFileTime(&now, &atime)) {
2667 win32_error("utime", NULL);
2668 goto done;
2669 }
2670 }
2671 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2672 PyErr_SetString(PyExc_TypeError,
2673 "utime() arg 2 must be a tuple (atime, mtime)");
2674 goto done;
2675 }
2676 else {
2677 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2678 &atimesec, &ausec) == -1)
2679 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002680 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002681 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2682 &mtimesec, &musec) == -1)
2683 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002684 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002685 }
2686 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2687 /* Avoid putting the file name into the error here,
2688 as that may confuse the user into believing that
2689 something is wrong with the file, when it also
2690 could be the time stamp that gives a problem. */
2691 win32_error("utime", NULL);
2692 }
2693 Py_INCREF(Py_None);
2694 result = Py_None;
2695done:
2696 CloseHandle(hFile);
2697 return result;
2698#else /* Py_WIN_WIDE_FILENAMES */
2699
Neal Norwitz2adf2102004-06-09 01:46:02 +00002700 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002701 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002702 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002703 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002704
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002705#if defined(HAVE_UTIMES)
2706 struct timeval buf[2];
2707#define ATIME buf[0].tv_sec
2708#define MTIME buf[1].tv_sec
2709#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002710/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002711 struct utimbuf buf;
2712#define ATIME buf.actime
2713#define MTIME buf.modtime
2714#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002715#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002716 time_t buf[2];
2717#define ATIME buf[0]
2718#define MTIME buf[1]
2719#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002720#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002721
Mark Hammond817c9292003-12-03 01:22:38 +00002722
Thomas Wouters477c8d52006-05-27 19:21:47 +00002723 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002724 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002725 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002726 if (arg == Py_None) {
2727 /* optional time values not given */
2728 Py_BEGIN_ALLOW_THREADS
2729 res = utime(path, NULL);
2730 Py_END_ALLOW_THREADS
2731 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002732 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002733 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002734 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002735 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002736 return NULL;
2737 }
2738 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002739 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002740 &atime, &ausec) == -1) {
2741 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002742 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002743 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002744 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002745 &mtime, &musec) == -1) {
2746 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002747 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002748 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002749 ATIME = atime;
2750 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002751#ifdef HAVE_UTIMES
2752 buf[0].tv_usec = ausec;
2753 buf[1].tv_usec = musec;
2754 Py_BEGIN_ALLOW_THREADS
2755 res = utimes(path, buf);
2756 Py_END_ALLOW_THREADS
2757#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002758 Py_BEGIN_ALLOW_THREADS
2759 res = utime(path, UTIME_ARG);
2760 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002761#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002762 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002763 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002764 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002765 }
Neal Norwitz96652712004-06-06 20:40:27 +00002766 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002767 Py_INCREF(Py_None);
2768 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002769#undef UTIME_ARG
2770#undef ATIME
2771#undef MTIME
Thomas Wouters477c8d52006-05-27 19:21:47 +00002772#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002773}
2774
Guido van Rossum85e3b011991-06-03 12:42:10 +00002775
Guido van Rossum3b066191991-06-04 19:40:25 +00002776/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002777
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002778PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002779"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002780Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002781
Barry Warsaw53699e91996-12-10 23:23:01 +00002782static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002783posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002784{
2785 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002786 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002787 return NULL;
2788 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002789 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002790}
2791
Martin v. Löwis114619e2002-10-07 06:44:21 +00002792#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2793static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002794free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002795{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002796 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002797 for (i = 0; i < count; i++)
2798 PyMem_Free(array[i]);
2799 PyMem_DEL(array);
2800}
2801#endif
2802
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002803
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002804#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002805PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002806"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002807Execute an executable path with arguments, replacing current process.\n\
2808\n\
2809 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002810 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002811
Barry Warsaw53699e91996-12-10 23:23:01 +00002812static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002813posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002814{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002815 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002816 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002817 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002818 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002819 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002820
Guido van Rossum89b33251993-10-22 14:26:06 +00002821 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002822 argv is a list or tuple of strings. */
2823
Martin v. Löwis114619e2002-10-07 06:44:21 +00002824 if (!PyArg_ParseTuple(args, "etO:execv",
2825 Py_FileSystemDefaultEncoding,
2826 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002827 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002828 if (PyList_Check(argv)) {
2829 argc = PyList_Size(argv);
2830 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002831 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002832 else if (PyTuple_Check(argv)) {
2833 argc = PyTuple_Size(argv);
2834 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002835 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002836 else {
Fred Drake661ea262000-10-24 19:57:45 +00002837 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002838 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002839 return NULL;
2840 }
2841
Barry Warsaw53699e91996-12-10 23:23:01 +00002842 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002843 if (argvlist == NULL) {
2844 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002845 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002846 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002847 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002848 if (!PyArg_Parse((*getitem)(argv, i), "et",
2849 Py_FileSystemDefaultEncoding,
2850 &argvlist[i])) {
2851 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002852 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002853 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002854 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002855 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002856
Guido van Rossum85e3b011991-06-03 12:42:10 +00002857 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002858 }
2859 argvlist[argc] = NULL;
2860
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002861 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002862
Guido van Rossum85e3b011991-06-03 12:42:10 +00002863 /* If we get here it's definitely an error */
2864
Martin v. Löwis114619e2002-10-07 06:44:21 +00002865 free_string_array(argvlist, argc);
2866 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002867 return posix_error();
2868}
2869
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002870
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002871PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002872"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002873Execute a path with arguments and environment, replacing current process.\n\
2874\n\
2875 path: path of executable file\n\
2876 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002877 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002878
Barry Warsaw53699e91996-12-10 23:23:01 +00002879static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002880posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002881{
2882 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002883 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002884 char **argvlist;
2885 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002886 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002887 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002888 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002889 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002890
2891 /* execve has three arguments: (path, argv, env), where
2892 argv is a list or tuple of strings and env is a dictionary
2893 like posix.environ. */
2894
Martin v. Löwis114619e2002-10-07 06:44:21 +00002895 if (!PyArg_ParseTuple(args, "etOO:execve",
2896 Py_FileSystemDefaultEncoding,
2897 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002898 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002899 if (PyList_Check(argv)) {
2900 argc = PyList_Size(argv);
2901 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002902 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002903 else if (PyTuple_Check(argv)) {
2904 argc = PyTuple_Size(argv);
2905 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002906 }
2907 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002908 PyErr_SetString(PyExc_TypeError,
2909 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002910 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002911 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002912 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002913 PyErr_SetString(PyExc_TypeError,
2914 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002915 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002916 }
2917
Barry Warsaw53699e91996-12-10 23:23:01 +00002918 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002919 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002920 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002921 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002922 }
2923 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002924 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002925 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002926 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002927 &argvlist[i]))
2928 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002929 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002930 goto fail_1;
2931 }
2932 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002933 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002934 argvlist[argc] = NULL;
2935
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002936 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002937 if (i < 0)
2938 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002939 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002940 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002941 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002942 goto fail_1;
2943 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002944 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002945 keys = PyMapping_Keys(env);
2946 vals = PyMapping_Values(env);
2947 if (!keys || !vals)
2948 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002949 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2950 PyErr_SetString(PyExc_TypeError,
2951 "execve(): env.keys() or env.values() is not a list");
2952 goto fail_2;
2953 }
Tim Peters5aa91602002-01-30 05:46:57 +00002954
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002955 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002956 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002957 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002958
2959 key = PyList_GetItem(keys, pos);
2960 val = PyList_GetItem(vals, pos);
2961 if (!key || !val)
2962 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002963
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002964 if (!PyArg_Parse(
2965 key,
2966 "s;execve() arg 3 contains a non-string key",
2967 &k) ||
2968 !PyArg_Parse(
2969 val,
2970 "s;execve() arg 3 contains a non-string value",
2971 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002972 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002973 goto fail_2;
2974 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002975
2976#if defined(PYOS_OS2)
2977 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2978 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2979#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002980 len = PyString_Size(key) + PyString_Size(val) + 2;
2981 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002982 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002983 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002984 goto fail_2;
2985 }
Tim Petersc8996f52001-12-03 20:41:00 +00002986 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002987 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002988#if defined(PYOS_OS2)
2989 }
2990#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002991 }
2992 envlist[envc] = 0;
2993
2994 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002995
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002996 /* If we get here it's definitely an error */
2997
2998 (void) posix_error();
2999
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003000 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003001 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003002 PyMem_DEL(envlist[envc]);
3003 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003004 fail_1:
3005 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003006 Py_XDECREF(vals);
3007 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003008 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003009 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003010 return NULL;
3011}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003012#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003013
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003014
Guido van Rossuma1065681999-01-25 23:20:23 +00003015#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003016PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003017"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003018Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003019\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003020 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003021 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003022 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003023
3024static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003025posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003026{
3027 char *path;
3028 PyObject *argv;
3029 char **argvlist;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003030 int mode, i;
3031 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003032 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003033 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003034
3035 /* spawnv has three arguments: (mode, path, argv), where
3036 argv is a list or tuple of strings. */
3037
Martin v. Löwis114619e2002-10-07 06:44:21 +00003038 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3039 Py_FileSystemDefaultEncoding,
3040 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003041 return NULL;
3042 if (PyList_Check(argv)) {
3043 argc = PyList_Size(argv);
3044 getitem = PyList_GetItem;
3045 }
3046 else if (PyTuple_Check(argv)) {
3047 argc = PyTuple_Size(argv);
3048 getitem = PyTuple_GetItem;
3049 }
3050 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003051 PyErr_SetString(PyExc_TypeError,
3052 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003053 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003054 return NULL;
3055 }
3056
3057 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003058 if (argvlist == NULL) {
3059 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003060 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003061 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003062 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003063 if (!PyArg_Parse((*getitem)(argv, i), "et",
3064 Py_FileSystemDefaultEncoding,
3065 &argvlist[i])) {
3066 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003067 PyErr_SetString(
3068 PyExc_TypeError,
3069 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003070 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00003071 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003072 }
3073 }
3074 argvlist[argc] = NULL;
3075
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003076#if defined(PYOS_OS2) && defined(PYCC_GCC)
3077 Py_BEGIN_ALLOW_THREADS
3078 spawnval = spawnv(mode, path, argvlist);
3079 Py_END_ALLOW_THREADS
3080#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003081 if (mode == _OLD_P_OVERLAY)
3082 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003083
Tim Peters25059d32001-12-07 20:35:43 +00003084 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003085 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003086 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003087#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003088
Martin v. Löwis114619e2002-10-07 06:44:21 +00003089 free_string_array(argvlist, argc);
3090 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003091
Fred Drake699f3522000-06-29 21:12:41 +00003092 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003093 return posix_error();
3094 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003095#if SIZEOF_LONG == SIZEOF_VOID_P
3096 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003097#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003098 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003099#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003100}
3101
3102
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003103PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003104"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003105Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003106\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003107 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003108 path: path of executable file\n\
3109 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003110 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003111
3112static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003113posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003114{
3115 char *path;
3116 PyObject *argv, *env;
3117 char **argvlist;
3118 char **envlist;
3119 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003120 int mode, pos, envc;
3121 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003122 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003123 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003124 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003125
3126 /* spawnve has four arguments: (mode, path, argv, env), where
3127 argv is a list or tuple of strings and env is a dictionary
3128 like posix.environ. */
3129
Martin v. Löwis114619e2002-10-07 06:44:21 +00003130 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3131 Py_FileSystemDefaultEncoding,
3132 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003133 return NULL;
3134 if (PyList_Check(argv)) {
3135 argc = PyList_Size(argv);
3136 getitem = PyList_GetItem;
3137 }
3138 else if (PyTuple_Check(argv)) {
3139 argc = PyTuple_Size(argv);
3140 getitem = PyTuple_GetItem;
3141 }
3142 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003143 PyErr_SetString(PyExc_TypeError,
3144 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003145 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003146 }
3147 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003148 PyErr_SetString(PyExc_TypeError,
3149 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003150 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003151 }
3152
3153 argvlist = PyMem_NEW(char *, argc+1);
3154 if (argvlist == NULL) {
3155 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003156 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003157 }
3158 for (i = 0; i < argc; i++) {
3159 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003160 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00003161 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00003162 &argvlist[i]))
3163 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003164 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003165 goto fail_1;
3166 }
3167 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003168 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003169 argvlist[argc] = NULL;
3170
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003171 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003172 if (i < 0)
3173 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003174 envlist = PyMem_NEW(char *, i + 1);
3175 if (envlist == NULL) {
3176 PyErr_NoMemory();
3177 goto fail_1;
3178 }
3179 envc = 0;
3180 keys = PyMapping_Keys(env);
3181 vals = PyMapping_Values(env);
3182 if (!keys || !vals)
3183 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003184 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3185 PyErr_SetString(PyExc_TypeError,
3186 "spawnve(): env.keys() or env.values() is not a list");
3187 goto fail_2;
3188 }
Tim Peters5aa91602002-01-30 05:46:57 +00003189
Guido van Rossuma1065681999-01-25 23:20:23 +00003190 for (pos = 0; pos < i; pos++) {
3191 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003192 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003193
3194 key = PyList_GetItem(keys, pos);
3195 val = PyList_GetItem(vals, pos);
3196 if (!key || !val)
3197 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003198
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003199 if (!PyArg_Parse(
3200 key,
3201 "s;spawnve() arg 3 contains a non-string key",
3202 &k) ||
3203 !PyArg_Parse(
3204 val,
3205 "s;spawnve() arg 3 contains a non-string value",
3206 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003207 {
3208 goto fail_2;
3209 }
Tim Petersc8996f52001-12-03 20:41:00 +00003210 len = PyString_Size(key) + PyString_Size(val) + 2;
3211 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003212 if (p == NULL) {
3213 PyErr_NoMemory();
3214 goto fail_2;
3215 }
Tim Petersc8996f52001-12-03 20:41:00 +00003216 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003217 envlist[envc++] = p;
3218 }
3219 envlist[envc] = 0;
3220
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003221#if defined(PYOS_OS2) && defined(PYCC_GCC)
3222 Py_BEGIN_ALLOW_THREADS
3223 spawnval = spawnve(mode, path, argvlist, envlist);
3224 Py_END_ALLOW_THREADS
3225#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003226 if (mode == _OLD_P_OVERLAY)
3227 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003228
3229 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003230 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003231 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003232#endif
Tim Peters25059d32001-12-07 20:35:43 +00003233
Fred Drake699f3522000-06-29 21:12:41 +00003234 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003235 (void) posix_error();
3236 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003237#if SIZEOF_LONG == SIZEOF_VOID_P
3238 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003239#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003240 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003241#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003242
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003243 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003244 while (--envc >= 0)
3245 PyMem_DEL(envlist[envc]);
3246 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003247 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003248 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003249 Py_XDECREF(vals);
3250 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003251 fail_0:
3252 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003253 return res;
3254}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003255
3256/* OS/2 supports spawnvp & spawnvpe natively */
3257#if defined(PYOS_OS2)
3258PyDoc_STRVAR(posix_spawnvp__doc__,
3259"spawnvp(mode, file, args)\n\n\
3260Execute the program 'file' in a new process, using the environment\n\
3261search path to find the file.\n\
3262\n\
3263 mode: mode of process creation\n\
3264 file: executable file name\n\
3265 args: tuple or list of strings");
3266
3267static PyObject *
3268posix_spawnvp(PyObject *self, PyObject *args)
3269{
3270 char *path;
3271 PyObject *argv;
3272 char **argvlist;
3273 int mode, i, argc;
3274 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003275 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003276
3277 /* spawnvp has three arguments: (mode, path, argv), where
3278 argv is a list or tuple of strings. */
3279
3280 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3281 Py_FileSystemDefaultEncoding,
3282 &path, &argv))
3283 return NULL;
3284 if (PyList_Check(argv)) {
3285 argc = PyList_Size(argv);
3286 getitem = PyList_GetItem;
3287 }
3288 else if (PyTuple_Check(argv)) {
3289 argc = PyTuple_Size(argv);
3290 getitem = PyTuple_GetItem;
3291 }
3292 else {
3293 PyErr_SetString(PyExc_TypeError,
3294 "spawnvp() arg 2 must be a tuple or list");
3295 PyMem_Free(path);
3296 return NULL;
3297 }
3298
3299 argvlist = PyMem_NEW(char *, argc+1);
3300 if (argvlist == NULL) {
3301 PyMem_Free(path);
3302 return PyErr_NoMemory();
3303 }
3304 for (i = 0; i < argc; i++) {
3305 if (!PyArg_Parse((*getitem)(argv, i), "et",
3306 Py_FileSystemDefaultEncoding,
3307 &argvlist[i])) {
3308 free_string_array(argvlist, i);
3309 PyErr_SetString(
3310 PyExc_TypeError,
3311 "spawnvp() arg 2 must contain only strings");
3312 PyMem_Free(path);
3313 return NULL;
3314 }
3315 }
3316 argvlist[argc] = NULL;
3317
3318 Py_BEGIN_ALLOW_THREADS
3319#if defined(PYCC_GCC)
3320 spawnval = spawnvp(mode, path, argvlist);
3321#else
3322 spawnval = _spawnvp(mode, path, argvlist);
3323#endif
3324 Py_END_ALLOW_THREADS
3325
3326 free_string_array(argvlist, argc);
3327 PyMem_Free(path);
3328
3329 if (spawnval == -1)
3330 return posix_error();
3331 else
3332 return Py_BuildValue("l", (long) spawnval);
3333}
3334
3335
3336PyDoc_STRVAR(posix_spawnvpe__doc__,
3337"spawnvpe(mode, file, args, env)\n\n\
3338Execute the program 'file' in a new process, using the environment\n\
3339search path to find the file.\n\
3340\n\
3341 mode: mode of process creation\n\
3342 file: executable file name\n\
3343 args: tuple or list of arguments\n\
3344 env: dictionary of strings mapping to strings");
3345
3346static PyObject *
3347posix_spawnvpe(PyObject *self, PyObject *args)
3348{
3349 char *path;
3350 PyObject *argv, *env;
3351 char **argvlist;
3352 char **envlist;
3353 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3354 int mode, i, pos, argc, envc;
3355 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003356 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003357 int lastarg = 0;
3358
3359 /* spawnvpe has four arguments: (mode, path, argv, env), where
3360 argv is a list or tuple of strings and env is a dictionary
3361 like posix.environ. */
3362
3363 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3364 Py_FileSystemDefaultEncoding,
3365 &path, &argv, &env))
3366 return NULL;
3367 if (PyList_Check(argv)) {
3368 argc = PyList_Size(argv);
3369 getitem = PyList_GetItem;
3370 }
3371 else if (PyTuple_Check(argv)) {
3372 argc = PyTuple_Size(argv);
3373 getitem = PyTuple_GetItem;
3374 }
3375 else {
3376 PyErr_SetString(PyExc_TypeError,
3377 "spawnvpe() arg 2 must be a tuple or list");
3378 goto fail_0;
3379 }
3380 if (!PyMapping_Check(env)) {
3381 PyErr_SetString(PyExc_TypeError,
3382 "spawnvpe() arg 3 must be a mapping object");
3383 goto fail_0;
3384 }
3385
3386 argvlist = PyMem_NEW(char *, argc+1);
3387 if (argvlist == NULL) {
3388 PyErr_NoMemory();
3389 goto fail_0;
3390 }
3391 for (i = 0; i < argc; i++) {
3392 if (!PyArg_Parse((*getitem)(argv, i),
3393 "et;spawnvpe() arg 2 must contain only strings",
3394 Py_FileSystemDefaultEncoding,
3395 &argvlist[i]))
3396 {
3397 lastarg = i;
3398 goto fail_1;
3399 }
3400 }
3401 lastarg = argc;
3402 argvlist[argc] = NULL;
3403
3404 i = PyMapping_Size(env);
3405 if (i < 0)
3406 goto fail_1;
3407 envlist = PyMem_NEW(char *, i + 1);
3408 if (envlist == NULL) {
3409 PyErr_NoMemory();
3410 goto fail_1;
3411 }
3412 envc = 0;
3413 keys = PyMapping_Keys(env);
3414 vals = PyMapping_Values(env);
3415 if (!keys || !vals)
3416 goto fail_2;
3417 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3418 PyErr_SetString(PyExc_TypeError,
3419 "spawnvpe(): env.keys() or env.values() is not a list");
3420 goto fail_2;
3421 }
3422
3423 for (pos = 0; pos < i; pos++) {
3424 char *p, *k, *v;
3425 size_t len;
3426
3427 key = PyList_GetItem(keys, pos);
3428 val = PyList_GetItem(vals, pos);
3429 if (!key || !val)
3430 goto fail_2;
3431
3432 if (!PyArg_Parse(
3433 key,
3434 "s;spawnvpe() arg 3 contains a non-string key",
3435 &k) ||
3436 !PyArg_Parse(
3437 val,
3438 "s;spawnvpe() arg 3 contains a non-string value",
3439 &v))
3440 {
3441 goto fail_2;
3442 }
3443 len = PyString_Size(key) + PyString_Size(val) + 2;
3444 p = PyMem_NEW(char, len);
3445 if (p == NULL) {
3446 PyErr_NoMemory();
3447 goto fail_2;
3448 }
3449 PyOS_snprintf(p, len, "%s=%s", k, v);
3450 envlist[envc++] = p;
3451 }
3452 envlist[envc] = 0;
3453
3454 Py_BEGIN_ALLOW_THREADS
3455#if defined(PYCC_GCC)
3456 spawnval = spawnve(mode, path, argvlist, envlist);
3457#else
3458 spawnval = _spawnve(mode, path, argvlist, envlist);
3459#endif
3460 Py_END_ALLOW_THREADS
3461
3462 if (spawnval == -1)
3463 (void) posix_error();
3464 else
3465 res = Py_BuildValue("l", (long) spawnval);
3466
3467 fail_2:
3468 while (--envc >= 0)
3469 PyMem_DEL(envlist[envc]);
3470 PyMem_DEL(envlist);
3471 fail_1:
3472 free_string_array(argvlist, lastarg);
3473 Py_XDECREF(vals);
3474 Py_XDECREF(keys);
3475 fail_0:
3476 PyMem_Free(path);
3477 return res;
3478}
3479#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003480#endif /* HAVE_SPAWNV */
3481
3482
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003483#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003484PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003485"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003486Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3487\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003488Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003489
3490static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003491posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003492{
Neal Norwitze241ce82003-02-17 18:17:05 +00003493 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003494 if (pid == -1)
3495 return posix_error();
3496 PyOS_AfterFork();
3497 return PyInt_FromLong((long)pid);
3498}
3499#endif
3500
3501
Guido van Rossumad0ee831995-03-01 10:34:45 +00003502#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003503PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003504"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003505Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003506Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003507
Barry Warsaw53699e91996-12-10 23:23:01 +00003508static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003509posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003510{
Neal Norwitze241ce82003-02-17 18:17:05 +00003511 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003512 if (pid == -1)
3513 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003514 if (pid == 0)
3515 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003516 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003517}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003518#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003519
Neal Norwitzb59798b2003-03-21 01:43:31 +00003520/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003521/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3522#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003523#define DEV_PTY_FILE "/dev/ptc"
3524#define HAVE_DEV_PTMX
3525#else
3526#define DEV_PTY_FILE "/dev/ptmx"
3527#endif
3528
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003529#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003530#ifdef HAVE_PTY_H
3531#include <pty.h>
3532#else
3533#ifdef HAVE_LIBUTIL_H
3534#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003535#endif /* HAVE_LIBUTIL_H */
3536#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003537#ifdef HAVE_STROPTS_H
3538#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003539#endif
3540#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003541
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003542#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003543PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003544"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003545Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003546
3547static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003548posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003549{
3550 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003551#ifndef HAVE_OPENPTY
3552 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003553#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003554#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003555 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003556#ifdef sun
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003557 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003558#endif
3559#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003560
Thomas Wouters70c21a12000-07-14 14:28:33 +00003561#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003562 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3563 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003564#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003565 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3566 if (slave_name == NULL)
3567 return posix_error();
3568
3569 slave_fd = open(slave_name, O_RDWR);
3570 if (slave_fd < 0)
3571 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003572#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003573 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003574 if (master_fd < 0)
3575 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003576 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003577 /* change permission of slave */
3578 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003579 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003580 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003581 }
3582 /* unlock slave */
3583 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003584 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003585 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003586 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003587 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003588 slave_name = ptsname(master_fd); /* get name of slave */
3589 if (slave_name == NULL)
3590 return posix_error();
3591 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3592 if (slave_fd < 0)
3593 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003594#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003595 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3596 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003597#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003598 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003599#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003600#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003601#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003602
Fred Drake8cef4cf2000-06-28 16:40:38 +00003603 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003604
Fred Drake8cef4cf2000-06-28 16:40:38 +00003605}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003606#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003607
3608#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003609PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003610"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003611Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3612Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003613To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003614
3615static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003616posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003617{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003618 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003619
Fred Drake8cef4cf2000-06-28 16:40:38 +00003620 pid = forkpty(&master_fd, NULL, NULL, NULL);
3621 if (pid == -1)
3622 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003623 if (pid == 0)
3624 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003625 return Py_BuildValue("(ii)", pid, master_fd);
3626}
3627#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003628
Guido van Rossumad0ee831995-03-01 10:34:45 +00003629#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003630PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003631"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003632Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003633
Barry Warsaw53699e91996-12-10 23:23:01 +00003634static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003635posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003636{
Barry Warsaw53699e91996-12-10 23:23:01 +00003637 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003638}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003639#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003640
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003641
Guido van Rossumad0ee831995-03-01 10:34:45 +00003642#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003643PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003644"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003645Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003646
Barry Warsaw53699e91996-12-10 23:23:01 +00003647static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003648posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003649{
Barry Warsaw53699e91996-12-10 23:23:01 +00003650 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003651}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003652#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003653
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003654
Guido van Rossumad0ee831995-03-01 10:34:45 +00003655#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003656PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003657"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003658Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003659
Barry Warsaw53699e91996-12-10 23:23:01 +00003660static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003661posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003662{
Barry Warsaw53699e91996-12-10 23:23:01 +00003663 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003664}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003665#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003666
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003667
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003668PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003669"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003670Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003671
Barry Warsaw53699e91996-12-10 23:23:01 +00003672static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003673posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003674{
Barry Warsaw53699e91996-12-10 23:23:01 +00003675 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003676}
3677
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003678
Fred Drakec9680921999-12-13 16:37:25 +00003679#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003680PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003681"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003682Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003683
3684static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003685posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003686{
3687 PyObject *result = NULL;
3688
Fred Drakec9680921999-12-13 16:37:25 +00003689#ifdef NGROUPS_MAX
3690#define MAX_GROUPS NGROUPS_MAX
3691#else
3692 /* defined to be 16 on Solaris7, so this should be a small number */
3693#define MAX_GROUPS 64
3694#endif
3695 gid_t grouplist[MAX_GROUPS];
3696 int n;
3697
3698 n = getgroups(MAX_GROUPS, grouplist);
3699 if (n < 0)
3700 posix_error();
3701 else {
3702 result = PyList_New(n);
3703 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003704 int i;
3705 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003706 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003707 if (o == NULL) {
3708 Py_DECREF(result);
3709 result = NULL;
3710 break;
3711 }
3712 PyList_SET_ITEM(result, i, o);
3713 }
3714 }
3715 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003716
Fred Drakec9680921999-12-13 16:37:25 +00003717 return result;
3718}
3719#endif
3720
Martin v. Löwis606edc12002-06-13 21:09:11 +00003721#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003722PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003723"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003724Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003725
3726static PyObject *
3727posix_getpgid(PyObject *self, PyObject *args)
3728{
3729 int pid, pgid;
3730 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3731 return NULL;
3732 pgid = getpgid(pid);
3733 if (pgid < 0)
3734 return posix_error();
3735 return PyInt_FromLong((long)pgid);
3736}
3737#endif /* HAVE_GETPGID */
3738
3739
Guido van Rossumb6775db1994-08-01 11:34:53 +00003740#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003741PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003742"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003743Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003744
Barry Warsaw53699e91996-12-10 23:23:01 +00003745static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003746posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003747{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003748#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003749 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003750#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003751 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003752#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003753}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003754#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003755
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003756
Guido van Rossumb6775db1994-08-01 11:34:53 +00003757#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003758PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003759"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003760Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003761
Barry Warsaw53699e91996-12-10 23:23:01 +00003762static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003763posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003764{
Guido van Rossum64933891994-10-20 21:56:42 +00003765#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003766 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003767#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003768 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003769#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003770 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003771 Py_INCREF(Py_None);
3772 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003773}
3774
Guido van Rossumb6775db1994-08-01 11:34:53 +00003775#endif /* HAVE_SETPGRP */
3776
Guido van Rossumad0ee831995-03-01 10:34:45 +00003777#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003778PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003779"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003780Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003781
Barry Warsaw53699e91996-12-10 23:23:01 +00003782static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003783posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003784{
Barry Warsaw53699e91996-12-10 23:23:01 +00003785 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003786}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003787#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003788
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003789
Fred Drake12c6e2d1999-12-14 21:25:03 +00003790#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003791PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003792"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003793Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003794
3795static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003796posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003797{
Neal Norwitze241ce82003-02-17 18:17:05 +00003798 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003799 char *name;
3800 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003801
Fred Drakea30680b2000-12-06 21:24:28 +00003802 errno = 0;
3803 name = getlogin();
3804 if (name == NULL) {
3805 if (errno)
3806 posix_error();
3807 else
3808 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003809 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003810 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003811 else
3812 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003813 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003814
Fred Drake12c6e2d1999-12-14 21:25:03 +00003815 return result;
3816}
3817#endif
3818
Guido van Rossumad0ee831995-03-01 10:34:45 +00003819#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003820PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003821"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003822Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003823
Barry Warsaw53699e91996-12-10 23:23:01 +00003824static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003825posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003826{
Barry Warsaw53699e91996-12-10 23:23:01 +00003827 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003828}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003829#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003830
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003831
Guido van Rossumad0ee831995-03-01 10:34:45 +00003832#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003833PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003834"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003835Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003836
Barry Warsaw53699e91996-12-10 23:23:01 +00003837static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003838posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003839{
3840 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003841 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003842 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003843#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003844 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3845 APIRET rc;
3846 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003847 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003848
3849 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3850 APIRET rc;
3851 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003852 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003853
3854 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003855 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003856#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003857 if (kill(pid, sig) == -1)
3858 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003859#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003860 Py_INCREF(Py_None);
3861 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003862}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003863#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003864
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003865#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003866PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003867"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003868Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003869
3870static PyObject *
3871posix_killpg(PyObject *self, PyObject *args)
3872{
3873 int pgid, sig;
3874 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3875 return NULL;
3876 if (killpg(pgid, sig) == -1)
3877 return posix_error();
3878 Py_INCREF(Py_None);
3879 return Py_None;
3880}
3881#endif
3882
Guido van Rossumc0125471996-06-28 18:55:32 +00003883#ifdef HAVE_PLOCK
3884
3885#ifdef HAVE_SYS_LOCK_H
3886#include <sys/lock.h>
3887#endif
3888
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003889PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003890"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003891Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003892
Barry Warsaw53699e91996-12-10 23:23:01 +00003893static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003894posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003895{
3896 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003897 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003898 return NULL;
3899 if (plock(op) == -1)
3900 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003901 Py_INCREF(Py_None);
3902 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003903}
3904#endif
3905
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003906
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003907#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003908PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003909"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003910Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003911
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003912#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003913#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003914static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003915async_system(const char *command)
3916{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003917 char errormsg[256], args[1024];
3918 RESULTCODES rcodes;
3919 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003920
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003921 char *shell = getenv("COMSPEC");
3922 if (!shell)
3923 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003924
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003925 /* avoid overflowing the argument buffer */
3926 if (strlen(shell) + 3 + strlen(command) >= 1024)
3927 return ERROR_NOT_ENOUGH_MEMORY
3928
3929 args[0] = '\0';
3930 strcat(args, shell);
3931 strcat(args, "/c ");
3932 strcat(args, command);
3933
3934 /* execute asynchronously, inheriting the environment */
3935 rc = DosExecPgm(errormsg,
3936 sizeof(errormsg),
3937 EXEC_ASYNC,
3938 args,
3939 NULL,
3940 &rcodes,
3941 shell);
3942 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003943}
3944
Guido van Rossumd48f2521997-12-05 22:19:34 +00003945static FILE *
3946popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003947{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003948 int oldfd, tgtfd;
3949 HFILE pipeh[2];
3950 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003951
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003952 /* mode determines which of stdin or stdout is reconnected to
3953 * the pipe to the child
3954 */
3955 if (strchr(mode, 'r') != NULL) {
3956 tgt_fd = 1; /* stdout */
3957 } else if (strchr(mode, 'w')) {
3958 tgt_fd = 0; /* stdin */
3959 } else {
3960 *err = ERROR_INVALID_ACCESS;
3961 return NULL;
3962 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003963
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00003964 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003965 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3966 *err = rc;
3967 return NULL;
3968 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003969
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003970 /* prevent other threads accessing stdio */
3971 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003972
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003973 /* reconnect stdio and execute child */
3974 oldfd = dup(tgtfd);
3975 close(tgtfd);
3976 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3977 DosClose(pipeh[tgtfd]);
3978 rc = async_system(command);
3979 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003980
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003981 /* restore stdio */
3982 dup2(oldfd, tgtfd);
3983 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003984
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003985 /* allow other threads access to stdio */
3986 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003987
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003988 /* if execution of child was successful return file stream */
3989 if (rc == NO_ERROR)
3990 return fdopen(pipeh[1 - tgtfd], mode);
3991 else {
3992 DosClose(pipeh[1 - tgtfd]);
3993 *err = rc;
3994 return NULL;
3995 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003996}
3997
3998static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003999posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004000{
4001 char *name;
4002 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00004003 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004004 FILE *fp;
4005 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004006 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004007 return NULL;
4008 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00004009 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004010 Py_END_ALLOW_THREADS
4011 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004012 return os2_error(err);
4013
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004014 f = PyFile_FromFile(fp, name, mode, fclose);
4015 if (f != NULL)
4016 PyFile_SetBufSize(f, bufsize);
4017 return f;
4018}
4019
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004020#elif defined(PYCC_GCC)
4021
4022/* standard posix version of popen() support */
4023static PyObject *
4024posix_popen(PyObject *self, PyObject *args)
4025{
4026 char *name;
4027 char *mode = "r";
4028 int bufsize = -1;
4029 FILE *fp;
4030 PyObject *f;
4031 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4032 return NULL;
4033 Py_BEGIN_ALLOW_THREADS
4034 fp = popen(name, mode);
4035 Py_END_ALLOW_THREADS
4036 if (fp == NULL)
4037 return posix_error();
4038 f = PyFile_FromFile(fp, name, mode, pclose);
4039 if (f != NULL)
4040 PyFile_SetBufSize(f, bufsize);
4041 return f;
4042}
4043
4044/* fork() under OS/2 has lots'o'warts
4045 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4046 * most of this code is a ripoff of the win32 code, but using the
4047 * capabilities of EMX's C library routines
4048 */
4049
4050/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4051#define POPEN_1 1
4052#define POPEN_2 2
4053#define POPEN_3 3
4054#define POPEN_4 4
4055
4056static PyObject *_PyPopen(char *, int, int, int);
4057static int _PyPclose(FILE *file);
4058
4059/*
4060 * Internal dictionary mapping popen* file pointers to process handles,
4061 * for use when retrieving the process exit code. See _PyPclose() below
4062 * for more information on this dictionary's use.
4063 */
4064static PyObject *_PyPopenProcs = NULL;
4065
4066/* os2emx version of popen2()
4067 *
4068 * The result of this function is a pipe (file) connected to the
4069 * process's stdin, and a pipe connected to the process's stdout.
4070 */
4071
4072static PyObject *
4073os2emx_popen2(PyObject *self, PyObject *args)
4074{
4075 PyObject *f;
4076 int tm=0;
4077
4078 char *cmdstring;
4079 char *mode = "t";
4080 int bufsize = -1;
4081 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4082 return NULL;
4083
4084 if (*mode == 't')
4085 tm = O_TEXT;
4086 else if (*mode != 'b') {
4087 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4088 return NULL;
4089 } else
4090 tm = O_BINARY;
4091
4092 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
4093
4094 return f;
4095}
4096
4097/*
4098 * Variation on os2emx.popen2
4099 *
4100 * The result of this function is 3 pipes - the process's stdin,
4101 * stdout and stderr
4102 */
4103
4104static PyObject *
4105os2emx_popen3(PyObject *self, PyObject *args)
4106{
4107 PyObject *f;
4108 int tm = 0;
4109
4110 char *cmdstring;
4111 char *mode = "t";
4112 int bufsize = -1;
4113 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4114 return NULL;
4115
4116 if (*mode == 't')
4117 tm = O_TEXT;
4118 else if (*mode != 'b') {
4119 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4120 return NULL;
4121 } else
4122 tm = O_BINARY;
4123
4124 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
4125
4126 return f;
4127}
4128
4129/*
4130 * Variation on os2emx.popen2
4131 *
Tim Peters11b23062003-04-23 02:39:17 +00004132 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004133 * and stdout+stderr combined as a single pipe.
4134 */
4135
4136static PyObject *
4137os2emx_popen4(PyObject *self, PyObject *args)
4138{
4139 PyObject *f;
4140 int tm = 0;
4141
4142 char *cmdstring;
4143 char *mode = "t";
4144 int bufsize = -1;
4145 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4146 return NULL;
4147
4148 if (*mode == 't')
4149 tm = O_TEXT;
4150 else if (*mode != 'b') {
4151 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4152 return NULL;
4153 } else
4154 tm = O_BINARY;
4155
4156 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
4157
4158 return f;
4159}
4160
4161/* a couple of structures for convenient handling of multiple
4162 * file handles and pipes
4163 */
4164struct file_ref
4165{
4166 int handle;
4167 int flags;
4168};
4169
4170struct pipe_ref
4171{
4172 int rd;
4173 int wr;
4174};
4175
4176/* The following code is derived from the win32 code */
4177
4178static PyObject *
4179_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4180{
4181 struct file_ref stdio[3];
4182 struct pipe_ref p_fd[3];
4183 FILE *p_s[3];
4184 int file_count, i, pipe_err, pipe_pid;
4185 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4186 PyObject *f, *p_f[3];
4187
4188 /* file modes for subsequent fdopen's on pipe handles */
4189 if (mode == O_TEXT)
4190 {
4191 rd_mode = "rt";
4192 wr_mode = "wt";
4193 }
4194 else
4195 {
4196 rd_mode = "rb";
4197 wr_mode = "wb";
4198 }
4199
4200 /* prepare shell references */
4201 if ((shell = getenv("EMXSHELL")) == NULL)
4202 if ((shell = getenv("COMSPEC")) == NULL)
4203 {
4204 errno = ENOENT;
4205 return posix_error();
4206 }
4207
4208 sh_name = _getname(shell);
4209 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4210 opt = "/c";
4211 else
4212 opt = "-c";
4213
4214 /* save current stdio fds + their flags, and set not inheritable */
4215 i = pipe_err = 0;
4216 while (pipe_err >= 0 && i < 3)
4217 {
4218 pipe_err = stdio[i].handle = dup(i);
4219 stdio[i].flags = fcntl(i, F_GETFD, 0);
4220 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4221 i++;
4222 }
4223 if (pipe_err < 0)
4224 {
4225 /* didn't get them all saved - clean up and bail out */
4226 int saved_err = errno;
4227 while (i-- > 0)
4228 {
4229 close(stdio[i].handle);
4230 }
4231 errno = saved_err;
4232 return posix_error();
4233 }
4234
4235 /* create pipe ends */
4236 file_count = 2;
4237 if (n == POPEN_3)
4238 file_count = 3;
4239 i = pipe_err = 0;
4240 while ((pipe_err == 0) && (i < file_count))
4241 pipe_err = pipe((int *)&p_fd[i++]);
4242 if (pipe_err < 0)
4243 {
4244 /* didn't get them all made - clean up and bail out */
4245 while (i-- > 0)
4246 {
4247 close(p_fd[i].wr);
4248 close(p_fd[i].rd);
4249 }
4250 errno = EPIPE;
4251 return posix_error();
4252 }
4253
4254 /* change the actual standard IO streams over temporarily,
4255 * making the retained pipe ends non-inheritable
4256 */
4257 pipe_err = 0;
4258
4259 /* - stdin */
4260 if (dup2(p_fd[0].rd, 0) == 0)
4261 {
4262 close(p_fd[0].rd);
4263 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4264 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4265 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4266 {
4267 close(p_fd[0].wr);
4268 pipe_err = -1;
4269 }
4270 }
4271 else
4272 {
4273 pipe_err = -1;
4274 }
4275
4276 /* - stdout */
4277 if (pipe_err == 0)
4278 {
4279 if (dup2(p_fd[1].wr, 1) == 1)
4280 {
4281 close(p_fd[1].wr);
4282 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4283 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4284 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4285 {
4286 close(p_fd[1].rd);
4287 pipe_err = -1;
4288 }
4289 }
4290 else
4291 {
4292 pipe_err = -1;
4293 }
4294 }
4295
4296 /* - stderr, as required */
4297 if (pipe_err == 0)
4298 switch (n)
4299 {
4300 case POPEN_3:
4301 {
4302 if (dup2(p_fd[2].wr, 2) == 2)
4303 {
4304 close(p_fd[2].wr);
4305 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4306 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4307 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4308 {
4309 close(p_fd[2].rd);
4310 pipe_err = -1;
4311 }
4312 }
4313 else
4314 {
4315 pipe_err = -1;
4316 }
4317 break;
4318 }
4319
4320 case POPEN_4:
4321 {
4322 if (dup2(1, 2) != 2)
4323 {
4324 pipe_err = -1;
4325 }
4326 break;
4327 }
4328 }
4329
4330 /* spawn the child process */
4331 if (pipe_err == 0)
4332 {
4333 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4334 if (pipe_pid == -1)
4335 {
4336 pipe_err = -1;
4337 }
4338 else
4339 {
4340 /* save the PID into the FILE structure
4341 * NOTE: this implementation doesn't actually
4342 * take advantage of this, but do it for
4343 * completeness - AIM Apr01
4344 */
4345 for (i = 0; i < file_count; i++)
4346 p_s[i]->_pid = pipe_pid;
4347 }
4348 }
4349
4350 /* reset standard IO to normal */
4351 for (i = 0; i < 3; i++)
4352 {
4353 dup2(stdio[i].handle, i);
4354 fcntl(i, F_SETFD, stdio[i].flags);
4355 close(stdio[i].handle);
4356 }
4357
4358 /* if any remnant problems, clean up and bail out */
4359 if (pipe_err < 0)
4360 {
4361 for (i = 0; i < 3; i++)
4362 {
4363 close(p_fd[i].rd);
4364 close(p_fd[i].wr);
4365 }
4366 errno = EPIPE;
4367 return posix_error_with_filename(cmdstring);
4368 }
4369
4370 /* build tuple of file objects to return */
4371 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4372 PyFile_SetBufSize(p_f[0], bufsize);
4373 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4374 PyFile_SetBufSize(p_f[1], bufsize);
4375 if (n == POPEN_3)
4376 {
4377 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4378 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004379 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004380 }
4381 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004382 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004383
4384 /*
4385 * Insert the files we've created into the process dictionary
4386 * all referencing the list with the process handle and the
4387 * initial number of files (see description below in _PyPclose).
4388 * Since if _PyPclose later tried to wait on a process when all
4389 * handles weren't closed, it could create a deadlock with the
4390 * child, we spend some energy here to try to ensure that we
4391 * either insert all file handles into the dictionary or none
4392 * at all. It's a little clumsy with the various popen modes
4393 * and variable number of files involved.
4394 */
4395 if (!_PyPopenProcs)
4396 {
4397 _PyPopenProcs = PyDict_New();
4398 }
4399
4400 if (_PyPopenProcs)
4401 {
4402 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4403 int ins_rc[3];
4404
4405 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4406 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4407
4408 procObj = PyList_New(2);
4409 pidObj = PyInt_FromLong((long) pipe_pid);
4410 intObj = PyInt_FromLong((long) file_count);
4411
4412 if (procObj && pidObj && intObj)
4413 {
4414 PyList_SetItem(procObj, 0, pidObj);
4415 PyList_SetItem(procObj, 1, intObj);
4416
4417 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4418 if (fileObj[0])
4419 {
4420 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4421 fileObj[0],
4422 procObj);
4423 }
4424 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4425 if (fileObj[1])
4426 {
4427 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4428 fileObj[1],
4429 procObj);
4430 }
4431 if (file_count >= 3)
4432 {
4433 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4434 if (fileObj[2])
4435 {
4436 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4437 fileObj[2],
4438 procObj);
4439 }
4440 }
4441
4442 if (ins_rc[0] < 0 || !fileObj[0] ||
4443 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4444 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4445 {
4446 /* Something failed - remove any dictionary
4447 * entries that did make it.
4448 */
4449 if (!ins_rc[0] && fileObj[0])
4450 {
4451 PyDict_DelItem(_PyPopenProcs,
4452 fileObj[0]);
4453 }
4454 if (!ins_rc[1] && fileObj[1])
4455 {
4456 PyDict_DelItem(_PyPopenProcs,
4457 fileObj[1]);
4458 }
4459 if (!ins_rc[2] && fileObj[2])
4460 {
4461 PyDict_DelItem(_PyPopenProcs,
4462 fileObj[2]);
4463 }
4464 }
4465 }
Tim Peters11b23062003-04-23 02:39:17 +00004466
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004467 /*
4468 * Clean up our localized references for the dictionary keys
4469 * and value since PyDict_SetItem will Py_INCREF any copies
4470 * that got placed in the dictionary.
4471 */
4472 Py_XDECREF(procObj);
4473 Py_XDECREF(fileObj[0]);
4474 Py_XDECREF(fileObj[1]);
4475 Py_XDECREF(fileObj[2]);
4476 }
4477
4478 /* Child is launched. */
4479 return f;
4480}
4481
4482/*
4483 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4484 * exit code for the child process and return as a result of the close.
4485 *
4486 * This function uses the _PyPopenProcs dictionary in order to map the
4487 * input file pointer to information about the process that was
4488 * originally created by the popen* call that created the file pointer.
4489 * The dictionary uses the file pointer as a key (with one entry
4490 * inserted for each file returned by the original popen* call) and a
4491 * single list object as the value for all files from a single call.
4492 * The list object contains the Win32 process handle at [0], and a file
4493 * count at [1], which is initialized to the total number of file
4494 * handles using that list.
4495 *
4496 * This function closes whichever handle it is passed, and decrements
4497 * the file count in the dictionary for the process handle pointed to
4498 * by this file. On the last close (when the file count reaches zero),
4499 * this function will wait for the child process and then return its
4500 * exit code as the result of the close() operation. This permits the
4501 * files to be closed in any order - it is always the close() of the
4502 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004503 *
4504 * NOTE: This function is currently called with the GIL released.
4505 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004506 */
4507
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004508static int _PyPclose(FILE *file)
4509{
4510 int result;
4511 int exit_code;
4512 int pipe_pid;
4513 PyObject *procObj, *pidObj, *intObj, *fileObj;
4514 int file_count;
4515#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004516 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004517#endif
4518
4519 /* Close the file handle first, to ensure it can't block the
4520 * child from exiting if it's the last handle.
4521 */
4522 result = fclose(file);
4523
4524#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004525 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004526#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004527 if (_PyPopenProcs)
4528 {
4529 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4530 (procObj = PyDict_GetItem(_PyPopenProcs,
4531 fileObj)) != NULL &&
4532 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4533 (intObj = PyList_GetItem(procObj,1)) != NULL)
4534 {
4535 pipe_pid = (int) PyInt_AsLong(pidObj);
4536 file_count = (int) PyInt_AsLong(intObj);
4537
4538 if (file_count > 1)
4539 {
4540 /* Still other files referencing process */
4541 file_count--;
4542 PyList_SetItem(procObj,1,
4543 PyInt_FromLong((long) file_count));
4544 }
4545 else
4546 {
4547 /* Last file for this process */
4548 if (result != EOF &&
4549 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4550 {
4551 /* extract exit status */
4552 if (WIFEXITED(exit_code))
4553 {
4554 result = WEXITSTATUS(exit_code);
4555 }
4556 else
4557 {
4558 errno = EPIPE;
4559 result = -1;
4560 }
4561 }
4562 else
4563 {
4564 /* Indicate failure - this will cause the file object
4565 * to raise an I/O error and translate the last
4566 * error code from errno. We do have a problem with
4567 * last errors that overlap the normal errno table,
4568 * but that's a consistent problem with the file object.
4569 */
4570 result = -1;
4571 }
4572 }
4573
4574 /* Remove this file pointer from dictionary */
4575 PyDict_DelItem(_PyPopenProcs, fileObj);
4576
4577 if (PyDict_Size(_PyPopenProcs) == 0)
4578 {
4579 Py_DECREF(_PyPopenProcs);
4580 _PyPopenProcs = NULL;
4581 }
4582
4583 } /* if object retrieval ok */
4584
4585 Py_XDECREF(fileObj);
4586 } /* if _PyPopenProcs */
4587
4588#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004589 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004590#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004591 return result;
4592}
4593
4594#endif /* PYCC_??? */
4595
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004596#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004597
4598/*
4599 * Portable 'popen' replacement for Win32.
4600 *
4601 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4602 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004603 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004604 */
4605
4606#include <malloc.h>
4607#include <io.h>
4608#include <fcntl.h>
4609
4610/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4611#define POPEN_1 1
4612#define POPEN_2 2
4613#define POPEN_3 3
4614#define POPEN_4 4
4615
4616static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004617static int _PyPclose(FILE *file);
4618
4619/*
4620 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004621 * for use when retrieving the process exit code. See _PyPclose() below
4622 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004623 */
4624static PyObject *_PyPopenProcs = NULL;
4625
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004626
4627/* popen that works from a GUI.
4628 *
4629 * The result of this function is a pipe (file) connected to the
4630 * processes stdin or stdout, depending on the requested mode.
4631 */
4632
4633static PyObject *
4634posix_popen(PyObject *self, PyObject *args)
4635{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004636 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004637 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004638
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004639 char *cmdstring;
4640 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004641 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004642 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004643 return NULL;
4644
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004645 if (*mode == 'r')
4646 tm = _O_RDONLY;
4647 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004648 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004649 return NULL;
4650 } else
4651 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004652
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004653 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004654 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004655 return NULL;
4656 }
4657
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004658 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004659 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004660 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004661 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004662 else
4663 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4664
4665 return f;
4666}
4667
4668/* Variation on win32pipe.popen
4669 *
4670 * The result of this function is a pipe (file) connected to the
4671 * process's stdin, and a pipe connected to the process's stdout.
4672 */
4673
4674static PyObject *
4675win32_popen2(PyObject *self, PyObject *args)
4676{
4677 PyObject *f;
4678 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004679
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004680 char *cmdstring;
4681 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004682 int bufsize = -1;
4683 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004684 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004685
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004686 if (*mode == 't')
4687 tm = _O_TEXT;
4688 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004689 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004690 return NULL;
4691 } else
4692 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004693
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004694 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004695 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004696 return NULL;
4697 }
4698
4699 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004700
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004701 return f;
4702}
4703
4704/*
4705 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004706 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004707 * The result of this function is 3 pipes - the process's stdin,
4708 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004709 */
4710
4711static PyObject *
4712win32_popen3(PyObject *self, PyObject *args)
4713{
4714 PyObject *f;
4715 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004716
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004717 char *cmdstring;
4718 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004719 int bufsize = -1;
4720 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004721 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004722
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004723 if (*mode == 't')
4724 tm = _O_TEXT;
4725 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004726 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004727 return NULL;
4728 } else
4729 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004730
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004731 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004732 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004733 return NULL;
4734 }
4735
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004736 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004737
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004738 return f;
4739}
4740
4741/*
4742 * Variation on win32pipe.popen
4743 *
Tim Peters5aa91602002-01-30 05:46:57 +00004744 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004745 * and stdout+stderr combined as a single pipe.
4746 */
4747
4748static PyObject *
4749win32_popen4(PyObject *self, PyObject *args)
4750{
4751 PyObject *f;
4752 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004753
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004754 char *cmdstring;
4755 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004756 int bufsize = -1;
4757 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004758 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004759
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004760 if (*mode == 't')
4761 tm = _O_TEXT;
4762 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004763 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004764 return NULL;
4765 } else
4766 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004767
4768 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004769 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004770 return NULL;
4771 }
4772
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004773 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004774
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004775 return f;
4776}
4777
Mark Hammond08501372001-01-31 07:30:29 +00004778static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004779_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004780 HANDLE hStdin,
4781 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004782 HANDLE hStderr,
4783 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004784{
4785 PROCESS_INFORMATION piProcInfo;
4786 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004787 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004788 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004789 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004790 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004791 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004792
4793 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004794 char *comshell;
4795
Tim Peters92e4dd82002-10-05 01:47:34 +00004796 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004797 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004798 /* x < i, so x fits into an integer */
4799 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004800
4801 /* Explicitly check if we are using COMMAND.COM. If we are
4802 * then use the w9xpopen hack.
4803 */
4804 comshell = s1 + x;
4805 while (comshell >= s1 && *comshell != '\\')
4806 --comshell;
4807 ++comshell;
4808
4809 if (GetVersion() < 0x80000000 &&
4810 _stricmp(comshell, "command.com") != 0) {
4811 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004812 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004813 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004814 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004815 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004816 }
4817 else {
4818 /*
Tim Peters402d5982001-08-27 06:37:48 +00004819 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4820 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004821 */
Mark Hammond08501372001-01-31 07:30:29 +00004822 char modulepath[_MAX_PATH];
4823 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004824 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Thomas Wouters477c8d52006-05-27 19:21:47 +00004825 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004826 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004827 x = i+1;
4828 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004829 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004830 strncat(modulepath,
4831 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004832 (sizeof(modulepath)/sizeof(modulepath[0]))
4833 -strlen(modulepath));
4834 if (stat(modulepath, &statinfo) != 0) {
Guido van Rossumd8faa362007-04-27 19:54:29 +00004835 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
Tim Peters5aa91602002-01-30 05:46:57 +00004836 /* Eeek - file-not-found - possibly an embedding
4837 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004838 */
Tim Peters5aa91602002-01-30 05:46:57 +00004839 strncpy(modulepath,
4840 Py_GetExecPrefix(),
Guido van Rossumd8faa362007-04-27 19:54:29 +00004841 mplen);
4842 modulepath[mplen-1] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004843 if (modulepath[strlen(modulepath)-1] != '\\')
4844 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004845 strncat(modulepath,
4846 szConsoleSpawn,
Guido van Rossumd8faa362007-04-27 19:54:29 +00004847 mplen-strlen(modulepath));
Mark Hammond08501372001-01-31 07:30:29 +00004848 /* No where else to look - raise an easily identifiable
4849 error, rather than leaving Windows to report
4850 "file not found" - as the user is probably blissfully
4851 unaware this shim EXE is used, and it will confuse them.
4852 (well, it confused me for a while ;-)
4853 */
4854 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004855 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004856 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004857 "for popen to work with your shell "
4858 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004859 szConsoleSpawn);
4860 return FALSE;
4861 }
4862 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004863 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004864 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004865 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004866
Tim Peters92e4dd82002-10-05 01:47:34 +00004867 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004868 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004869 /* To maintain correct argument passing semantics,
4870 we pass the command-line as it stands, and allow
4871 quoting to be applied. w9xpopen.exe will then
4872 use its argv vector, and re-quote the necessary
4873 args for the ultimate child process.
4874 */
Tim Peters75cdad52001-11-28 22:07:30 +00004875 PyOS_snprintf(
4876 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004877 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004878 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004879 s1,
4880 s3,
4881 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004882 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004883 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004884 dialog:
4885 "Your program accessed mem currently in use at xxx"
4886 and a hopeful warning about the stability of your
4887 system.
4888 Cost is Ctrl+C wont kill children, but anyone
4889 who cares can have a go!
4890 */
4891 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004892 }
4893 }
4894
4895 /* Could be an else here to try cmd.exe / command.com in the path
4896 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004897 else {
Tim Peters402d5982001-08-27 06:37:48 +00004898 PyErr_SetString(PyExc_RuntimeError,
4899 "Cannot locate a COMSPEC environment variable to "
4900 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004901 return FALSE;
4902 }
Tim Peters5aa91602002-01-30 05:46:57 +00004903
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004904 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4905 siStartInfo.cb = sizeof(STARTUPINFO);
4906 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4907 siStartInfo.hStdInput = hStdin;
4908 siStartInfo.hStdOutput = hStdout;
4909 siStartInfo.hStdError = hStderr;
4910 siStartInfo.wShowWindow = SW_HIDE;
4911
4912 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004913 s2,
4914 NULL,
4915 NULL,
4916 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004917 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004918 NULL,
4919 NULL,
4920 &siStartInfo,
4921 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004922 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004923 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004924
Mark Hammondb37a3732000-08-14 04:47:33 +00004925 /* Return process handle */
4926 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004927 return TRUE;
4928 }
Tim Peters402d5982001-08-27 06:37:48 +00004929 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004930 return FALSE;
4931}
4932
4933/* The following code is based off of KB: Q190351 */
4934
4935static PyObject *
4936_PyPopen(char *cmdstring, int mode, int n)
4937{
4938 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4939 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004940 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004941
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004942 SECURITY_ATTRIBUTES saAttr;
4943 BOOL fSuccess;
4944 int fd1, fd2, fd3;
4945 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004946 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004947 PyObject *f;
4948
4949 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4950 saAttr.bInheritHandle = TRUE;
4951 saAttr.lpSecurityDescriptor = NULL;
4952
4953 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4954 return win32_error("CreatePipe", NULL);
4955
4956 /* Create new output read handle and the input write handle. Set
4957 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004958 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004959 * being created. */
4960 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004961 GetCurrentProcess(), &hChildStdinWrDup, 0,
4962 FALSE,
4963 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004964 if (!fSuccess)
4965 return win32_error("DuplicateHandle", NULL);
4966
4967 /* Close the inheritable version of ChildStdin
4968 that we're using. */
4969 CloseHandle(hChildStdinWr);
4970
4971 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4972 return win32_error("CreatePipe", NULL);
4973
4974 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004975 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4976 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004977 if (!fSuccess)
4978 return win32_error("DuplicateHandle", NULL);
4979
4980 /* Close the inheritable version of ChildStdout
4981 that we're using. */
4982 CloseHandle(hChildStdoutRd);
4983
4984 if (n != POPEN_4) {
4985 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4986 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004987 fSuccess = DuplicateHandle(GetCurrentProcess(),
4988 hChildStderrRd,
4989 GetCurrentProcess(),
4990 &hChildStderrRdDup, 0,
4991 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004992 if (!fSuccess)
4993 return win32_error("DuplicateHandle", NULL);
4994 /* Close the inheritable version of ChildStdErr that we're using. */
4995 CloseHandle(hChildStderrRd);
4996 }
Tim Peters5aa91602002-01-30 05:46:57 +00004997
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004998 switch (n) {
4999 case POPEN_1:
5000 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5001 case _O_WRONLY | _O_TEXT:
5002 /* Case for writing to child Stdin in text mode. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00005003 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005004 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005005 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005006 PyFile_SetBufSize(f, 0);
5007 /* We don't care about these pipes anymore, so close them. */
5008 CloseHandle(hChildStdoutRdDup);
5009 CloseHandle(hChildStderrRdDup);
5010 break;
5011
5012 case _O_RDONLY | _O_TEXT:
5013 /* Case for reading from child Stdout in text mode. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00005014 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005015 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005016 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005017 PyFile_SetBufSize(f, 0);
5018 /* We don't care about these pipes anymore, so close them. */
5019 CloseHandle(hChildStdinWrDup);
5020 CloseHandle(hChildStderrRdDup);
5021 break;
5022
5023 case _O_RDONLY | _O_BINARY:
5024 /* Case for readinig from child Stdout in binary mode. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00005025 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005026 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005027 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005028 PyFile_SetBufSize(f, 0);
5029 /* We don't care about these pipes anymore, so close them. */
5030 CloseHandle(hChildStdinWrDup);
5031 CloseHandle(hChildStderrRdDup);
5032 break;
5033
5034 case _O_WRONLY | _O_BINARY:
5035 /* Case for writing to child Stdin in binary mode. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00005036 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005037 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005038 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005039 PyFile_SetBufSize(f, 0);
5040 /* We don't care about these pipes anymore, so close them. */
5041 CloseHandle(hChildStdoutRdDup);
5042 CloseHandle(hChildStderrRdDup);
5043 break;
5044 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005045 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005046 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005047
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005048 case POPEN_2:
5049 case POPEN_4:
5050 {
5051 char *m1, *m2;
5052 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005053
Tim Peters7dca21e2002-08-19 00:42:29 +00005054 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005055 m1 = "r";
5056 m2 = "w";
5057 } else {
5058 m1 = "rb";
5059 m2 = "wb";
5060 }
5061
Thomas Wouters477c8d52006-05-27 19:21:47 +00005062 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005063 f1 = _fdopen(fd1, m2);
Thomas Wouters477c8d52006-05-27 19:21:47 +00005064 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005065 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005066 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005067 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00005068 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005069 PyFile_SetBufSize(p2, 0);
5070
5071 if (n != 4)
5072 CloseHandle(hChildStderrRdDup);
5073
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005074 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00005075 Py_XDECREF(p1);
5076 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00005077 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005078 break;
5079 }
Tim Peters5aa91602002-01-30 05:46:57 +00005080
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005081 case POPEN_3:
5082 {
5083 char *m1, *m2;
5084 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005085
Tim Peters7dca21e2002-08-19 00:42:29 +00005086 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005087 m1 = "r";
5088 m2 = "w";
5089 } else {
5090 m1 = "rb";
5091 m2 = "wb";
5092 }
5093
Thomas Wouters477c8d52006-05-27 19:21:47 +00005094 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005095 f1 = _fdopen(fd1, m2);
Thomas Wouters477c8d52006-05-27 19:21:47 +00005096 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005097 f2 = _fdopen(fd2, m1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00005098 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005099 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005100 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00005101 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5102 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005103 PyFile_SetBufSize(p1, 0);
5104 PyFile_SetBufSize(p2, 0);
5105 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005106 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00005107 Py_XDECREF(p1);
5108 Py_XDECREF(p2);
5109 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00005110 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005111 break;
5112 }
5113 }
5114
5115 if (n == POPEN_4) {
5116 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005117 hChildStdinRd,
5118 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005119 hChildStdoutWr,
5120 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005121 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005122 }
5123 else {
5124 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005125 hChildStdinRd,
5126 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005127 hChildStderrWr,
5128 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005129 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005130 }
5131
Mark Hammondb37a3732000-08-14 04:47:33 +00005132 /*
5133 * Insert the files we've created into the process dictionary
5134 * all referencing the list with the process handle and the
5135 * initial number of files (see description below in _PyPclose).
5136 * Since if _PyPclose later tried to wait on a process when all
5137 * handles weren't closed, it could create a deadlock with the
5138 * child, we spend some energy here to try to ensure that we
5139 * either insert all file handles into the dictionary or none
5140 * at all. It's a little clumsy with the various popen modes
5141 * and variable number of files involved.
5142 */
5143 if (!_PyPopenProcs) {
5144 _PyPopenProcs = PyDict_New();
5145 }
5146
5147 if (_PyPopenProcs) {
5148 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5149 int ins_rc[3];
5150
5151 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5152 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
5153
5154 procObj = PyList_New(2);
5155 hProcessObj = PyLong_FromVoidPtr(hProcess);
5156 intObj = PyInt_FromLong(file_count);
5157
5158 if (procObj && hProcessObj && intObj) {
5159 PyList_SetItem(procObj,0,hProcessObj);
5160 PyList_SetItem(procObj,1,intObj);
5161
5162 fileObj[0] = PyLong_FromVoidPtr(f1);
5163 if (fileObj[0]) {
5164 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5165 fileObj[0],
5166 procObj);
5167 }
5168 if (file_count >= 2) {
5169 fileObj[1] = PyLong_FromVoidPtr(f2);
5170 if (fileObj[1]) {
5171 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5172 fileObj[1],
5173 procObj);
5174 }
5175 }
5176 if (file_count >= 3) {
5177 fileObj[2] = PyLong_FromVoidPtr(f3);
5178 if (fileObj[2]) {
5179 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5180 fileObj[2],
5181 procObj);
5182 }
5183 }
5184
5185 if (ins_rc[0] < 0 || !fileObj[0] ||
5186 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5187 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5188 /* Something failed - remove any dictionary
5189 * entries that did make it.
5190 */
5191 if (!ins_rc[0] && fileObj[0]) {
5192 PyDict_DelItem(_PyPopenProcs,
5193 fileObj[0]);
5194 }
5195 if (!ins_rc[1] && fileObj[1]) {
5196 PyDict_DelItem(_PyPopenProcs,
5197 fileObj[1]);
5198 }
5199 if (!ins_rc[2] && fileObj[2]) {
5200 PyDict_DelItem(_PyPopenProcs,
5201 fileObj[2]);
5202 }
5203 }
5204 }
Tim Peters5aa91602002-01-30 05:46:57 +00005205
Mark Hammondb37a3732000-08-14 04:47:33 +00005206 /*
5207 * Clean up our localized references for the dictionary keys
5208 * and value since PyDict_SetItem will Py_INCREF any copies
5209 * that got placed in the dictionary.
5210 */
5211 Py_XDECREF(procObj);
5212 Py_XDECREF(fileObj[0]);
5213 Py_XDECREF(fileObj[1]);
5214 Py_XDECREF(fileObj[2]);
5215 }
5216
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005217 /* Child is launched. Close the parents copy of those pipe
5218 * handles that only the child should have open. You need to
5219 * make sure that no handles to the write end of the output pipe
5220 * are maintained in this process or else the pipe will not close
5221 * when the child process exits and the ReadFile will hang. */
5222
5223 if (!CloseHandle(hChildStdinRd))
5224 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005225
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005226 if (!CloseHandle(hChildStdoutWr))
5227 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005228
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005229 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5230 return win32_error("CloseHandle", NULL);
5231
5232 return f;
5233}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005234
5235/*
5236 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5237 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005238 *
5239 * This function uses the _PyPopenProcs dictionary in order to map the
5240 * input file pointer to information about the process that was
5241 * originally created by the popen* call that created the file pointer.
5242 * The dictionary uses the file pointer as a key (with one entry
5243 * inserted for each file returned by the original popen* call) and a
5244 * single list object as the value for all files from a single call.
5245 * The list object contains the Win32 process handle at [0], and a file
5246 * count at [1], which is initialized to the total number of file
5247 * handles using that list.
5248 *
5249 * This function closes whichever handle it is passed, and decrements
5250 * the file count in the dictionary for the process handle pointed to
5251 * by this file. On the last close (when the file count reaches zero),
5252 * this function will wait for the child process and then return its
5253 * exit code as the result of the close() operation. This permits the
5254 * files to be closed in any order - it is always the close() of the
5255 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005256 *
5257 * NOTE: This function is currently called with the GIL released.
5258 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005259 */
Tim Peters736aa322000-09-01 06:51:24 +00005260
Fredrik Lundh56055a42000-07-23 19:47:12 +00005261static int _PyPclose(FILE *file)
5262{
Fredrik Lundh20318932000-07-26 17:29:12 +00005263 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005264 DWORD exit_code;
5265 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00005266 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5267 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005268#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005269 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005270#endif
5271
Fredrik Lundh20318932000-07-26 17:29:12 +00005272 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00005273 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00005274 */
5275 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005276#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005277 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005278#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005279 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005280 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5281 (procObj = PyDict_GetItem(_PyPopenProcs,
5282 fileObj)) != NULL &&
5283 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5284 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5285
5286 hProcess = PyLong_AsVoidPtr(hProcessObj);
5287 file_count = PyInt_AsLong(intObj);
5288
5289 if (file_count > 1) {
5290 /* Still other files referencing process */
5291 file_count--;
5292 PyList_SetItem(procObj,1,
5293 PyInt_FromLong(file_count));
5294 } else {
5295 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00005296 if (result != EOF &&
5297 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5298 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00005299 /* Possible truncation here in 16-bit environments, but
5300 * real exit codes are just the lower byte in any event.
5301 */
5302 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005303 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00005304 /* Indicate failure - this will cause the file object
5305 * to raise an I/O error and translate the last Win32
5306 * error code from errno. We do have a problem with
5307 * last errors that overlap the normal errno table,
5308 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005309 */
Fredrik Lundh20318932000-07-26 17:29:12 +00005310 if (result != EOF) {
5311 /* If the error wasn't from the fclose(), then
5312 * set errno for the file object error handling.
5313 */
5314 errno = GetLastError();
5315 }
5316 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005317 }
5318
5319 /* Free up the native handle at this point */
5320 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00005321 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005322
Mark Hammondb37a3732000-08-14 04:47:33 +00005323 /* Remove this file pointer from dictionary */
5324 PyDict_DelItem(_PyPopenProcs, fileObj);
5325
5326 if (PyDict_Size(_PyPopenProcs) == 0) {
5327 Py_DECREF(_PyPopenProcs);
5328 _PyPopenProcs = NULL;
5329 }
5330
5331 } /* if object retrieval ok */
5332
5333 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005334 } /* if _PyPopenProcs */
5335
Tim Peters736aa322000-09-01 06:51:24 +00005336#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005337 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005338#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005339 return result;
5340}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005341
5342#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005343static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005344posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005345{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005346 char *name;
5347 char *mode = "r";
5348 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00005349 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005350 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005351 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00005352 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00005353 /* Strip mode of binary or text modifiers */
5354 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5355 mode = "r";
5356 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5357 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00005358 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005359 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005360 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00005361 if (fp == NULL)
5362 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005363 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005364 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005365 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005366 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005367}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005368
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005369#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005370#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005371
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005372
Guido van Rossumb6775db1994-08-01 11:34:53 +00005373#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005374PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005375"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005376Set the current process's user id.");
5377
Barry Warsaw53699e91996-12-10 23:23:01 +00005378static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005379posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005380{
5381 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005382 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005383 return NULL;
5384 if (setuid(uid) < 0)
5385 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005386 Py_INCREF(Py_None);
5387 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005388}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005389#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005390
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005391
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005392#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005393PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005394"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005395Set the current process's effective user id.");
5396
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005397static PyObject *
5398posix_seteuid (PyObject *self, PyObject *args)
5399{
5400 int euid;
5401 if (!PyArg_ParseTuple(args, "i", &euid)) {
5402 return NULL;
5403 } else if (seteuid(euid) < 0) {
5404 return posix_error();
5405 } else {
5406 Py_INCREF(Py_None);
5407 return Py_None;
5408 }
5409}
5410#endif /* HAVE_SETEUID */
5411
5412#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005413PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005414"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005415Set the current process's effective group id.");
5416
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005417static PyObject *
5418posix_setegid (PyObject *self, PyObject *args)
5419{
5420 int egid;
5421 if (!PyArg_ParseTuple(args, "i", &egid)) {
5422 return NULL;
5423 } else if (setegid(egid) < 0) {
5424 return posix_error();
5425 } else {
5426 Py_INCREF(Py_None);
5427 return Py_None;
5428 }
5429}
5430#endif /* HAVE_SETEGID */
5431
5432#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005433PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005434"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005435Set the current process's real and effective user ids.");
5436
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005437static PyObject *
5438posix_setreuid (PyObject *self, PyObject *args)
5439{
5440 int ruid, euid;
5441 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
5442 return NULL;
5443 } else if (setreuid(ruid, euid) < 0) {
5444 return posix_error();
5445 } else {
5446 Py_INCREF(Py_None);
5447 return Py_None;
5448 }
5449}
5450#endif /* HAVE_SETREUID */
5451
5452#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005453PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005454"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005455Set the current process's real and effective group ids.");
5456
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005457static PyObject *
5458posix_setregid (PyObject *self, PyObject *args)
5459{
5460 int rgid, egid;
5461 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
5462 return NULL;
5463 } else if (setregid(rgid, egid) < 0) {
5464 return posix_error();
5465 } else {
5466 Py_INCREF(Py_None);
5467 return Py_None;
5468 }
5469}
5470#endif /* HAVE_SETREGID */
5471
Guido van Rossumb6775db1994-08-01 11:34:53 +00005472#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005473PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005474"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005475Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005476
Barry Warsaw53699e91996-12-10 23:23:01 +00005477static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005478posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005479{
5480 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005481 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005482 return NULL;
5483 if (setgid(gid) < 0)
5484 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005485 Py_INCREF(Py_None);
5486 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005487}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005488#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005489
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005490#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005491PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005492"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005493Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005494
5495static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00005496posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005497{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005498 int i, len;
5499 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005500
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005501 if (!PySequence_Check(groups)) {
5502 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5503 return NULL;
5504 }
5505 len = PySequence_Size(groups);
5506 if (len > MAX_GROUPS) {
5507 PyErr_SetString(PyExc_ValueError, "too many groups");
5508 return NULL;
5509 }
5510 for(i = 0; i < len; i++) {
5511 PyObject *elem;
5512 elem = PySequence_GetItem(groups, i);
5513 if (!elem)
5514 return NULL;
Guido van Rossumddefaf32007-01-14 03:31:43 +00005515 if (!PyLong_Check(elem)) {
5516 PyErr_SetString(PyExc_TypeError,
5517 "groups must be integers");
5518 Py_DECREF(elem);
5519 return NULL;
5520 } else {
5521 unsigned long x = PyLong_AsUnsignedLong(elem);
5522 if (PyErr_Occurred()) {
5523 PyErr_SetString(PyExc_TypeError,
5524 "group id too big");
Georg Brandla13c2442005-11-22 19:30:31 +00005525 Py_DECREF(elem);
5526 return NULL;
Georg Brandla13c2442005-11-22 19:30:31 +00005527 }
Georg Brandla13c2442005-11-22 19:30:31 +00005528 grouplist[i] = x;
Guido van Rossumddefaf32007-01-14 03:31:43 +00005529 /* read back the value to see if it fitted in gid_t */
Georg Brandla13c2442005-11-22 19:30:31 +00005530 if (grouplist[i] != x) {
5531 PyErr_SetString(PyExc_TypeError,
5532 "group id too big");
5533 Py_DECREF(elem);
5534 return NULL;
5535 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005536 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005537 Py_DECREF(elem);
5538 }
5539
5540 if (setgroups(len, grouplist) < 0)
5541 return posix_error();
5542 Py_INCREF(Py_None);
5543 return Py_None;
5544}
5545#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005546
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005547#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
5548static PyObject *
5549wait_helper(int pid, int status, struct rusage *ru)
5550{
5551 PyObject *result;
5552 static PyObject *struct_rusage;
5553
5554 if (pid == -1)
5555 return posix_error();
5556
5557 if (struct_rusage == NULL) {
5558 PyObject *m = PyImport_ImportModule("resource");
5559 if (m == NULL)
5560 return NULL;
5561 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5562 Py_DECREF(m);
5563 if (struct_rusage == NULL)
5564 return NULL;
5565 }
5566
5567 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5568 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5569 if (!result)
5570 return NULL;
5571
5572#ifndef doubletime
5573#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5574#endif
5575
5576 PyStructSequence_SET_ITEM(result, 0,
5577 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5578 PyStructSequence_SET_ITEM(result, 1,
5579 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5580#define SET_INT(result, index, value)\
5581 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5582 SET_INT(result, 2, ru->ru_maxrss);
5583 SET_INT(result, 3, ru->ru_ixrss);
5584 SET_INT(result, 4, ru->ru_idrss);
5585 SET_INT(result, 5, ru->ru_isrss);
5586 SET_INT(result, 6, ru->ru_minflt);
5587 SET_INT(result, 7, ru->ru_majflt);
5588 SET_INT(result, 8, ru->ru_nswap);
5589 SET_INT(result, 9, ru->ru_inblock);
5590 SET_INT(result, 10, ru->ru_oublock);
5591 SET_INT(result, 11, ru->ru_msgsnd);
5592 SET_INT(result, 12, ru->ru_msgrcv);
5593 SET_INT(result, 13, ru->ru_nsignals);
5594 SET_INT(result, 14, ru->ru_nvcsw);
5595 SET_INT(result, 15, ru->ru_nivcsw);
5596#undef SET_INT
5597
5598 if (PyErr_Occurred()) {
5599 Py_DECREF(result);
5600 return NULL;
5601 }
5602
5603 return Py_BuildValue("iiN", pid, status, result);
5604}
5605#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
5606
5607#ifdef HAVE_WAIT3
5608PyDoc_STRVAR(posix_wait3__doc__,
5609"wait3(options) -> (pid, status, rusage)\n\n\
5610Wait for completion of a child process.");
5611
5612static PyObject *
5613posix_wait3(PyObject *self, PyObject *args)
5614{
5615 int pid, options;
5616 struct rusage ru;
5617 WAIT_TYPE status;
5618 WAIT_STATUS_INT(status) = 0;
5619
5620 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5621 return NULL;
5622
5623 Py_BEGIN_ALLOW_THREADS
5624 pid = wait3(&status, options, &ru);
5625 Py_END_ALLOW_THREADS
5626
5627 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
5628}
5629#endif /* HAVE_WAIT3 */
5630
5631#ifdef HAVE_WAIT4
5632PyDoc_STRVAR(posix_wait4__doc__,
5633"wait4(pid, options) -> (pid, status, rusage)\n\n\
5634Wait for completion of a given child process.");
5635
5636static PyObject *
5637posix_wait4(PyObject *self, PyObject *args)
5638{
5639 int pid, options;
5640 struct rusage ru;
5641 WAIT_TYPE status;
5642 WAIT_STATUS_INT(status) = 0;
5643
5644 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5645 return NULL;
5646
5647 Py_BEGIN_ALLOW_THREADS
5648 pid = wait4(pid, &status, options, &ru);
5649 Py_END_ALLOW_THREADS
5650
5651 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
5652}
5653#endif /* HAVE_WAIT4 */
5654
Guido van Rossumb6775db1994-08-01 11:34:53 +00005655#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005656PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005657"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005658Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005659
Barry Warsaw53699e91996-12-10 23:23:01 +00005660static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005661posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005662{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005663 int pid, options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005664 WAIT_TYPE status;
5665 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005666
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005667 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005668 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005669 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005670 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005671 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005672 if (pid == -1)
5673 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005674
5675 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005676}
5677
Tim Petersab034fa2002-02-01 11:27:43 +00005678#elif defined(HAVE_CWAIT)
5679
5680/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005681PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005682"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005683"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005684
5685static PyObject *
5686posix_waitpid(PyObject *self, PyObject *args)
5687{
Thomas Wouters477c8d52006-05-27 19:21:47 +00005688 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005689 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005690
5691 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5692 return NULL;
5693 Py_BEGIN_ALLOW_THREADS
5694 pid = _cwait(&status, pid, options);
5695 Py_END_ALLOW_THREADS
5696 if (pid == -1)
5697 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005698
5699 /* shift the status left a byte so this is more like the POSIX waitpid */
5700 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005701}
5702#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005703
Guido van Rossumad0ee831995-03-01 10:34:45 +00005704#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005705PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005706"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005707Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005708
Barry Warsaw53699e91996-12-10 23:23:01 +00005709static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005710posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005711{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005712 int pid;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005713 WAIT_TYPE status;
5714 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005715
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005716 Py_BEGIN_ALLOW_THREADS
5717 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005718 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005719 if (pid == -1)
5720 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005721
5722 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005723}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005724#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005725
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005726
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005727PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005728"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005729Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005730
Barry Warsaw53699e91996-12-10 23:23:01 +00005731static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005732posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005733{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005734#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005735 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005736#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005737#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005738 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005739#else
5740 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5741#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005742#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005743}
5744
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005745
Guido van Rossumb6775db1994-08-01 11:34:53 +00005746#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005747PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005748"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005749Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005750
Barry Warsaw53699e91996-12-10 23:23:01 +00005751static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005752posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005753{
Thomas Wouters89f507f2006-12-13 04:49:30 +00005754 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005755 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005756 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005757 int n;
Thomas Wouters89f507f2006-12-13 04:49:30 +00005758 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00005759
5760 if (!PyArg_ParseTuple(args, "et:readlink",
5761 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005762 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00005763 v = PySequence_GetItem(args, 0);
5764 if (v == NULL) return NULL;
5765
5766 if (PyUnicode_Check(v)) {
5767 arg_is_unicode = 1;
5768 }
5769 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005770
Barry Warsaw53699e91996-12-10 23:23:01 +00005771 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005772 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005773 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005774 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005775 return posix_error_with_filename(path);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005776
5777 v = PyString_FromStringAndSize(buf, n);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005778 if (arg_is_unicode) {
5779 PyObject *w;
5780
5781 w = PyUnicode_FromEncodedObject(v,
5782 Py_FileSystemDefaultEncoding,
5783 "strict");
5784 if (w != NULL) {
5785 Py_DECREF(v);
5786 v = w;
5787 }
5788 else {
5789 /* fall back to the original byte string, as
5790 discussed in patch #683592 */
5791 PyErr_Clear();
5792 }
5793 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00005794 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005795}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005796#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005797
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005798
Guido van Rossumb6775db1994-08-01 11:34:53 +00005799#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005800PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005801"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005802Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005803
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005804static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005805posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005806{
Thomas Wouters477c8d52006-05-27 19:21:47 +00005807 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005808}
5809#endif /* HAVE_SYMLINK */
5810
5811
5812#ifdef HAVE_TIMES
5813#ifndef HZ
5814#define HZ 60 /* Universal constant :-) */
5815#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005816
Guido van Rossumd48f2521997-12-05 22:19:34 +00005817#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5818static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005819system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005820{
5821 ULONG value = 0;
5822
5823 Py_BEGIN_ALLOW_THREADS
5824 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5825 Py_END_ALLOW_THREADS
5826
5827 return value;
5828}
5829
5830static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005831posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005832{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005833 /* Currently Only Uptime is Provided -- Others Later */
5834 return Py_BuildValue("ddddd",
5835 (double)0 /* t.tms_utime / HZ */,
5836 (double)0 /* t.tms_stime / HZ */,
5837 (double)0 /* t.tms_cutime / HZ */,
5838 (double)0 /* t.tms_cstime / HZ */,
5839 (double)system_uptime() / 1000);
5840}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005841#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005842static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005843posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005844{
5845 struct tms t;
5846 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005847 errno = 0;
5848 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005849 if (c == (clock_t) -1)
5850 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005851 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005852 (double)t.tms_utime / HZ,
5853 (double)t.tms_stime / HZ,
5854 (double)t.tms_cutime / HZ,
5855 (double)t.tms_cstime / HZ,
5856 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005857}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005858#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005859#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005860
5861
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005862#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005863#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005864static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005865posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005866{
5867 FILETIME create, exit, kernel, user;
5868 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005869 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005870 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5871 /* The fields of a FILETIME structure are the hi and lo part
5872 of a 64-bit value expressed in 100 nanosecond units.
5873 1e7 is one second in such units; 1e-7 the inverse.
5874 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5875 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005876 return Py_BuildValue(
5877 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005878 (double)(kernel.dwHighDateTime*429.4967296 +
5879 kernel.dwLowDateTime*1e-7),
5880 (double)(user.dwHighDateTime*429.4967296 +
5881 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005882 (double)0,
5883 (double)0,
5884 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005885}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005886#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005887
5888#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005889PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005890"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005891Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005892#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005893
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005894
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005895#ifdef HAVE_GETSID
5896PyDoc_STRVAR(posix_getsid__doc__,
5897"getsid(pid) -> sid\n\n\
5898Call the system call getsid().");
5899
5900static PyObject *
5901posix_getsid(PyObject *self, PyObject *args)
5902{
5903 int pid, sid;
5904 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5905 return NULL;
5906 sid = getsid(pid);
5907 if (sid < 0)
5908 return posix_error();
5909 return PyInt_FromLong((long)sid);
5910}
5911#endif /* HAVE_GETSID */
5912
5913
Guido van Rossumb6775db1994-08-01 11:34:53 +00005914#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005915PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005916"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005917Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005918
Barry Warsaw53699e91996-12-10 23:23:01 +00005919static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005920posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005921{
Guido van Rossum687dd131993-05-17 08:34:16 +00005922 if (setsid() < 0)
5923 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005924 Py_INCREF(Py_None);
5925 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005926}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005927#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005928
Guido van Rossumb6775db1994-08-01 11:34:53 +00005929#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005930PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005931"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005932Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005933
Barry Warsaw53699e91996-12-10 23:23:01 +00005934static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005935posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005936{
5937 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005938 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005939 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005940 if (setpgid(pid, pgrp) < 0)
5941 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005942 Py_INCREF(Py_None);
5943 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005944}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005945#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005946
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005947
Guido van Rossumb6775db1994-08-01 11:34:53 +00005948#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005949PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005950"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005951Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005952
Barry Warsaw53699e91996-12-10 23:23:01 +00005953static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005954posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005955{
5956 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005957 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005958 return NULL;
5959 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005960 if (pgid < 0)
5961 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005962 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005963}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005964#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005965
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005966
Guido van Rossumb6775db1994-08-01 11:34:53 +00005967#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005968PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005969"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005970Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005971
Barry Warsaw53699e91996-12-10 23:23:01 +00005972static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005973posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005974{
5975 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005976 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005977 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005978 if (tcsetpgrp(fd, pgid) < 0)
5979 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005980 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005981 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005982}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005983#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005984
Guido van Rossum687dd131993-05-17 08:34:16 +00005985/* Functions acting on file descriptors */
5986
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005987PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005988"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005989Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005990
Barry Warsaw53699e91996-12-10 23:23:01 +00005991static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005992posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005993{
Mark Hammondef8b6542001-05-13 08:04:26 +00005994 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005995 int flag;
5996 int mode = 0777;
5997 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005998
5999#ifdef MS_WINDOWS
6000 if (unicode_file_names()) {
6001 PyUnicodeObject *po;
6002 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6003 Py_BEGIN_ALLOW_THREADS
6004 /* PyUnicode_AS_UNICODE OK without thread
6005 lock as it is a simple dereference. */
6006 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6007 Py_END_ALLOW_THREADS
6008 if (fd < 0)
6009 return posix_error();
6010 return PyInt_FromLong((long)fd);
6011 }
6012 /* Drop the argument parsing error as narrow strings
6013 are also valid. */
6014 PyErr_Clear();
6015 }
6016#endif
6017
Tim Peters5aa91602002-01-30 05:46:57 +00006018 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00006019 Py_FileSystemDefaultEncoding, &file,
6020 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00006021 return NULL;
6022
Barry Warsaw53699e91996-12-10 23:23:01 +00006023 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006024 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00006025 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006026 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00006027 return posix_error_with_allocated_filename(file);
6028 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00006029 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006030}
6031
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006032
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006033PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006034"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006035Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006036
Barry Warsaw53699e91996-12-10 23:23:01 +00006037static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006038posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006039{
6040 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006041 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006042 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006043 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006044 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006045 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006046 if (res < 0)
6047 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006048 Py_INCREF(Py_None);
6049 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006050}
6051
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006052
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006053PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006054"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006055Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006056
Barry Warsaw53699e91996-12-10 23:23:01 +00006057static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006058posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006059{
6060 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006061 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006062 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006063 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006064 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006065 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006066 if (fd < 0)
6067 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006068 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006069}
6070
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006071
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006072PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006073"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006074Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006075
Barry Warsaw53699e91996-12-10 23:23:01 +00006076static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006077posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006078{
6079 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006080 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00006081 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006082 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006083 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00006084 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006085 if (res < 0)
6086 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006087 Py_INCREF(Py_None);
6088 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006089}
6090
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006091
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006092PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006093"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006094Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006095
Barry Warsaw53699e91996-12-10 23:23:01 +00006096static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006097posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006098{
6099 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006100#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006101 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006102#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00006103 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006104#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006105 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006106 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00006107 return NULL;
6108#ifdef SEEK_SET
6109 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6110 switch (how) {
6111 case 0: how = SEEK_SET; break;
6112 case 1: how = SEEK_CUR; break;
6113 case 2: how = SEEK_END; break;
6114 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006115#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006116
6117#if !defined(HAVE_LARGEFILE_SUPPORT)
6118 pos = PyInt_AsLong(posobj);
6119#else
6120 pos = PyLong_Check(posobj) ?
6121 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
6122#endif
6123 if (PyErr_Occurred())
6124 return NULL;
6125
Barry Warsaw53699e91996-12-10 23:23:01 +00006126 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006127#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00006128 res = _lseeki64(fd, pos, how);
6129#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006130 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006131#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006132 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006133 if (res < 0)
6134 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006135
6136#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00006137 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006138#else
6139 return PyLong_FromLongLong(res);
6140#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006141}
6142
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006143
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006144PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006145"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006146Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006147
Barry Warsaw53699e91996-12-10 23:23:01 +00006148static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006149posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006150{
Guido van Rossum572dbf82007-04-27 23:53:51 +00006151 int fd, size;
6152 Py_ssize_t n;
Barry Warsaw53699e91996-12-10 23:23:01 +00006153 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006154 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00006155 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00006156 if (size < 0) {
6157 errno = EINVAL;
6158 return posix_error();
6159 }
Guido van Rossum572dbf82007-04-27 23:53:51 +00006160 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006161 if (buffer == NULL)
6162 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006163 Py_BEGIN_ALLOW_THREADS
Guido van Rossum572dbf82007-04-27 23:53:51 +00006164 n = read(fd, PyBytes_AsString(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00006165 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00006166 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006167 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00006168 return posix_error();
6169 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00006170 if (n != size)
Guido van Rossum572dbf82007-04-27 23:53:51 +00006171 PyBytes_Resize(buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00006172 return buffer;
6173}
6174
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006175
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006176PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006177"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006178Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006179
Barry Warsaw53699e91996-12-10 23:23:01 +00006180static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006181posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006182{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006183 int fd;
6184 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00006185 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006186
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006187 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00006188 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006189 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006190 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00006191 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006192 if (size < 0)
6193 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006194 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006195}
6196
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006197
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006198PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006199"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006200Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006201
Barry Warsaw53699e91996-12-10 23:23:01 +00006202static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006203posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006204{
6205 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00006206 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00006207 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006208 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006209 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006210#ifdef __VMS
6211 /* on OpenVMS we must ensure that all bytes are written to the file */
6212 fsync(fd);
6213#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006214 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00006215 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00006216 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00006217 if (res != 0) {
6218#ifdef MS_WINDOWS
6219 return win32_error("fstat", NULL);
6220#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006221 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006222#endif
6223 }
Tim Peters5aa91602002-01-30 05:46:57 +00006224
Martin v. Löwis14694662006-02-03 12:54:16 +00006225 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006226}
6227
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006228
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006229PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006230"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006231Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006232
Barry Warsaw53699e91996-12-10 23:23:01 +00006233static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006234posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006235{
Guido van Rossum687dd131993-05-17 08:34:16 +00006236 int fd;
Guido van Rossumd8faa362007-04-27 19:54:29 +00006237 char *orgmode = "r";
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006238 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00006239 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00006240 PyObject *f;
Guido van Rossumd8faa362007-04-27 19:54:29 +00006241 char *mode;
6242 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00006243 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006244
Guido van Rossumd8faa362007-04-27 19:54:29 +00006245 /* Sanitize mode. See fileobject.c */
6246 mode = PyMem_MALLOC(strlen(orgmode)+3);
6247 if (!mode) {
6248 PyErr_NoMemory();
6249 return NULL;
6250 }
6251 strcpy(mode, orgmode);
6252 if (_PyFile_SanitizeMode(mode)) {
6253 PyMem_FREE(mode);
Thomas Heller1f043e22002-11-07 16:00:59 +00006254 return NULL;
6255 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006256 Py_BEGIN_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006257#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
6258 if (mode[0] == 'a') {
6259 /* try to make sure the O_APPEND flag is set */
6260 int flags;
6261 flags = fcntl(fd, F_GETFL);
6262 if (flags != -1)
6263 fcntl(fd, F_SETFL, flags | O_APPEND);
6264 fp = fdopen(fd, mode);
6265 if (fp == NULL && flags != -1)
6266 /* restore old mode if fdopen failed */
6267 fcntl(fd, F_SETFL, flags);
6268 } else {
6269 fp = fdopen(fd, mode);
6270 }
6271#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006272 fp = fdopen(fd, mode);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006273#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006274 Py_END_ALLOW_THREADS
Guido van Rossum360e4b82007-05-14 22:51:27 +00006275 PyMem_FREE(mode);
Guido van Rossum687dd131993-05-17 08:34:16 +00006276 if (fp == NULL)
6277 return posix_error();
Guido van Rossumd8faa362007-04-27 19:54:29 +00006278 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006279 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00006280 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006281 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006282}
6283
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006284PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006285"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006286Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006287connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006288
6289static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006290posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006291{
6292 int fd;
6293 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6294 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006295 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006296}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006297
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006298#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006299PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006300"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006301Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006302
Barry Warsaw53699e91996-12-10 23:23:01 +00006303static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006304posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006305{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006306#if defined(PYOS_OS2)
6307 HFILE read, write;
6308 APIRET rc;
6309
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006310 Py_BEGIN_ALLOW_THREADS
6311 rc = DosCreatePipe( &read, &write, 4096);
6312 Py_END_ALLOW_THREADS
6313 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006314 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006315
6316 return Py_BuildValue("(ii)", read, write);
6317#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006318#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00006319 int fds[2];
6320 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00006321 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006322 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00006323 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006324 if (res != 0)
6325 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006326 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006327#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00006328 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006329 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00006330 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00006331 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006332 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00006333 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00006334 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006335 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00006336 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6337 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006338 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006339#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006340#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006341}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006342#endif /* HAVE_PIPE */
6343
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006344
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006345#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006346PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006347"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006348Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006349
Barry Warsaw53699e91996-12-10 23:23:01 +00006350static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006351posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006352{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006353 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006354 int mode = 0666;
6355 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006356 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006357 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006358 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006359 res = mkfifo(filename, mode);
6360 Py_END_ALLOW_THREADS
6361 if (res < 0)
6362 return posix_error();
6363 Py_INCREF(Py_None);
6364 return Py_None;
6365}
6366#endif
6367
6368
Neal Norwitz11690112002-07-30 01:08:28 +00006369#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006370PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006371"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006372Create a filesystem node (file, device special file or named pipe)\n\
6373named filename. mode specifies both the permissions to use and the\n\
6374type of node to be created, being combined (bitwise OR) with one of\n\
6375S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006376device defines the newly created device special file (probably using\n\
6377os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006378
6379
6380static PyObject *
6381posix_mknod(PyObject *self, PyObject *args)
6382{
6383 char *filename;
6384 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006385 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006386 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00006387 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006388 return NULL;
6389 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006390 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00006391 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006392 if (res < 0)
6393 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006394 Py_INCREF(Py_None);
6395 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006396}
6397#endif
6398
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006399#ifdef HAVE_DEVICE_MACROS
6400PyDoc_STRVAR(posix_major__doc__,
6401"major(device) -> major number\n\
6402Extracts a device major number from a raw device number.");
6403
6404static PyObject *
6405posix_major(PyObject *self, PyObject *args)
6406{
6407 int device;
6408 if (!PyArg_ParseTuple(args, "i:major", &device))
6409 return NULL;
6410 return PyInt_FromLong((long)major(device));
6411}
6412
6413PyDoc_STRVAR(posix_minor__doc__,
6414"minor(device) -> minor number\n\
6415Extracts a device minor number from a raw device number.");
6416
6417static PyObject *
6418posix_minor(PyObject *self, PyObject *args)
6419{
6420 int device;
6421 if (!PyArg_ParseTuple(args, "i:minor", &device))
6422 return NULL;
6423 return PyInt_FromLong((long)minor(device));
6424}
6425
6426PyDoc_STRVAR(posix_makedev__doc__,
6427"makedev(major, minor) -> device number\n\
6428Composes a raw device number from the major and minor device numbers.");
6429
6430static PyObject *
6431posix_makedev(PyObject *self, PyObject *args)
6432{
6433 int major, minor;
6434 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6435 return NULL;
6436 return PyInt_FromLong((long)makedev(major, minor));
6437}
6438#endif /* device macros */
6439
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006440
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006441#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006442PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006443"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006444Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006445
Barry Warsaw53699e91996-12-10 23:23:01 +00006446static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006447posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006448{
6449 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006450 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006451 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006452 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006453
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006454 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006455 return NULL;
6456
6457#if !defined(HAVE_LARGEFILE_SUPPORT)
6458 length = PyInt_AsLong(lenobj);
6459#else
6460 length = PyLong_Check(lenobj) ?
6461 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6462#endif
6463 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006464 return NULL;
6465
Barry Warsaw53699e91996-12-10 23:23:01 +00006466 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006467 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006468 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006469 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006470 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006471 return NULL;
6472 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006473 Py_INCREF(Py_None);
6474 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006475}
6476#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006477
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006478#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006479PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006480"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006481Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006482
Fred Drake762e2061999-08-26 17:23:54 +00006483/* Save putenv() parameters as values here, so we can collect them when they
6484 * get re-set with another call for the same key. */
6485static PyObject *posix_putenv_garbage;
6486
Tim Peters5aa91602002-01-30 05:46:57 +00006487static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006488posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006489{
6490 char *s1, *s2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006491 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006492 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006493 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006494
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006495 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006496 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006497
6498#if defined(PYOS_OS2)
6499 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6500 APIRET rc;
6501
Guido van Rossumd48f2521997-12-05 22:19:34 +00006502 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6503 if (rc != NO_ERROR)
6504 return os2_error(rc);
6505
6506 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6507 APIRET rc;
6508
Guido van Rossumd48f2521997-12-05 22:19:34 +00006509 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6510 if (rc != NO_ERROR)
6511 return os2_error(rc);
6512 } else {
6513#endif
6514
Fred Drake762e2061999-08-26 17:23:54 +00006515 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006516 len = strlen(s1) + strlen(s2) + 2;
6517 /* len includes space for a trailing \0; the size arg to
6518 PyString_FromStringAndSize does not count that */
6519 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006520 if (newstr == NULL)
6521 return PyErr_NoMemory();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006522 newenv = PyString_AS_STRING(newstr);
6523 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6524 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006525 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006526 posix_error();
6527 return NULL;
6528 }
Fred Drake762e2061999-08-26 17:23:54 +00006529 /* Install the first arg and newstr in posix_putenv_garbage;
6530 * this will cause previous value to be collected. This has to
6531 * happen after the real putenv() call because the old value
6532 * was still accessible until then. */
6533 if (PyDict_SetItem(posix_putenv_garbage,
6534 PyTuple_GET_ITEM(args, 0), newstr)) {
6535 /* really not much we can do; just leak */
6536 PyErr_Clear();
6537 }
6538 else {
6539 Py_DECREF(newstr);
6540 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006541
6542#if defined(PYOS_OS2)
6543 }
6544#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006545 Py_INCREF(Py_None);
6546 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006547}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006548#endif /* putenv */
6549
Guido van Rossumc524d952001-10-19 01:31:59 +00006550#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006551PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006552"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006553Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006554
6555static PyObject *
6556posix_unsetenv(PyObject *self, PyObject *args)
6557{
6558 char *s1;
6559
6560 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6561 return NULL;
6562
6563 unsetenv(s1);
6564
6565 /* Remove the key from posix_putenv_garbage;
6566 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006567 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006568 * old value was still accessible until then.
6569 */
6570 if (PyDict_DelItem(posix_putenv_garbage,
6571 PyTuple_GET_ITEM(args, 0))) {
6572 /* really not much we can do; just leak */
6573 PyErr_Clear();
6574 }
6575
6576 Py_INCREF(Py_None);
6577 return Py_None;
6578}
6579#endif /* unsetenv */
6580
Guido van Rossumb6a47161997-09-15 22:54:34 +00006581#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006582PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006583"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006584Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006585
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006586static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006587posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006588{
6589 int code;
6590 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006591 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006592 return NULL;
6593 message = strerror(code);
6594 if (message == NULL) {
6595 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006596 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006597 return NULL;
6598 }
6599 return PyString_FromString(message);
6600}
6601#endif /* strerror */
6602
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006603
Guido van Rossumc9641791998-08-04 15:26:23 +00006604#ifdef HAVE_SYS_WAIT_H
6605
Fred Drake106c1a02002-04-23 15:58:02 +00006606#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006607PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006608"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006609Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006610
6611static PyObject *
6612posix_WCOREDUMP(PyObject *self, PyObject *args)
6613{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006614 WAIT_TYPE status;
6615 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006616
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006617 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006618 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006619
6620 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006621}
6622#endif /* WCOREDUMP */
6623
6624#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006625PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006626"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006627Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006628job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006629
6630static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006631posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006632{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006633 WAIT_TYPE status;
6634 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006635
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006636 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006637 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006638
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006639 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006640}
6641#endif /* WIFCONTINUED */
6642
Guido van Rossumc9641791998-08-04 15:26:23 +00006643#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006644PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006645"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006646Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006647
6648static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006649posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006650{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006651 WAIT_TYPE status;
6652 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006653
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006654 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006655 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006656
Fred Drake106c1a02002-04-23 15:58:02 +00006657 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006658}
6659#endif /* WIFSTOPPED */
6660
6661#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006662PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006663"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006664Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006665
6666static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006667posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006668{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006669 WAIT_TYPE status;
6670 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006671
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006672 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006673 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006674
Fred Drake106c1a02002-04-23 15:58:02 +00006675 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006676}
6677#endif /* WIFSIGNALED */
6678
6679#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006680PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006681"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006682Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006683system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006684
6685static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006686posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006687{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006688 WAIT_TYPE status;
6689 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006690
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006691 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006692 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006693
Fred Drake106c1a02002-04-23 15:58:02 +00006694 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006695}
6696#endif /* WIFEXITED */
6697
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006698#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006699PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006700"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006701Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006702
6703static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006704posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006705{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006706 WAIT_TYPE status;
6707 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006708
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006709 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006710 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006711
Guido van Rossumc9641791998-08-04 15:26:23 +00006712 return Py_BuildValue("i", WEXITSTATUS(status));
6713}
6714#endif /* WEXITSTATUS */
6715
6716#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006717PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006718"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006719Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006720value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006721
6722static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006723posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006724{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006725 WAIT_TYPE status;
6726 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006727
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006728 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006729 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006730
Guido van Rossumc9641791998-08-04 15:26:23 +00006731 return Py_BuildValue("i", WTERMSIG(status));
6732}
6733#endif /* WTERMSIG */
6734
6735#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006736PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006737"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006738Return the signal that stopped the process that provided\n\
6739the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006740
6741static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006742posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006743{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006744 WAIT_TYPE status;
6745 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006746
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006747 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006748 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006749
Guido van Rossumc9641791998-08-04 15:26:23 +00006750 return Py_BuildValue("i", WSTOPSIG(status));
6751}
6752#endif /* WSTOPSIG */
6753
6754#endif /* HAVE_SYS_WAIT_H */
6755
6756
Thomas Wouters477c8d52006-05-27 19:21:47 +00006757#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006758#ifdef _SCO_DS
6759/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6760 needed definitions in sys/statvfs.h */
6761#define _SVID3
6762#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006763#include <sys/statvfs.h>
6764
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006765static PyObject*
6766_pystatvfs_fromstructstatvfs(struct statvfs st) {
6767 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6768 if (v == NULL)
6769 return NULL;
6770
6771#if !defined(HAVE_LARGEFILE_SUPPORT)
6772 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6773 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6774 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6775 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6776 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6777 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6778 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6779 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6780 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6781 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6782#else
6783 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6784 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006785 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006786 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006787 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006788 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006789 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006790 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006791 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006792 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006793 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006794 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006795 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006796 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006797 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6798 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6799#endif
6800
6801 return v;
6802}
6803
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006804PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006805"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006806Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006807
6808static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006809posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006810{
6811 int fd, res;
6812 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006813
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006814 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006815 return NULL;
6816 Py_BEGIN_ALLOW_THREADS
6817 res = fstatvfs(fd, &st);
6818 Py_END_ALLOW_THREADS
6819 if (res != 0)
6820 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006821
6822 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006823}
Thomas Wouters477c8d52006-05-27 19:21:47 +00006824#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006825
6826
Thomas Wouters477c8d52006-05-27 19:21:47 +00006827#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006828#include <sys/statvfs.h>
6829
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006830PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006831"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006832Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006833
6834static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006835posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006836{
6837 char *path;
6838 int res;
6839 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006840 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006841 return NULL;
6842 Py_BEGIN_ALLOW_THREADS
6843 res = statvfs(path, &st);
6844 Py_END_ALLOW_THREADS
6845 if (res != 0)
6846 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006847
6848 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006849}
6850#endif /* HAVE_STATVFS */
6851
6852
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006853#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006854PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006855"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006856Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006857The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006858or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006859
6860static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006861posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006862{
6863 PyObject *result = NULL;
6864 char *dir = NULL;
6865 char *pfx = NULL;
6866 char *name;
6867
6868 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6869 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006870
6871 if (PyErr_Warn(PyExc_RuntimeWarning,
6872 "tempnam is a potential security risk to your program") < 0)
6873 return NULL;
6874
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006875#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006876 name = _tempnam(dir, pfx);
6877#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006878 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006879#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006880 if (name == NULL)
6881 return PyErr_NoMemory();
6882 result = PyString_FromString(name);
6883 free(name);
6884 return result;
6885}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006886#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006887
6888
6889#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006890PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006891"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006892Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006893
6894static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006895posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006896{
6897 FILE *fp;
6898
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006899 fp = tmpfile();
6900 if (fp == NULL)
6901 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006902 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006903}
6904#endif
6905
6906
6907#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006908PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006909"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006910Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006911
6912static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006913posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006914{
6915 char buffer[L_tmpnam];
6916 char *name;
6917
Skip Montanaro95618b52001-08-18 18:52:10 +00006918 if (PyErr_Warn(PyExc_RuntimeWarning,
6919 "tmpnam is a potential security risk to your program") < 0)
6920 return NULL;
6921
Greg Wardb48bc172000-03-01 21:51:56 +00006922#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006923 name = tmpnam_r(buffer);
6924#else
6925 name = tmpnam(buffer);
6926#endif
6927 if (name == NULL) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006928 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006929#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006930 "unexpected NULL from tmpnam_r"
6931#else
6932 "unexpected NULL from tmpnam"
6933#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006934 );
6935 PyErr_SetObject(PyExc_OSError, err);
6936 Py_XDECREF(err);
6937 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006938 }
6939 return PyString_FromString(buffer);
6940}
6941#endif
6942
6943
Fred Drakec9680921999-12-13 16:37:25 +00006944/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6945 * It maps strings representing configuration variable names to
6946 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006947 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006948 * rarely-used constants. There are three separate tables that use
6949 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006950 *
6951 * This code is always included, even if none of the interfaces that
6952 * need it are included. The #if hackery needed to avoid it would be
6953 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006954 */
6955struct constdef {
6956 char *name;
6957 long value;
6958};
6959
Fred Drake12c6e2d1999-12-14 21:25:03 +00006960static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006961conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6962 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006963{
6964 if (PyInt_Check(arg)) {
6965 *valuep = PyInt_AS_LONG(arg);
6966 return 1;
6967 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00006968 else {
Fred Drake12c6e2d1999-12-14 21:25:03 +00006969 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006970 size_t lo = 0;
6971 size_t mid;
6972 size_t hi = tablesize;
6973 int cmp;
Guido van Rossumbce56a62007-05-10 18:04:33 +00006974 const char *confname;
6975 Py_ssize_t namelen;
6976 if (PyObject_AsCharBuffer(arg, &confname, &namelen) < 0) {
6977 PyErr_SetString(PyExc_TypeError,
6978 "configuration names must be strings or integers");
6979 return 0;
6980 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00006981 while (lo < hi) {
6982 mid = (lo + hi) / 2;
6983 cmp = strcmp(confname, table[mid].name);
6984 if (cmp < 0)
6985 hi = mid;
6986 else if (cmp > 0)
6987 lo = mid + 1;
6988 else {
6989 *valuep = table[mid].value;
6990 return 1;
6991 }
6992 }
6993 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Guido van Rossumbce56a62007-05-10 18:04:33 +00006994 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006995 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00006996}
6997
6998
6999#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7000static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007001#ifdef _PC_ABI_AIO_XFER_MAX
7002 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
7003#endif
7004#ifdef _PC_ABI_ASYNC_IO
7005 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
7006#endif
Fred Drakec9680921999-12-13 16:37:25 +00007007#ifdef _PC_ASYNC_IO
7008 {"PC_ASYNC_IO", _PC_ASYNC_IO},
7009#endif
7010#ifdef _PC_CHOWN_RESTRICTED
7011 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
7012#endif
7013#ifdef _PC_FILESIZEBITS
7014 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
7015#endif
7016#ifdef _PC_LAST
7017 {"PC_LAST", _PC_LAST},
7018#endif
7019#ifdef _PC_LINK_MAX
7020 {"PC_LINK_MAX", _PC_LINK_MAX},
7021#endif
7022#ifdef _PC_MAX_CANON
7023 {"PC_MAX_CANON", _PC_MAX_CANON},
7024#endif
7025#ifdef _PC_MAX_INPUT
7026 {"PC_MAX_INPUT", _PC_MAX_INPUT},
7027#endif
7028#ifdef _PC_NAME_MAX
7029 {"PC_NAME_MAX", _PC_NAME_MAX},
7030#endif
7031#ifdef _PC_NO_TRUNC
7032 {"PC_NO_TRUNC", _PC_NO_TRUNC},
7033#endif
7034#ifdef _PC_PATH_MAX
7035 {"PC_PATH_MAX", _PC_PATH_MAX},
7036#endif
7037#ifdef _PC_PIPE_BUF
7038 {"PC_PIPE_BUF", _PC_PIPE_BUF},
7039#endif
7040#ifdef _PC_PRIO_IO
7041 {"PC_PRIO_IO", _PC_PRIO_IO},
7042#endif
7043#ifdef _PC_SOCK_MAXBUF
7044 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
7045#endif
7046#ifdef _PC_SYNC_IO
7047 {"PC_SYNC_IO", _PC_SYNC_IO},
7048#endif
7049#ifdef _PC_VDISABLE
7050 {"PC_VDISABLE", _PC_VDISABLE},
7051#endif
7052};
7053
Fred Drakec9680921999-12-13 16:37:25 +00007054static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007055conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007056{
7057 return conv_confname(arg, valuep, posix_constants_pathconf,
7058 sizeof(posix_constants_pathconf)
7059 / sizeof(struct constdef));
7060}
7061#endif
7062
7063#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007064PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007065"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007066Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007067If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007068
7069static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007070posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007071{
7072 PyObject *result = NULL;
7073 int name, fd;
7074
Fred Drake12c6e2d1999-12-14 21:25:03 +00007075 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7076 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00007077 long limit;
7078
7079 errno = 0;
7080 limit = fpathconf(fd, name);
7081 if (limit == -1 && errno != 0)
7082 posix_error();
7083 else
7084 result = PyInt_FromLong(limit);
7085 }
7086 return result;
7087}
7088#endif
7089
7090
7091#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007092PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007093"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007094Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007095If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007096
7097static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007098posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007099{
7100 PyObject *result = NULL;
7101 int name;
7102 char *path;
7103
7104 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7105 conv_path_confname, &name)) {
7106 long limit;
7107
7108 errno = 0;
7109 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007110 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00007111 if (errno == EINVAL)
7112 /* could be a path or name problem */
7113 posix_error();
7114 else
7115 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007116 }
Fred Drakec9680921999-12-13 16:37:25 +00007117 else
7118 result = PyInt_FromLong(limit);
7119 }
7120 return result;
7121}
7122#endif
7123
7124#ifdef HAVE_CONFSTR
7125static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007126#ifdef _CS_ARCHITECTURE
7127 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
7128#endif
7129#ifdef _CS_HOSTNAME
7130 {"CS_HOSTNAME", _CS_HOSTNAME},
7131#endif
7132#ifdef _CS_HW_PROVIDER
7133 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
7134#endif
7135#ifdef _CS_HW_SERIAL
7136 {"CS_HW_SERIAL", _CS_HW_SERIAL},
7137#endif
7138#ifdef _CS_INITTAB_NAME
7139 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
7140#endif
Fred Drakec9680921999-12-13 16:37:25 +00007141#ifdef _CS_LFS64_CFLAGS
7142 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
7143#endif
7144#ifdef _CS_LFS64_LDFLAGS
7145 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
7146#endif
7147#ifdef _CS_LFS64_LIBS
7148 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
7149#endif
7150#ifdef _CS_LFS64_LINTFLAGS
7151 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
7152#endif
7153#ifdef _CS_LFS_CFLAGS
7154 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
7155#endif
7156#ifdef _CS_LFS_LDFLAGS
7157 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
7158#endif
7159#ifdef _CS_LFS_LIBS
7160 {"CS_LFS_LIBS", _CS_LFS_LIBS},
7161#endif
7162#ifdef _CS_LFS_LINTFLAGS
7163 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
7164#endif
Fred Draked86ed291999-12-15 15:34:33 +00007165#ifdef _CS_MACHINE
7166 {"CS_MACHINE", _CS_MACHINE},
7167#endif
Fred Drakec9680921999-12-13 16:37:25 +00007168#ifdef _CS_PATH
7169 {"CS_PATH", _CS_PATH},
7170#endif
Fred Draked86ed291999-12-15 15:34:33 +00007171#ifdef _CS_RELEASE
7172 {"CS_RELEASE", _CS_RELEASE},
7173#endif
7174#ifdef _CS_SRPC_DOMAIN
7175 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
7176#endif
7177#ifdef _CS_SYSNAME
7178 {"CS_SYSNAME", _CS_SYSNAME},
7179#endif
7180#ifdef _CS_VERSION
7181 {"CS_VERSION", _CS_VERSION},
7182#endif
Fred Drakec9680921999-12-13 16:37:25 +00007183#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
7184 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
7185#endif
7186#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
7187 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
7188#endif
7189#ifdef _CS_XBS5_ILP32_OFF32_LIBS
7190 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
7191#endif
7192#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
7193 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
7194#endif
7195#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
7196 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
7197#endif
7198#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
7199 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
7200#endif
7201#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
7202 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
7203#endif
7204#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
7205 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
7206#endif
7207#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7208 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
7209#endif
7210#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7211 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7212#endif
7213#ifdef _CS_XBS5_LP64_OFF64_LIBS
7214 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7215#endif
7216#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7217 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7218#endif
7219#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7220 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7221#endif
7222#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7223 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7224#endif
7225#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7226 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7227#endif
7228#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7229 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7230#endif
Fred Draked86ed291999-12-15 15:34:33 +00007231#ifdef _MIPS_CS_AVAIL_PROCESSORS
7232 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7233#endif
7234#ifdef _MIPS_CS_BASE
7235 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7236#endif
7237#ifdef _MIPS_CS_HOSTID
7238 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7239#endif
7240#ifdef _MIPS_CS_HW_NAME
7241 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7242#endif
7243#ifdef _MIPS_CS_NUM_PROCESSORS
7244 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7245#endif
7246#ifdef _MIPS_CS_OSREL_MAJ
7247 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7248#endif
7249#ifdef _MIPS_CS_OSREL_MIN
7250 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7251#endif
7252#ifdef _MIPS_CS_OSREL_PATCH
7253 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7254#endif
7255#ifdef _MIPS_CS_OS_NAME
7256 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7257#endif
7258#ifdef _MIPS_CS_OS_PROVIDER
7259 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7260#endif
7261#ifdef _MIPS_CS_PROCESSORS
7262 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7263#endif
7264#ifdef _MIPS_CS_SERIAL
7265 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7266#endif
7267#ifdef _MIPS_CS_VENDOR
7268 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7269#endif
Fred Drakec9680921999-12-13 16:37:25 +00007270};
7271
7272static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007273conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007274{
7275 return conv_confname(arg, valuep, posix_constants_confstr,
7276 sizeof(posix_constants_confstr)
7277 / sizeof(struct constdef));
7278}
7279
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007280PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007281"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007282Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007283
7284static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007285posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007286{
7287 PyObject *result = NULL;
7288 int name;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007289 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007290
7291 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007292 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007293
Fred Drakec9680921999-12-13 16:37:25 +00007294 errno = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007295 len = confstr(name, buffer, sizeof(buffer));
7296 if (len == 0) {
7297 if (errno) {
7298 posix_error();
7299 }
7300 else {
7301 result = Py_None;
7302 Py_INCREF(Py_None);
7303 }
Fred Drakec9680921999-12-13 16:37:25 +00007304 }
7305 else {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007306 if ((unsigned int)len >= sizeof(buffer)) {
7307 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007308 if (result != NULL)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007309 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00007310 }
7311 else
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007312 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007313 }
7314 }
7315 return result;
7316}
7317#endif
7318
7319
7320#ifdef HAVE_SYSCONF
7321static struct constdef posix_constants_sysconf[] = {
7322#ifdef _SC_2_CHAR_TERM
7323 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7324#endif
7325#ifdef _SC_2_C_BIND
7326 {"SC_2_C_BIND", _SC_2_C_BIND},
7327#endif
7328#ifdef _SC_2_C_DEV
7329 {"SC_2_C_DEV", _SC_2_C_DEV},
7330#endif
7331#ifdef _SC_2_C_VERSION
7332 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7333#endif
7334#ifdef _SC_2_FORT_DEV
7335 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7336#endif
7337#ifdef _SC_2_FORT_RUN
7338 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7339#endif
7340#ifdef _SC_2_LOCALEDEF
7341 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7342#endif
7343#ifdef _SC_2_SW_DEV
7344 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7345#endif
7346#ifdef _SC_2_UPE
7347 {"SC_2_UPE", _SC_2_UPE},
7348#endif
7349#ifdef _SC_2_VERSION
7350 {"SC_2_VERSION", _SC_2_VERSION},
7351#endif
Fred Draked86ed291999-12-15 15:34:33 +00007352#ifdef _SC_ABI_ASYNCHRONOUS_IO
7353 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7354#endif
7355#ifdef _SC_ACL
7356 {"SC_ACL", _SC_ACL},
7357#endif
Fred Drakec9680921999-12-13 16:37:25 +00007358#ifdef _SC_AIO_LISTIO_MAX
7359 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7360#endif
Fred Drakec9680921999-12-13 16:37:25 +00007361#ifdef _SC_AIO_MAX
7362 {"SC_AIO_MAX", _SC_AIO_MAX},
7363#endif
7364#ifdef _SC_AIO_PRIO_DELTA_MAX
7365 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7366#endif
7367#ifdef _SC_ARG_MAX
7368 {"SC_ARG_MAX", _SC_ARG_MAX},
7369#endif
7370#ifdef _SC_ASYNCHRONOUS_IO
7371 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7372#endif
7373#ifdef _SC_ATEXIT_MAX
7374 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7375#endif
Fred Draked86ed291999-12-15 15:34:33 +00007376#ifdef _SC_AUDIT
7377 {"SC_AUDIT", _SC_AUDIT},
7378#endif
Fred Drakec9680921999-12-13 16:37:25 +00007379#ifdef _SC_AVPHYS_PAGES
7380 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7381#endif
7382#ifdef _SC_BC_BASE_MAX
7383 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7384#endif
7385#ifdef _SC_BC_DIM_MAX
7386 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7387#endif
7388#ifdef _SC_BC_SCALE_MAX
7389 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7390#endif
7391#ifdef _SC_BC_STRING_MAX
7392 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7393#endif
Fred Draked86ed291999-12-15 15:34:33 +00007394#ifdef _SC_CAP
7395 {"SC_CAP", _SC_CAP},
7396#endif
Fred Drakec9680921999-12-13 16:37:25 +00007397#ifdef _SC_CHARCLASS_NAME_MAX
7398 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7399#endif
7400#ifdef _SC_CHAR_BIT
7401 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7402#endif
7403#ifdef _SC_CHAR_MAX
7404 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7405#endif
7406#ifdef _SC_CHAR_MIN
7407 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7408#endif
7409#ifdef _SC_CHILD_MAX
7410 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7411#endif
7412#ifdef _SC_CLK_TCK
7413 {"SC_CLK_TCK", _SC_CLK_TCK},
7414#endif
7415#ifdef _SC_COHER_BLKSZ
7416 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7417#endif
7418#ifdef _SC_COLL_WEIGHTS_MAX
7419 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7420#endif
7421#ifdef _SC_DCACHE_ASSOC
7422 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7423#endif
7424#ifdef _SC_DCACHE_BLKSZ
7425 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7426#endif
7427#ifdef _SC_DCACHE_LINESZ
7428 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7429#endif
7430#ifdef _SC_DCACHE_SZ
7431 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7432#endif
7433#ifdef _SC_DCACHE_TBLKSZ
7434 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7435#endif
7436#ifdef _SC_DELAYTIMER_MAX
7437 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7438#endif
7439#ifdef _SC_EQUIV_CLASS_MAX
7440 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7441#endif
7442#ifdef _SC_EXPR_NEST_MAX
7443 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7444#endif
7445#ifdef _SC_FSYNC
7446 {"SC_FSYNC", _SC_FSYNC},
7447#endif
7448#ifdef _SC_GETGR_R_SIZE_MAX
7449 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7450#endif
7451#ifdef _SC_GETPW_R_SIZE_MAX
7452 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7453#endif
7454#ifdef _SC_ICACHE_ASSOC
7455 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7456#endif
7457#ifdef _SC_ICACHE_BLKSZ
7458 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7459#endif
7460#ifdef _SC_ICACHE_LINESZ
7461 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7462#endif
7463#ifdef _SC_ICACHE_SZ
7464 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7465#endif
Fred Draked86ed291999-12-15 15:34:33 +00007466#ifdef _SC_INF
7467 {"SC_INF", _SC_INF},
7468#endif
Fred Drakec9680921999-12-13 16:37:25 +00007469#ifdef _SC_INT_MAX
7470 {"SC_INT_MAX", _SC_INT_MAX},
7471#endif
7472#ifdef _SC_INT_MIN
7473 {"SC_INT_MIN", _SC_INT_MIN},
7474#endif
7475#ifdef _SC_IOV_MAX
7476 {"SC_IOV_MAX", _SC_IOV_MAX},
7477#endif
Fred Draked86ed291999-12-15 15:34:33 +00007478#ifdef _SC_IP_SECOPTS
7479 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7480#endif
Fred Drakec9680921999-12-13 16:37:25 +00007481#ifdef _SC_JOB_CONTROL
7482 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7483#endif
Fred Draked86ed291999-12-15 15:34:33 +00007484#ifdef _SC_KERN_POINTERS
7485 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7486#endif
7487#ifdef _SC_KERN_SIM
7488 {"SC_KERN_SIM", _SC_KERN_SIM},
7489#endif
Fred Drakec9680921999-12-13 16:37:25 +00007490#ifdef _SC_LINE_MAX
7491 {"SC_LINE_MAX", _SC_LINE_MAX},
7492#endif
7493#ifdef _SC_LOGIN_NAME_MAX
7494 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7495#endif
7496#ifdef _SC_LOGNAME_MAX
7497 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7498#endif
7499#ifdef _SC_LONG_BIT
7500 {"SC_LONG_BIT", _SC_LONG_BIT},
7501#endif
Fred Draked86ed291999-12-15 15:34:33 +00007502#ifdef _SC_MAC
7503 {"SC_MAC", _SC_MAC},
7504#endif
Fred Drakec9680921999-12-13 16:37:25 +00007505#ifdef _SC_MAPPED_FILES
7506 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7507#endif
7508#ifdef _SC_MAXPID
7509 {"SC_MAXPID", _SC_MAXPID},
7510#endif
7511#ifdef _SC_MB_LEN_MAX
7512 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7513#endif
7514#ifdef _SC_MEMLOCK
7515 {"SC_MEMLOCK", _SC_MEMLOCK},
7516#endif
7517#ifdef _SC_MEMLOCK_RANGE
7518 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7519#endif
7520#ifdef _SC_MEMORY_PROTECTION
7521 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7522#endif
7523#ifdef _SC_MESSAGE_PASSING
7524 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7525#endif
Fred Draked86ed291999-12-15 15:34:33 +00007526#ifdef _SC_MMAP_FIXED_ALIGNMENT
7527 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7528#endif
Fred Drakec9680921999-12-13 16:37:25 +00007529#ifdef _SC_MQ_OPEN_MAX
7530 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7531#endif
7532#ifdef _SC_MQ_PRIO_MAX
7533 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7534#endif
Fred Draked86ed291999-12-15 15:34:33 +00007535#ifdef _SC_NACLS_MAX
7536 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7537#endif
Fred Drakec9680921999-12-13 16:37:25 +00007538#ifdef _SC_NGROUPS_MAX
7539 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7540#endif
7541#ifdef _SC_NL_ARGMAX
7542 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7543#endif
7544#ifdef _SC_NL_LANGMAX
7545 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7546#endif
7547#ifdef _SC_NL_MSGMAX
7548 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7549#endif
7550#ifdef _SC_NL_NMAX
7551 {"SC_NL_NMAX", _SC_NL_NMAX},
7552#endif
7553#ifdef _SC_NL_SETMAX
7554 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7555#endif
7556#ifdef _SC_NL_TEXTMAX
7557 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7558#endif
7559#ifdef _SC_NPROCESSORS_CONF
7560 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7561#endif
7562#ifdef _SC_NPROCESSORS_ONLN
7563 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7564#endif
Fred Draked86ed291999-12-15 15:34:33 +00007565#ifdef _SC_NPROC_CONF
7566 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7567#endif
7568#ifdef _SC_NPROC_ONLN
7569 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7570#endif
Fred Drakec9680921999-12-13 16:37:25 +00007571#ifdef _SC_NZERO
7572 {"SC_NZERO", _SC_NZERO},
7573#endif
7574#ifdef _SC_OPEN_MAX
7575 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7576#endif
7577#ifdef _SC_PAGESIZE
7578 {"SC_PAGESIZE", _SC_PAGESIZE},
7579#endif
7580#ifdef _SC_PAGE_SIZE
7581 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7582#endif
7583#ifdef _SC_PASS_MAX
7584 {"SC_PASS_MAX", _SC_PASS_MAX},
7585#endif
7586#ifdef _SC_PHYS_PAGES
7587 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7588#endif
7589#ifdef _SC_PII
7590 {"SC_PII", _SC_PII},
7591#endif
7592#ifdef _SC_PII_INTERNET
7593 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7594#endif
7595#ifdef _SC_PII_INTERNET_DGRAM
7596 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7597#endif
7598#ifdef _SC_PII_INTERNET_STREAM
7599 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7600#endif
7601#ifdef _SC_PII_OSI
7602 {"SC_PII_OSI", _SC_PII_OSI},
7603#endif
7604#ifdef _SC_PII_OSI_CLTS
7605 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7606#endif
7607#ifdef _SC_PII_OSI_COTS
7608 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7609#endif
7610#ifdef _SC_PII_OSI_M
7611 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7612#endif
7613#ifdef _SC_PII_SOCKET
7614 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7615#endif
7616#ifdef _SC_PII_XTI
7617 {"SC_PII_XTI", _SC_PII_XTI},
7618#endif
7619#ifdef _SC_POLL
7620 {"SC_POLL", _SC_POLL},
7621#endif
7622#ifdef _SC_PRIORITIZED_IO
7623 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7624#endif
7625#ifdef _SC_PRIORITY_SCHEDULING
7626 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7627#endif
7628#ifdef _SC_REALTIME_SIGNALS
7629 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7630#endif
7631#ifdef _SC_RE_DUP_MAX
7632 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7633#endif
7634#ifdef _SC_RTSIG_MAX
7635 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7636#endif
7637#ifdef _SC_SAVED_IDS
7638 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7639#endif
7640#ifdef _SC_SCHAR_MAX
7641 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7642#endif
7643#ifdef _SC_SCHAR_MIN
7644 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7645#endif
7646#ifdef _SC_SELECT
7647 {"SC_SELECT", _SC_SELECT},
7648#endif
7649#ifdef _SC_SEMAPHORES
7650 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7651#endif
7652#ifdef _SC_SEM_NSEMS_MAX
7653 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7654#endif
7655#ifdef _SC_SEM_VALUE_MAX
7656 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7657#endif
7658#ifdef _SC_SHARED_MEMORY_OBJECTS
7659 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7660#endif
7661#ifdef _SC_SHRT_MAX
7662 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7663#endif
7664#ifdef _SC_SHRT_MIN
7665 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7666#endif
7667#ifdef _SC_SIGQUEUE_MAX
7668 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7669#endif
7670#ifdef _SC_SIGRT_MAX
7671 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7672#endif
7673#ifdef _SC_SIGRT_MIN
7674 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7675#endif
Fred Draked86ed291999-12-15 15:34:33 +00007676#ifdef _SC_SOFTPOWER
7677 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7678#endif
Fred Drakec9680921999-12-13 16:37:25 +00007679#ifdef _SC_SPLIT_CACHE
7680 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7681#endif
7682#ifdef _SC_SSIZE_MAX
7683 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7684#endif
7685#ifdef _SC_STACK_PROT
7686 {"SC_STACK_PROT", _SC_STACK_PROT},
7687#endif
7688#ifdef _SC_STREAM_MAX
7689 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7690#endif
7691#ifdef _SC_SYNCHRONIZED_IO
7692 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7693#endif
7694#ifdef _SC_THREADS
7695 {"SC_THREADS", _SC_THREADS},
7696#endif
7697#ifdef _SC_THREAD_ATTR_STACKADDR
7698 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7699#endif
7700#ifdef _SC_THREAD_ATTR_STACKSIZE
7701 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7702#endif
7703#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7704 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7705#endif
7706#ifdef _SC_THREAD_KEYS_MAX
7707 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7708#endif
7709#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7710 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7711#endif
7712#ifdef _SC_THREAD_PRIO_INHERIT
7713 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7714#endif
7715#ifdef _SC_THREAD_PRIO_PROTECT
7716 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7717#endif
7718#ifdef _SC_THREAD_PROCESS_SHARED
7719 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7720#endif
7721#ifdef _SC_THREAD_SAFE_FUNCTIONS
7722 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7723#endif
7724#ifdef _SC_THREAD_STACK_MIN
7725 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7726#endif
7727#ifdef _SC_THREAD_THREADS_MAX
7728 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7729#endif
7730#ifdef _SC_TIMERS
7731 {"SC_TIMERS", _SC_TIMERS},
7732#endif
7733#ifdef _SC_TIMER_MAX
7734 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7735#endif
7736#ifdef _SC_TTY_NAME_MAX
7737 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7738#endif
7739#ifdef _SC_TZNAME_MAX
7740 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7741#endif
7742#ifdef _SC_T_IOV_MAX
7743 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7744#endif
7745#ifdef _SC_UCHAR_MAX
7746 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7747#endif
7748#ifdef _SC_UINT_MAX
7749 {"SC_UINT_MAX", _SC_UINT_MAX},
7750#endif
7751#ifdef _SC_UIO_MAXIOV
7752 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7753#endif
7754#ifdef _SC_ULONG_MAX
7755 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7756#endif
7757#ifdef _SC_USHRT_MAX
7758 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7759#endif
7760#ifdef _SC_VERSION
7761 {"SC_VERSION", _SC_VERSION},
7762#endif
7763#ifdef _SC_WORD_BIT
7764 {"SC_WORD_BIT", _SC_WORD_BIT},
7765#endif
7766#ifdef _SC_XBS5_ILP32_OFF32
7767 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7768#endif
7769#ifdef _SC_XBS5_ILP32_OFFBIG
7770 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7771#endif
7772#ifdef _SC_XBS5_LP64_OFF64
7773 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7774#endif
7775#ifdef _SC_XBS5_LPBIG_OFFBIG
7776 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7777#endif
7778#ifdef _SC_XOPEN_CRYPT
7779 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7780#endif
7781#ifdef _SC_XOPEN_ENH_I18N
7782 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7783#endif
7784#ifdef _SC_XOPEN_LEGACY
7785 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7786#endif
7787#ifdef _SC_XOPEN_REALTIME
7788 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7789#endif
7790#ifdef _SC_XOPEN_REALTIME_THREADS
7791 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7792#endif
7793#ifdef _SC_XOPEN_SHM
7794 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7795#endif
7796#ifdef _SC_XOPEN_UNIX
7797 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7798#endif
7799#ifdef _SC_XOPEN_VERSION
7800 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7801#endif
7802#ifdef _SC_XOPEN_XCU_VERSION
7803 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7804#endif
7805#ifdef _SC_XOPEN_XPG2
7806 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7807#endif
7808#ifdef _SC_XOPEN_XPG3
7809 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7810#endif
7811#ifdef _SC_XOPEN_XPG4
7812 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7813#endif
7814};
7815
7816static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007817conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007818{
7819 return conv_confname(arg, valuep, posix_constants_sysconf,
7820 sizeof(posix_constants_sysconf)
7821 / sizeof(struct constdef));
7822}
7823
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007824PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007825"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007826Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007827
7828static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007829posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007830{
7831 PyObject *result = NULL;
7832 int name;
7833
7834 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7835 int value;
7836
7837 errno = 0;
7838 value = sysconf(name);
7839 if (value == -1 && errno != 0)
7840 posix_error();
7841 else
7842 result = PyInt_FromLong(value);
7843 }
7844 return result;
7845}
7846#endif
7847
7848
Fred Drakebec628d1999-12-15 18:31:10 +00007849/* This code is used to ensure that the tables of configuration value names
7850 * are in sorted order as required by conv_confname(), and also to build the
7851 * the exported dictionaries that are used to publish information about the
7852 * names available on the host platform.
7853 *
7854 * Sorting the table at runtime ensures that the table is properly ordered
7855 * when used, even for platforms we're not able to test on. It also makes
7856 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007857 */
Fred Drakebec628d1999-12-15 18:31:10 +00007858
7859static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007860cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007861{
7862 const struct constdef *c1 =
7863 (const struct constdef *) v1;
7864 const struct constdef *c2 =
7865 (const struct constdef *) v2;
7866
7867 return strcmp(c1->name, c2->name);
7868}
7869
7870static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007871setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007872 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007873{
Fred Drakebec628d1999-12-15 18:31:10 +00007874 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007875 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007876
7877 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7878 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007879 if (d == NULL)
7880 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007881
Barry Warsaw3155db32000-04-13 15:20:40 +00007882 for (i=0; i < tablesize; ++i) {
7883 PyObject *o = PyInt_FromLong(table[i].value);
7884 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7885 Py_XDECREF(o);
7886 Py_DECREF(d);
7887 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007888 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007889 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007890 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007891 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007892}
7893
Fred Drakebec628d1999-12-15 18:31:10 +00007894/* Return -1 on failure, 0 on success. */
7895static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007896setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007897{
7898#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007899 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007900 sizeof(posix_constants_pathconf)
7901 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007902 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007903 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007904#endif
7905#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007906 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007907 sizeof(posix_constants_confstr)
7908 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007909 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007910 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007911#endif
7912#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007913 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007914 sizeof(posix_constants_sysconf)
7915 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007916 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007917 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007918#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007919 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007920}
Fred Draked86ed291999-12-15 15:34:33 +00007921
7922
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007923PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007924"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007925Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007926in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007927
7928static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007929posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007930{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007931 abort();
7932 /*NOTREACHED*/
7933 Py_FatalError("abort() called from Python code didn't abort!");
7934 return NULL;
7935}
Fred Drakebec628d1999-12-15 18:31:10 +00007936
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007937#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007938PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007939"startfile(filepath [, operation]) - Start a file with its associated\n\
7940application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007941\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007942When \"operation\" is not specified or \"open\", this acts like\n\
7943double-clicking the file in Explorer, or giving the file name as an\n\
7944argument to the DOS \"start\" command: the file is opened with whatever\n\
7945application (if any) its extension is associated.\n\
7946When another \"operation\" is given, it specifies what should be done with\n\
7947the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007948\n\
7949startfile returns as soon as the associated application is launched.\n\
7950There is no option to wait for the application to close, and no way\n\
7951to retrieve the application's exit status.\n\
7952\n\
7953The filepath is relative to the current directory. If you want to use\n\
7954an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007955the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007956
7957static PyObject *
7958win32_startfile(PyObject *self, PyObject *args)
7959{
7960 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00007961 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007962 HINSTANCE rc;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007963#ifdef Py_WIN_WIDE_FILENAMES
7964 if (unicode_file_names()) {
7965 PyObject *unipath, *woperation = NULL;
7966 if (!PyArg_ParseTuple(args, "U|s:startfile",
7967 &unipath, &operation)) {
7968 PyErr_Clear();
7969 goto normal;
7970 }
7971
7972
7973 if (operation) {
7974 woperation = PyUnicode_DecodeASCII(operation,
7975 strlen(operation), NULL);
7976 if (!woperation) {
7977 PyErr_Clear();
7978 operation = NULL;
7979 goto normal;
7980 }
7981 }
7982
7983 Py_BEGIN_ALLOW_THREADS
7984 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
7985 PyUnicode_AS_UNICODE(unipath),
7986 NULL, NULL, SW_SHOWNORMAL);
7987 Py_END_ALLOW_THREADS
7988
7989 Py_XDECREF(woperation);
7990 if (rc <= (HINSTANCE)32) {
7991 PyObject *errval = win32_error_unicode("startfile",
7992 PyUnicode_AS_UNICODE(unipath));
7993 return errval;
7994 }
7995 Py_INCREF(Py_None);
7996 return Py_None;
7997 }
7998#endif
7999
8000normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00008001 if (!PyArg_ParseTuple(args, "et|s:startfile",
8002 Py_FileSystemDefaultEncoding, &filepath,
8003 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00008004 return NULL;
8005 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00008006 rc = ShellExecute((HWND)0, operation, filepath,
8007 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008008 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00008009 if (rc <= (HINSTANCE)32) {
8010 PyObject *errval = win32_error("startfile", filepath);
8011 PyMem_Free(filepath);
8012 return errval;
8013 }
8014 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008015 Py_INCREF(Py_None);
8016 return Py_None;
8017}
8018#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008019
Martin v. Löwis438b5342002-12-27 10:16:42 +00008020#ifdef HAVE_GETLOADAVG
8021PyDoc_STRVAR(posix_getloadavg__doc__,
8022"getloadavg() -> (float, float, float)\n\n\
8023Return the number of processes in the system run queue averaged over\n\
8024the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8025was unobtainable");
8026
8027static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008028posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008029{
8030 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008031 if (getloadavg(loadavg, 3)!=3) {
8032 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8033 return NULL;
8034 } else
8035 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
8036}
8037#endif
8038
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008039#ifdef MS_WINDOWS
8040
8041PyDoc_STRVAR(win32_urandom__doc__,
8042"urandom(n) -> str\n\n\
8043Return a string of n random bytes suitable for cryptographic use.");
8044
8045typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8046 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8047 DWORD dwFlags );
8048typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8049 BYTE *pbBuffer );
8050
8051static CRYPTGENRANDOM pCryptGenRandom = NULL;
8052static HCRYPTPROV hCryptProv = 0;
8053
Tim Peters4ad82172004-08-30 17:02:04 +00008054static PyObject*
8055win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008056{
Tim Petersd3115382004-08-30 17:36:46 +00008057 int howMany;
8058 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008059
Tim Peters4ad82172004-08-30 17:02:04 +00008060 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00008061 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00008062 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00008063 if (howMany < 0)
8064 return PyErr_Format(PyExc_ValueError,
8065 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008066
Tim Peters4ad82172004-08-30 17:02:04 +00008067 if (hCryptProv == 0) {
8068 HINSTANCE hAdvAPI32 = NULL;
8069 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008070
Tim Peters4ad82172004-08-30 17:02:04 +00008071 /* Obtain handle to the DLL containing CryptoAPI
8072 This should not fail */
8073 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8074 if(hAdvAPI32 == NULL)
8075 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008076
Tim Peters4ad82172004-08-30 17:02:04 +00008077 /* Obtain pointers to the CryptoAPI functions
8078 This will fail on some early versions of Win95 */
8079 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8080 hAdvAPI32,
8081 "CryptAcquireContextA");
8082 if (pCryptAcquireContext == NULL)
8083 return PyErr_Format(PyExc_NotImplementedError,
8084 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008085
Tim Peters4ad82172004-08-30 17:02:04 +00008086 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8087 hAdvAPI32, "CryptGenRandom");
Thomas Wouters89f507f2006-12-13 04:49:30 +00008088 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00008089 return PyErr_Format(PyExc_NotImplementedError,
8090 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008091
Tim Peters4ad82172004-08-30 17:02:04 +00008092 /* Acquire context */
8093 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8094 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8095 return win32_error("CryptAcquireContext", NULL);
8096 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008097
Tim Peters4ad82172004-08-30 17:02:04 +00008098 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00008099 result = PyString_FromStringAndSize(NULL, howMany);
8100 if (result != NULL) {
8101 /* Get random data */
8102 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
8103 PyString_AS_STRING(result))) {
8104 Py_DECREF(result);
8105 return win32_error("CryptGenRandom", NULL);
8106 }
Tim Peters4ad82172004-08-30 17:02:04 +00008107 }
Tim Petersd3115382004-08-30 17:36:46 +00008108 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008109}
8110#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008111
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008112#ifdef __VMS
8113/* Use openssl random routine */
8114#include <openssl/rand.h>
8115PyDoc_STRVAR(vms_urandom__doc__,
8116"urandom(n) -> str\n\n\
8117Return a string of n random bytes suitable for cryptographic use.");
8118
8119static PyObject*
8120vms_urandom(PyObject *self, PyObject *args)
8121{
8122 int howMany;
8123 PyObject* result;
8124
8125 /* Read arguments */
8126 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8127 return NULL;
8128 if (howMany < 0)
8129 return PyErr_Format(PyExc_ValueError,
8130 "negative argument not allowed");
8131
8132 /* Allocate bytes */
8133 result = PyString_FromStringAndSize(NULL, howMany);
8134 if (result != NULL) {
8135 /* Get random data */
8136 if (RAND_pseudo_bytes((unsigned char*)
8137 PyString_AS_STRING(result),
8138 howMany) < 0) {
8139 Py_DECREF(result);
8140 return PyErr_Format(PyExc_ValueError,
8141 "RAND_pseudo_bytes");
8142 }
8143 }
8144 return result;
8145}
8146#endif
8147
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008148static PyMethodDef posix_methods[] = {
8149 {"access", posix_access, METH_VARARGS, posix_access__doc__},
8150#ifdef HAVE_TTYNAME
8151 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
8152#endif
8153 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00008154#ifdef HAVE_CHFLAGS
8155 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
8156#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008157 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008158#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008159 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008160#endif /* HAVE_CHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00008161#ifdef HAVE_LCHFLAGS
8162 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
8163#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008164#ifdef HAVE_LCHOWN
8165 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
8166#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008167#ifdef HAVE_CHROOT
8168 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
8169#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008170#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00008171 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008172#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008173#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00008174 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Neal Norwitze241ce82003-02-17 18:17:05 +00008175 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008176#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008177#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008178 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008179#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008180 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8181 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8182 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008183#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008184 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008185#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008186#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008187 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008188#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008189 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8190 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8191 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008192 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008193#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008194 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008195#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008196#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008197 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008198#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008199 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008200#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00008201 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008202#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008203 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8204 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8205 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008206#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00008207 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008208#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008209 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008210#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008211 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8212 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008213#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008214#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008215 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8216 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008217#if defined(PYOS_OS2)
8218 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8219 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8220#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008221#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008222#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00008223 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008224#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008225#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00008226 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008227#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008228#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00008229 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008230#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008231#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00008232 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008233#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008234#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008235 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008236#endif /* HAVE_GETEGID */
8237#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008238 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008239#endif /* HAVE_GETEUID */
8240#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008241 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008242#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008243#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00008244 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008245#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008246 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008247#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008248 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008249#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008250#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00008251 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008252#endif /* HAVE_GETPPID */
8253#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008254 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008255#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008256#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00008257 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008258#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008259#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008260 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008261#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008262#ifdef HAVE_KILLPG
8263 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8264#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008265#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008266 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008267#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008268#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008269 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008270#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008271 {"popen2", win32_popen2, METH_VARARGS},
8272 {"popen3", win32_popen3, METH_VARARGS},
8273 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00008274 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008275#else
8276#if defined(PYOS_OS2) && defined(PYCC_GCC)
8277 {"popen2", os2emx_popen2, METH_VARARGS},
8278 {"popen3", os2emx_popen3, METH_VARARGS},
8279 {"popen4", os2emx_popen4, METH_VARARGS},
8280#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008281#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008282#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008283#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008284 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008285#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008286#ifdef HAVE_SETEUID
8287 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8288#endif /* HAVE_SETEUID */
8289#ifdef HAVE_SETEGID
8290 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8291#endif /* HAVE_SETEGID */
8292#ifdef HAVE_SETREUID
8293 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8294#endif /* HAVE_SETREUID */
8295#ifdef HAVE_SETREGID
8296 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8297#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008298#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008299 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008300#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008301#ifdef HAVE_SETGROUPS
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00008302 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008303#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008304#ifdef HAVE_GETPGID
8305 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8306#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008307#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008308 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008309#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008310#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00008311 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008312#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008313#ifdef HAVE_WAIT3
8314 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8315#endif /* HAVE_WAIT3 */
8316#ifdef HAVE_WAIT4
8317 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8318#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008319#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008320 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008321#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008322#ifdef HAVE_GETSID
8323 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8324#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008325#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00008326 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008327#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008328#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008329 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008330#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008331#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008332 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008333#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008334#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008335 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008336#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008337 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8338 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8339 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8340 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8341 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8342 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8343 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8344 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8345 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00008346 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008347#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00008348 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008349#endif
8350#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008351 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008352#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008353#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008354 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8355#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008356#ifdef HAVE_DEVICE_MACROS
8357 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8358 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8359 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8360#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008361#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008362 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008363#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008364#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008365 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008366#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008367#ifdef HAVE_UNSETENV
8368 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8369#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00008370#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008371 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00008372#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00008373#ifdef HAVE_FCHDIR
8374 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8375#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008376#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008377 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008378#endif
8379#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008380 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008381#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008382#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008383#ifdef WCOREDUMP
8384 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8385#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008386#ifdef WIFCONTINUED
8387 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8388#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008389#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008390 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008391#endif /* WIFSTOPPED */
8392#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008393 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008394#endif /* WIFSIGNALED */
8395#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008396 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008397#endif /* WIFEXITED */
8398#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008399 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008400#endif /* WEXITSTATUS */
8401#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008402 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008403#endif /* WTERMSIG */
8404#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008405 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008406#endif /* WSTOPSIG */
8407#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008408#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008409 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008410#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00008411#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008412 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008413#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008414#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00008415 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008416#endif
8417#ifdef HAVE_TEMPNAM
8418 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8419#endif
8420#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00008421 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008422#endif
Fred Drakec9680921999-12-13 16:37:25 +00008423#ifdef HAVE_CONFSTR
8424 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8425#endif
8426#ifdef HAVE_SYSCONF
8427 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8428#endif
8429#ifdef HAVE_FPATHCONF
8430 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8431#endif
8432#ifdef HAVE_PATHCONF
8433 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8434#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008435 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008436#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00008437 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8438#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008439#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00008440 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008441#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008442 #ifdef MS_WINDOWS
8443 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8444 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008445 #ifdef __VMS
8446 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8447 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008448 {NULL, NULL} /* Sentinel */
8449};
8450
8451
Barry Warsaw4a342091996-12-19 23:50:02 +00008452static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008453ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008454{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008455 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008456}
8457
Guido van Rossumd48f2521997-12-05 22:19:34 +00008458#if defined(PYOS_OS2)
8459/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008460static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008461{
8462 APIRET rc;
8463 ULONG values[QSV_MAX+1];
8464 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008465 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008466
8467 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008468 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008469 Py_END_ALLOW_THREADS
8470
8471 if (rc != NO_ERROR) {
8472 os2_error(rc);
8473 return -1;
8474 }
8475
Fred Drake4d1e64b2002-04-15 19:40:07 +00008476 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8477 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8478 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8479 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8480 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8481 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8482 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008483
8484 switch (values[QSV_VERSION_MINOR]) {
8485 case 0: ver = "2.00"; break;
8486 case 10: ver = "2.10"; break;
8487 case 11: ver = "2.11"; break;
8488 case 30: ver = "3.00"; break;
8489 case 40: ver = "4.00"; break;
8490 case 50: ver = "5.00"; break;
8491 default:
Tim Peters885d4572001-11-28 20:27:42 +00008492 PyOS_snprintf(tmp, sizeof(tmp),
8493 "%d-%d", values[QSV_VERSION_MAJOR],
8494 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008495 ver = &tmp[0];
8496 }
8497
8498 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008499 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008500 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008501
8502 /* Add Indicator of Which Drive was Used to Boot the System */
8503 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8504 tmp[1] = ':';
8505 tmp[2] = '\0';
8506
Fred Drake4d1e64b2002-04-15 19:40:07 +00008507 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008508}
8509#endif
8510
Barry Warsaw4a342091996-12-19 23:50:02 +00008511static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008512all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008513{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008514#ifdef F_OK
8515 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008516#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008517#ifdef R_OK
8518 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008519#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008520#ifdef W_OK
8521 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008522#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008523#ifdef X_OK
8524 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008525#endif
Fred Drakec9680921999-12-13 16:37:25 +00008526#ifdef NGROUPS_MAX
8527 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8528#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008529#ifdef TMP_MAX
8530 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8531#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008532#ifdef WCONTINUED
8533 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8534#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008535#ifdef WNOHANG
8536 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008537#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008538#ifdef WUNTRACED
8539 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8540#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008541#ifdef O_RDONLY
8542 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8543#endif
8544#ifdef O_WRONLY
8545 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8546#endif
8547#ifdef O_RDWR
8548 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8549#endif
8550#ifdef O_NDELAY
8551 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8552#endif
8553#ifdef O_NONBLOCK
8554 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8555#endif
8556#ifdef O_APPEND
8557 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8558#endif
8559#ifdef O_DSYNC
8560 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8561#endif
8562#ifdef O_RSYNC
8563 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8564#endif
8565#ifdef O_SYNC
8566 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8567#endif
8568#ifdef O_NOCTTY
8569 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8570#endif
8571#ifdef O_CREAT
8572 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8573#endif
8574#ifdef O_EXCL
8575 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8576#endif
8577#ifdef O_TRUNC
8578 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8579#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008580#ifdef O_BINARY
8581 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8582#endif
8583#ifdef O_TEXT
8584 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8585#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008586#ifdef O_LARGEFILE
8587 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8588#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008589#ifdef O_SHLOCK
8590 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8591#endif
8592#ifdef O_EXLOCK
8593 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8594#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008595
Tim Peters5aa91602002-01-30 05:46:57 +00008596/* MS Windows */
8597#ifdef O_NOINHERIT
8598 /* Don't inherit in child processes. */
8599 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8600#endif
8601#ifdef _O_SHORT_LIVED
8602 /* Optimize for short life (keep in memory). */
8603 /* MS forgot to define this one with a non-underscore form too. */
8604 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8605#endif
8606#ifdef O_TEMPORARY
8607 /* Automatically delete when last handle is closed. */
8608 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8609#endif
8610#ifdef O_RANDOM
8611 /* Optimize for random access. */
8612 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8613#endif
8614#ifdef O_SEQUENTIAL
8615 /* Optimize for sequential access. */
8616 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8617#endif
8618
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008619/* GNU extensions. */
8620#ifdef O_DIRECT
8621 /* Direct disk access. */
8622 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8623#endif
8624#ifdef O_DIRECTORY
8625 /* Must be a directory. */
8626 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8627#endif
8628#ifdef O_NOFOLLOW
8629 /* Do not follow links. */
8630 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8631#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008632
Barry Warsaw5676bd12003-01-07 20:57:09 +00008633 /* These come from sysexits.h */
8634#ifdef EX_OK
8635 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008636#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008637#ifdef EX_USAGE
8638 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008639#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008640#ifdef EX_DATAERR
8641 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008642#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008643#ifdef EX_NOINPUT
8644 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008645#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008646#ifdef EX_NOUSER
8647 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008648#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008649#ifdef EX_NOHOST
8650 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008651#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008652#ifdef EX_UNAVAILABLE
8653 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008654#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008655#ifdef EX_SOFTWARE
8656 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008657#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008658#ifdef EX_OSERR
8659 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008660#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008661#ifdef EX_OSFILE
8662 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008663#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008664#ifdef EX_CANTCREAT
8665 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008666#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008667#ifdef EX_IOERR
8668 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008669#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008670#ifdef EX_TEMPFAIL
8671 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008672#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008673#ifdef EX_PROTOCOL
8674 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008675#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008676#ifdef EX_NOPERM
8677 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008678#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008679#ifdef EX_CONFIG
8680 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008681#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008682#ifdef EX_NOTFOUND
8683 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008684#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008685
Guido van Rossum246bc171999-02-01 23:54:31 +00008686#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008687#if defined(PYOS_OS2) && defined(PYCC_GCC)
8688 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8689 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8690 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8691 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8692 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8693 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8694 if (ins(d, "P_PM", (long)P_PM)) return -1;
8695 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8696 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8697 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8698 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8699 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8700 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8701 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8702 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8703 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8704 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8705 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8706 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8707 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8708#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008709 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8710 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8711 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8712 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8713 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008714#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008715#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008716
Guido van Rossumd48f2521997-12-05 22:19:34 +00008717#if defined(PYOS_OS2)
8718 if (insertvalues(d)) return -1;
8719#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008720 return 0;
8721}
8722
8723
Tim Peters5aa91602002-01-30 05:46:57 +00008724#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008725#define INITFUNC initnt
8726#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008727
8728#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008729#define INITFUNC initos2
8730#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008731
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008732#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008733#define INITFUNC initposix
8734#define MODNAME "posix"
8735#endif
8736
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008737PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008738INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008739{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008740 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008741
Fred Drake4d1e64b2002-04-15 19:40:07 +00008742 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008743 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008744 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008745 if (m == NULL)
8746 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008747
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008748 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008749 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008750 Py_XINCREF(v);
8751 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008752 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008753 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008754
Fred Drake4d1e64b2002-04-15 19:40:07 +00008755 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008756 return;
8757
Fred Drake4d1e64b2002-04-15 19:40:07 +00008758 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008759 return;
8760
Fred Drake4d1e64b2002-04-15 19:40:07 +00008761 Py_INCREF(PyExc_OSError);
8762 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008763
Guido van Rossumb3d39562000-01-31 18:41:26 +00008764#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008765 if (posix_putenv_garbage == NULL)
8766 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008767#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008768
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008769 if (!initialized) {
8770 stat_result_desc.name = MODNAME ".stat_result";
8771 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8772 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8773 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8774 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8775 structseq_new = StatResultType.tp_new;
8776 StatResultType.tp_new = statresult_new;
8777
8778 statvfs_result_desc.name = MODNAME ".statvfs_result";
8779 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
8780 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008781 Py_INCREF((PyObject*) &StatResultType);
8782 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008783 Py_INCREF((PyObject*) &StatVFSResultType);
8784 PyModule_AddObject(m, "statvfs_result",
8785 (PyObject*) &StatVFSResultType);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008786 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008787
8788#ifdef __APPLE__
8789 /*
8790 * Step 2 of weak-linking support on Mac OS X.
8791 *
8792 * The code below removes functions that are not available on the
8793 * currently active platform.
8794 *
8795 * This block allow one to use a python binary that was build on
8796 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8797 * OSX 10.4.
8798 */
8799#ifdef HAVE_FSTATVFS
8800 if (fstatvfs == NULL) {
8801 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8802 return;
8803 }
8804 }
8805#endif /* HAVE_FSTATVFS */
8806
8807#ifdef HAVE_STATVFS
8808 if (statvfs == NULL) {
8809 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8810 return;
8811 }
8812 }
8813#endif /* HAVE_STATVFS */
8814
8815# ifdef HAVE_LCHOWN
8816 if (lchown == NULL) {
8817 if (PyObject_DelAttrString(m, "lchown") == -1) {
8818 return;
8819 }
8820 }
8821#endif /* HAVE_LCHOWN */
8822
8823
8824#endif /* __APPLE__ */
8825
Guido van Rossumb6775db1994-08-01 11:34:53 +00008826}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008827
8828#ifdef __cplusplus
8829}
8830#endif