blob: 8e7f2ffd33bc3e2d65cdb0ac48a2b6c932681674 [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 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000018 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000019 * 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
Victor Stinner8c62be82010-05-06 00:08:46 +000072#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000073#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
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000095#ifdef HAVE_LANGINFO_H
96#include <langinfo.h>
97#endif
98
Guido van Rossuma4916fa1996-05-23 22:58:55 +000099/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000100/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000101#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000102#include <process.h>
103#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000104#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000105#define HAVE_GETCWD 1
106#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000107#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000108#if defined(__OS2__)
109#define HAVE_EXECV 1
110#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000111#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000112#include <process.h>
113#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000114#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000115#define HAVE_EXECV 1
116#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000117#define HAVE_OPENDIR 1
118#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000119#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000120#define HAVE_WAIT 1
121#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000122#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000123#define HAVE_GETCWD 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000124#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000125#define HAVE_EXECV 1
126#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000127#define HAVE_SYSTEM 1
128#define HAVE_CWAIT 1
129#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000130#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000131#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000132#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
133/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000134#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000135/* Unix functions that the configure script doesn't check for */
136#define HAVE_EXECV 1
137#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000138#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000139#define HAVE_FORK1 1
140#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000141#define HAVE_GETCWD 1
142#define HAVE_GETEGID 1
143#define HAVE_GETEUID 1
144#define HAVE_GETGID 1
145#define HAVE_GETPPID 1
146#define HAVE_GETUID 1
147#define HAVE_KILL 1
148#define HAVE_OPENDIR 1
149#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000150#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000151#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000152#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000153#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000154#endif /* _MSC_VER */
155#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000156#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000157#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000158
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000159#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000160
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000161#if defined(__sgi)&&_COMPILER_VERSION>=700
162/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
163 (default) */
164extern char *ctermid_r(char *);
165#endif
166
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000167#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000168#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000170#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000171#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000172extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000173#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000174extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000176#endif
177#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000178extern int chdir(char *);
179extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000180#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000181extern int chdir(const char *);
182extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000183#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000184#ifdef __BORLANDC__
185extern int chmod(const char *, int);
186#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000187extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000188#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000189/*#ifdef HAVE_FCHMOD
190extern int fchmod(int, mode_t);
191#endif*/
192/*#ifdef HAVE_LCHMOD
193extern int lchmod(const char *, mode_t);
194#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000195extern int chown(const char *, uid_t, gid_t);
196extern char *getcwd(char *, int);
197extern char *strerror(int);
198extern int link(const char *, const char *);
199extern int rename(const char *, const char *);
200extern int stat(const char *, struct stat *);
201extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000203extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000204#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000206extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000207#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000209
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000210#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211
Guido van Rossumb6775db1994-08-01 11:34:53 +0000212#ifdef HAVE_UTIME_H
213#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000214#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000216#ifdef HAVE_SYS_UTIME_H
217#include <sys/utime.h>
218#define HAVE_UTIME_H /* pretend we do for the rest of this file */
219#endif /* HAVE_SYS_UTIME_H */
220
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221#ifdef HAVE_SYS_TIMES_H
222#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000223#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224
225#ifdef HAVE_SYS_PARAM_H
226#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000227#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228
229#ifdef HAVE_SYS_UTSNAME_H
230#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000231#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000233#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000235#define NAMLEN(dirent) strlen((dirent)->d_name)
236#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000237#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000238#include <direct.h>
239#define NAMLEN(dirent) strlen((dirent)->d_name)
240#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000242#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000243#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000244#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000246#endif
247#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000249#endif
250#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000252#endif
253#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000255#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000256#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000258#endif
259#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000261#endif
262#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000264#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000265#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000266#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000268#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000269#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000270
Guido van Rossumd48f2521997-12-05 22:19:34 +0000271#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000273#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000274
Tim Petersbc2e10e2002-03-03 23:17:02 +0000275#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000276#if defined(PATH_MAX) && PATH_MAX > 1024
277#define MAXPATHLEN PATH_MAX
278#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000279#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000280#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000281#endif /* MAXPATHLEN */
282
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000283#ifdef UNION_WAIT
284/* Emulate some macros on systems that have a union instead of macros */
285
286#ifndef WIFEXITED
287#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
288#endif
289
290#ifndef WEXITSTATUS
291#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
292#endif
293
294#ifndef WTERMSIG
295#define WTERMSIG(u_wait) ((u_wait).w_termsig)
296#endif
297
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000298#define WAIT_TYPE union wait
299#define WAIT_STATUS_INT(s) (s.w_status)
300
301#else /* !UNION_WAIT */
302#define WAIT_TYPE int
303#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000304#endif /* UNION_WAIT */
305
Greg Wardb48bc172000-03-01 21:51:56 +0000306/* Don't use the "_r" form if we don't need it (also, won't have a
307 prototype for it, at least on Solaris -- maybe others as well?). */
308#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
309#define USE_CTERMID_R
310#endif
311
Fred Drake699f3522000-06-29 21:12:41 +0000312/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000313#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000314#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000315# define STAT win32_stat
316# define FSTAT win32_fstat
317# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000318#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000319# define STAT stat
320# define FSTAT fstat
321# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000322#endif
323
Tim Peters11b23062003-04-23 02:39:17 +0000324#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000325#include <sys/mkdev.h>
326#else
327#if defined(MAJOR_IN_SYSMACROS)
328#include <sys/sysmacros.h>
329#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000330#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
331#include <sys/mkdev.h>
332#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000333#endif
Fred Drake699f3522000-06-29 21:12:41 +0000334
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000335#if defined _MSC_VER && _MSC_VER >= 1400
336/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
337 * valid and throw an assertion if it isn't.
338 * Normally, an invalid fd is likely to be a C program error and therefore
339 * an assertion can be useful, but it does contradict the POSIX standard
340 * which for write(2) states:
341 * "Otherwise, -1 shall be returned and errno set to indicate the error."
342 * "[EBADF] The fildes argument is not a valid file descriptor open for
343 * writing."
344 * Furthermore, python allows the user to enter any old integer
345 * as a fd and should merely raise a python exception on error.
346 * The Microsoft CRT doesn't provide an official way to check for the
347 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000348 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000349 * internal structures involved.
350 * The structures below must be updated for each version of visual studio
351 * according to the file internal.h in the CRT source, until MS comes
352 * up with a less hacky way to do this.
353 * (all of this is to avoid globally modifying the CRT behaviour using
354 * _set_invalid_parameter_handler() and _CrtSetReportMode())
355 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000356/* The actual size of the structure is determined at runtime.
357 * Only the first items must be present.
358 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000359typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000360 intptr_t osfhnd;
361 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000362} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000363
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000364extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000365#define IOINFO_L2E 5
366#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
367#define IOINFO_ARRAYS 64
368#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
369#define FOPEN 0x01
370#define _NO_CONSOLE_FILENO (intptr_t)-2
371
372/* This function emulates what the windows CRT does to validate file handles */
373int
374_PyVerify_fd(int fd)
375{
Victor Stinner8c62be82010-05-06 00:08:46 +0000376 const int i1 = fd >> IOINFO_L2E;
377 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000378
Victor Stinner8c62be82010-05-06 00:08:46 +0000379 static int sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000380
Victor Stinner8c62be82010-05-06 00:08:46 +0000381 /* Determine the actual size of the ioinfo structure,
382 * as used by the CRT loaded in memory
383 */
384 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
385 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
386 }
387 if (sizeof_ioinfo == 0) {
388 /* This should not happen... */
389 goto fail;
390 }
391
392 /* See that it isn't a special CLEAR fileno */
393 if (fd != _NO_CONSOLE_FILENO) {
394 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
395 * we check pointer validity and other info
396 */
397 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
398 /* finally, check that the file is open */
399 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
400 if (info->osfile & FOPEN) {
401 return 1;
402 }
403 }
404 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000405 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000406 errno = EBADF;
407 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000408}
409
410/* the special case of checking dup2. The target fd must be in a sensible range */
411static int
412_PyVerify_fd_dup2(int fd1, int fd2)
413{
Victor Stinner8c62be82010-05-06 00:08:46 +0000414 if (!_PyVerify_fd(fd1))
415 return 0;
416 if (fd2 == _NO_CONSOLE_FILENO)
417 return 0;
418 if ((unsigned)fd2 < _NHANDLE_)
419 return 1;
420 else
421 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000422}
423#else
424/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
425#define _PyVerify_fd_dup2(A, B) (1)
426#endif
427
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000428/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000429#ifdef WITH_NEXT_FRAMEWORK
430/* On Darwin/MacOSX a shared library or framework has no access to
431** environ directly, we must obtain it with _NSGetEnviron().
432*/
433#include <crt_externs.h>
434static char **environ;
435#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000436extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000437#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000438
Barry Warsaw53699e91996-12-10 23:23:01 +0000439static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000440convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000441{
Victor Stinner8c62be82010-05-06 00:08:46 +0000442 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000443#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000444 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000445#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000446 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000447#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000448#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000449 APIRET rc;
450 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
451#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000452
Victor Stinner8c62be82010-05-06 00:08:46 +0000453 d = PyDict_New();
454 if (d == NULL)
455 return NULL;
456#ifdef WITH_NEXT_FRAMEWORK
457 if (environ == NULL)
458 environ = *_NSGetEnviron();
459#endif
460#ifdef MS_WINDOWS
461 /* _wenviron must be initialized in this way if the program is started
462 through main() instead of wmain(). */
463 _wgetenv(L"");
464 if (_wenviron == NULL)
465 return d;
466 /* This part ignores errors */
467 for (e = _wenviron; *e != NULL; e++) {
468 PyObject *k;
469 PyObject *v;
470 wchar_t *p = wcschr(*e, L'=');
471 if (p == NULL)
472 continue;
473 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
474 if (k == NULL) {
475 PyErr_Clear();
476 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000477 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000478 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
479 if (v == NULL) {
480 PyErr_Clear();
481 Py_DECREF(k);
482 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000483 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000484 if (PyDict_GetItem(d, k) == NULL) {
485 if (PyDict_SetItem(d, k, v) != 0)
486 PyErr_Clear();
487 }
488 Py_DECREF(k);
489 Py_DECREF(v);
490 }
491#else
492 if (environ == NULL)
493 return d;
494 /* This part ignores errors */
495 for (e = environ; *e != NULL; e++) {
496 PyObject *k;
497 PyObject *v;
498 char *p = strchr(*e, '=');
499 if (p == NULL)
500 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000501 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000502 if (k == NULL) {
503 PyErr_Clear();
504 continue;
505 }
Victor Stinner84ae1182010-05-06 22:05:07 +0000506 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +0000507 if (v == NULL) {
508 PyErr_Clear();
509 Py_DECREF(k);
510 continue;
511 }
512 if (PyDict_GetItem(d, k) == NULL) {
513 if (PyDict_SetItem(d, k, v) != 0)
514 PyErr_Clear();
515 }
516 Py_DECREF(k);
517 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000518 }
519#endif
Victor Stinner8c62be82010-05-06 00:08:46 +0000520#if defined(PYOS_OS2)
521 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
522 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
523 PyObject *v = PyBytes_FromString(buffer);
524 PyDict_SetItemString(d, "BEGINLIBPATH", v);
525 Py_DECREF(v);
526 }
527 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
528 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
529 PyObject *v = PyBytes_FromString(buffer);
530 PyDict_SetItemString(d, "ENDLIBPATH", v);
531 Py_DECREF(v);
532 }
533#endif
534 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000535}
536
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000537/* Set a POSIX-specific error from errno, and return NULL */
538
Barry Warsawd58d7641998-07-23 16:14:40 +0000539static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000540posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000541{
Victor Stinner8c62be82010-05-06 00:08:46 +0000542 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000543}
Barry Warsawd58d7641998-07-23 16:14:40 +0000544static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000545posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000546{
Victor Stinner8c62be82010-05-06 00:08:46 +0000547 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000548}
549
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000550#ifdef MS_WINDOWS
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000551static PyObject *
552posix_error_with_unicode_filename(Py_UNICODE* name)
553{
Victor Stinner8c62be82010-05-06 00:08:46 +0000554 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000555}
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000556#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000557
558
Mark Hammondef8b6542001-05-13 08:04:26 +0000559static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000560posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000561{
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000562 PyObject *name_str, *rc;
563 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
564 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +0000565 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000566 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
567 name_str);
568 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +0000569 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000570}
571
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000572#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000573static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +0000574win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000575{
Victor Stinner8c62be82010-05-06 00:08:46 +0000576 /* XXX We should pass the function name along in the future.
577 (winreg.c also wants to pass the function name.)
578 This would however require an additional param to the
579 Windows error object, which is non-trivial.
580 */
581 errno = GetLastError();
582 if (filename)
583 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
584 else
585 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000586}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000587
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000588static PyObject *
589win32_error_unicode(char* function, Py_UNICODE* filename)
590{
Victor Stinner8c62be82010-05-06 00:08:46 +0000591 /* XXX - see win32_error for comments on 'function' */
592 errno = GetLastError();
593 if (filename)
594 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
595 else
596 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000597}
598
Thomas Wouters477c8d52006-05-27 19:21:47 +0000599static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000600convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000601{
Victor Stinner8c62be82010-05-06 00:08:46 +0000602 if (PyUnicode_CheckExact(*param))
603 Py_INCREF(*param);
604 else if (PyUnicode_Check(*param))
605 /* For a Unicode subtype that's not a Unicode object,
606 return a true Unicode object with the same data. */
607 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
608 PyUnicode_GET_SIZE(*param));
609 else
610 *param = PyUnicode_FromEncodedObject(*param,
611 Py_FileSystemDefaultEncoding,
612 "strict");
613 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000614}
615
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000616#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000617
Guido van Rossumd48f2521997-12-05 22:19:34 +0000618#if defined(PYOS_OS2)
619/**********************************************************************
620 * Helper Function to Trim and Format OS/2 Messages
621 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000622static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000623os2_formatmsg(char *msgbuf, int msglen, char *reason)
624{
625 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
626
627 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
628 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
629
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000630 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000631 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
632 }
633
634 /* Add Optional Reason Text */
635 if (reason) {
636 strcat(msgbuf, " : ");
637 strcat(msgbuf, reason);
638 }
639}
640
641/**********************************************************************
642 * Decode an OS/2 Operating System Error Code
643 *
644 * A convenience function to lookup an OS/2 error code and return a
645 * text message we can use to raise a Python exception.
646 *
647 * Notes:
648 * The messages for errors returned from the OS/2 kernel reside in
649 * the file OSO001.MSG in the \OS2 directory hierarchy.
650 *
651 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000652static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000653os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
654{
655 APIRET rc;
656 ULONG msglen;
657
658 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
659 Py_BEGIN_ALLOW_THREADS
660 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
661 errorcode, "oso001.msg", &msglen);
662 Py_END_ALLOW_THREADS
663
664 if (rc == NO_ERROR)
665 os2_formatmsg(msgbuf, msglen, reason);
666 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000667 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +0000668 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000669
670 return msgbuf;
671}
672
673/* Set an OS/2-specific error and return NULL. OS/2 kernel
674 errors are not in a global variable e.g. 'errno' nor are
675 they congruent with posix error numbers. */
676
Victor Stinner8c62be82010-05-06 00:08:46 +0000677static PyObject *
678os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000679{
680 char text[1024];
681 PyObject *v;
682
683 os2_strerror(text, sizeof(text), code, "");
684
685 v = Py_BuildValue("(is)", code, text);
686 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000687 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000688 Py_DECREF(v);
689 }
690 return NULL; /* Signal to Python that an Exception is Pending */
691}
692
693#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000694
695/* POSIX generic methods */
696
Barry Warsaw53699e91996-12-10 23:23:01 +0000697static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000698posix_fildes(PyObject *fdobj, int (*func)(int))
699{
Victor Stinner8c62be82010-05-06 00:08:46 +0000700 int fd;
701 int res;
702 fd = PyObject_AsFileDescriptor(fdobj);
703 if (fd < 0)
704 return NULL;
705 if (!_PyVerify_fd(fd))
706 return posix_error();
707 Py_BEGIN_ALLOW_THREADS
708 res = (*func)(fd);
709 Py_END_ALLOW_THREADS
710 if (res < 0)
711 return posix_error();
712 Py_INCREF(Py_None);
713 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000714}
Guido van Rossum21142a01999-01-08 21:05:37 +0000715
716static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000717posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000718{
Victor Stinner8c62be82010-05-06 00:08:46 +0000719 PyObject *opath1 = NULL;
720 char *path1;
721 int res;
722 if (!PyArg_ParseTuple(args, format,
723 PyUnicode_FSConverter, &opath1))
724 return NULL;
725 path1 = PyBytes_AsString(opath1);
726 Py_BEGIN_ALLOW_THREADS
727 res = (*func)(path1);
728 Py_END_ALLOW_THREADS
729 if (res < 0)
730 return posix_error_with_allocated_filename(opath1);
731 Py_DECREF(opath1);
732 Py_INCREF(Py_None);
733 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000734}
735
Barry Warsaw53699e91996-12-10 23:23:01 +0000736static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000737posix_2str(PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +0000738 char *format,
739 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000740{
Victor Stinner8c62be82010-05-06 00:08:46 +0000741 PyObject *opath1 = NULL, *opath2 = NULL;
742 char *path1, *path2;
743 int res;
744 if (!PyArg_ParseTuple(args, format,
745 PyUnicode_FSConverter, &opath1,
746 PyUnicode_FSConverter, &opath2)) {
747 return NULL;
748 }
749 path1 = PyBytes_AsString(opath1);
750 path2 = PyBytes_AsString(opath2);
751 Py_BEGIN_ALLOW_THREADS
752 res = (*func)(path1, path2);
753 Py_END_ALLOW_THREADS
754 Py_DECREF(opath1);
755 Py_DECREF(opath2);
756 if (res != 0)
757 /* XXX how to report both path1 and path2??? */
758 return posix_error();
759 Py_INCREF(Py_None);
760 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000761}
762
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000763#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000764static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +0000765win32_1str(PyObject* args, char* func,
766 char* format, BOOL (__stdcall *funcA)(LPCSTR),
767 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000768{
Victor Stinner8c62be82010-05-06 00:08:46 +0000769 PyObject *uni;
770 char *ansi;
771 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +0000772
Victor Stinner8c62be82010-05-06 00:08:46 +0000773 if (!PyArg_ParseTuple(args, wformat, &uni))
774 PyErr_Clear();
775 else {
776 Py_BEGIN_ALLOW_THREADS
777 result = funcW(PyUnicode_AsUnicode(uni));
778 Py_END_ALLOW_THREADS
779 if (!result)
780 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
781 Py_INCREF(Py_None);
782 return Py_None;
783 }
784 if (!PyArg_ParseTuple(args, format, &ansi))
785 return NULL;
786 Py_BEGIN_ALLOW_THREADS
787 result = funcA(ansi);
788 Py_END_ALLOW_THREADS
789 if (!result)
790 return win32_error(func, ansi);
791 Py_INCREF(Py_None);
792 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000793
794}
795
796/* This is a reimplementation of the C library's chdir function,
797 but one that produces Win32 errors instead of DOS error codes.
798 chdir is essentially a wrapper around SetCurrentDirectory; however,
799 it also needs to set "magic" environment variables indicating
800 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000801static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000802win32_chdir(LPCSTR path)
803{
Victor Stinner8c62be82010-05-06 00:08:46 +0000804 char new_path[MAX_PATH+1];
805 int result;
806 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000807
Victor Stinner8c62be82010-05-06 00:08:46 +0000808 if(!SetCurrentDirectoryA(path))
809 return FALSE;
810 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
811 if (!result)
812 return FALSE;
813 /* In the ANSI API, there should not be any paths longer
814 than MAX_PATH. */
815 assert(result <= MAX_PATH+1);
816 if (strncmp(new_path, "\\\\", 2) == 0 ||
817 strncmp(new_path, "//", 2) == 0)
818 /* UNC path, nothing to do. */
819 return TRUE;
820 env[1] = new_path[0];
821 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000822}
823
824/* The Unicode version differs from the ANSI version
825 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000826static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000827win32_wchdir(LPCWSTR path)
828{
Victor Stinner8c62be82010-05-06 00:08:46 +0000829 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
830 int result;
831 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000832
Victor Stinner8c62be82010-05-06 00:08:46 +0000833 if(!SetCurrentDirectoryW(path))
834 return FALSE;
835 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
836 if (!result)
837 return FALSE;
838 if (result > MAX_PATH+1) {
839 new_path = malloc(result * sizeof(wchar_t));
840 if (!new_path) {
841 SetLastError(ERROR_OUTOFMEMORY);
842 return FALSE;
843 }
844 result = GetCurrentDirectoryW(result, new_path);
845 if (!result) {
846 free(new_path);
847 return FALSE;
848 }
849 }
850 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
851 wcsncmp(new_path, L"//", 2) == 0)
852 /* UNC path, nothing to do. */
853 return TRUE;
854 env[1] = new_path[0];
855 result = SetEnvironmentVariableW(env, new_path);
856 if (new_path != _new_path)
857 free(new_path);
858 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000859}
860#endif
861
Martin v. Löwis14694662006-02-03 12:54:16 +0000862#ifdef MS_WINDOWS
863/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
864 - time stamps are restricted to second resolution
865 - file modification times suffer from forth-and-back conversions between
866 UTC and local time
867 Therefore, we implement our own stat, based on the Win32 API directly.
868*/
Victor Stinner8c62be82010-05-06 00:08:46 +0000869#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +0000870
871struct win32_stat{
872 int st_dev;
873 __int64 st_ino;
874 unsigned short st_mode;
875 int st_nlink;
876 int st_uid;
877 int st_gid;
878 int st_rdev;
879 __int64 st_size;
880 int st_atime;
881 int st_atime_nsec;
882 int st_mtime;
883 int st_mtime_nsec;
884 int st_ctime;
885 int st_ctime_nsec;
886};
887
888static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
889
890static void
891FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
892{
Victor Stinner8c62be82010-05-06 00:08:46 +0000893 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
894 /* Cannot simply cast and dereference in_ptr,
895 since it might not be aligned properly */
896 __int64 in;
897 memcpy(&in, in_ptr, sizeof(in));
898 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
899 /* XXX Win32 supports time stamps past 2038; we currently don't */
900 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
Martin v. Löwis14694662006-02-03 12:54:16 +0000901}
902
Thomas Wouters477c8d52006-05-27 19:21:47 +0000903static void
904time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
905{
Victor Stinner8c62be82010-05-06 00:08:46 +0000906 /* XXX endianness */
907 __int64 out;
908 out = time_in + secs_between_epochs;
909 out = out * 10000000 + nsec_in / 100;
910 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000911}
912
Martin v. Löwis14694662006-02-03 12:54:16 +0000913/* Below, we *know* that ugo+r is 0444 */
914#if _S_IREAD != 0400
915#error Unsupported C library
916#endif
917static int
918attributes_to_mode(DWORD attr)
919{
Victor Stinner8c62be82010-05-06 00:08:46 +0000920 int m = 0;
921 if (attr & FILE_ATTRIBUTE_DIRECTORY)
922 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
923 else
924 m |= _S_IFREG;
925 if (attr & FILE_ATTRIBUTE_READONLY)
926 m |= 0444;
927 else
928 m |= 0666;
929 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +0000930}
931
932static int
933attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
934{
Victor Stinner8c62be82010-05-06 00:08:46 +0000935 memset(result, 0, sizeof(*result));
936 result->st_mode = attributes_to_mode(info->dwFileAttributes);
937 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
938 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
939 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
940 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Martin v. Löwis14694662006-02-03 12:54:16 +0000941
Victor Stinner8c62be82010-05-06 00:08:46 +0000942 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +0000943}
944
Guido van Rossumd8faa362007-04-27 19:54:29 +0000945static BOOL
946attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
947{
Victor Stinner8c62be82010-05-06 00:08:46 +0000948 HANDLE hFindFile;
949 WIN32_FIND_DATAA FileData;
950 hFindFile = FindFirstFileA(pszFile, &FileData);
951 if (hFindFile == INVALID_HANDLE_VALUE)
952 return FALSE;
953 FindClose(hFindFile);
954 pfad->dwFileAttributes = FileData.dwFileAttributes;
955 pfad->ftCreationTime = FileData.ftCreationTime;
956 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
957 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
958 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
959 pfad->nFileSizeLow = FileData.nFileSizeLow;
960 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000961}
962
963static BOOL
964attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
965{
Victor Stinner8c62be82010-05-06 00:08:46 +0000966 HANDLE hFindFile;
967 WIN32_FIND_DATAW FileData;
968 hFindFile = FindFirstFileW(pszFile, &FileData);
969 if (hFindFile == INVALID_HANDLE_VALUE)
970 return FALSE;
971 FindClose(hFindFile);
972 pfad->dwFileAttributes = FileData.dwFileAttributes;
973 pfad->ftCreationTime = FileData.ftCreationTime;
974 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
975 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
976 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
977 pfad->nFileSizeLow = FileData.nFileSizeLow;
978 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000979}
980
Brian Curtind40e6f72010-07-08 21:39:08 +0000981/* About the following functions: win32_lstat, win32_lstat_w, win32_stat,
982 win32_stat_w
983
984 In Posix, stat automatically traverses symlinks and returns the stat
985 structure for the target. In Windows, the equivalent GetFileAttributes by
986 default does not traverse symlinks and instead returns attributes for
987 the symlink.
988
989 Therefore, win32_lstat will get the attributes traditionally, and
990 win32_stat will first explicitly resolve the symlink target and then will
991 call win32_lstat on that result.
992
993 The _w represent Unicode equivalents of the aformentioned ANSI functions. */
994
995static int
996win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +0000997{
Victor Stinner8c62be82010-05-06 00:08:46 +0000998 WIN32_FILE_ATTRIBUTE_DATA info;
999 int code;
1000 char *dot;
Brian Curtind40e6f72010-07-08 21:39:08 +00001001 WIN32_FIND_DATAA find_data;
1002 HANDLE find_data_handle;
Victor Stinner8c62be82010-05-06 00:08:46 +00001003 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
1004 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1005 /* Protocol violation: we explicitly clear errno, instead of
1006 setting it to a POSIX error. Callers should use GetLastError. */
1007 errno = 0;
1008 return -1;
1009 } else {
1010 /* Could not get attributes on open file. Fall back to
1011 reading the directory. */
1012 if (!attributes_from_dir(path, &info)) {
1013 /* Very strange. This should not fail now */
1014 errno = 0;
1015 return -1;
1016 }
1017 }
1018 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001019
Victor Stinner8c62be82010-05-06 00:08:46 +00001020 code = attribute_data_to_stat(&info, result);
1021 if (code != 0)
1022 return code;
Brian Curtind40e6f72010-07-08 21:39:08 +00001023
1024 /* Get WIN32_FIND_DATA structure for the path to determine if
1025 it is a symlink */
1026 if(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1027 find_data_handle = FindFirstFileA(path, &find_data);
1028 if(find_data_handle != INVALID_HANDLE_VALUE) {
1029 if(find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
1030 /* first clear the S_IFMT bits */
1031 result->st_mode ^= (result->st_mode & 0170000);
1032 /* now set the bits that make this a symlink */
1033 result->st_mode |= 0120000;
1034 }
1035 FindClose(find_data_handle);
1036 }
1037 }
1038
Victor Stinner8c62be82010-05-06 00:08:46 +00001039 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1040 dot = strrchr(path, '.');
1041 if (dot) {
Brian Curtind40e6f72010-07-08 21:39:08 +00001042 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1043 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00001044 result->st_mode |= 0111;
1045 }
1046 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001047}
1048
Victor Stinner8c62be82010-05-06 00:08:46 +00001049static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001050win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001051{
Victor Stinner8c62be82010-05-06 00:08:46 +00001052 int code;
1053 const wchar_t *dot;
1054 WIN32_FILE_ATTRIBUTE_DATA info;
Brian Curtind40e6f72010-07-08 21:39:08 +00001055 WIN32_FIND_DATAW find_data;
1056 HANDLE find_data_handle;
Victor Stinner8c62be82010-05-06 00:08:46 +00001057 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
1058 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1059 /* Protocol violation: we explicitly clear errno, instead of
1060 setting it to a POSIX error. Callers should use GetLastError. */
1061 errno = 0;
1062 return -1;
1063 } else {
Brian Curtind40e6f72010-07-08 21:39:08 +00001064 /* Could not get attributes on open file. Fall back to reading
1065 the directory. */
1066 if (!attributes_from_dir_w(path, &info)) {
1067 /* Very strange. This should not fail now */
1068 errno = 0;
1069 return -1;
1070 }
1071 }
1072 }
1073 code = attribute_data_to_stat(&info, result);
1074 if (code < 0)
1075 return code;
1076
1077 /* Get WIN32_FIND_DATA structure for the path to determine if
1078 it is a symlink */
1079 if(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1080 find_data_handle = FindFirstFileW(path, &find_data);
1081 if(find_data_handle != INVALID_HANDLE_VALUE) {
1082 if(find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
1083 /* first clear the S_IFMT bits */
1084 result->st_mode ^= (result->st_mode & 0170000);
1085 /* now set the bits that make this a symlink */
1086 result->st_mode |= 0120000;
1087 }
1088 FindClose(find_data_handle);
1089 }
1090 }
1091
1092 /* Set IFEXEC if it is an .exe, .bat, ... */
1093 dot = wcsrchr(path, '.');
1094 if (dot) {
1095 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1096 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1097 result->st_mode |= 0111;
1098 }
1099 return code;
1100}
1101
1102/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1103static int has_GetFinalPathNameByHandle = 0;
1104static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1105 DWORD);
1106static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1107 DWORD);
1108static int
1109check_GetFinalPathNameByHandle()
1110{
1111 HINSTANCE hKernel32;
1112 /* only recheck */
1113 if (!has_GetFinalPathNameByHandle)
1114 {
1115 hKernel32 = GetModuleHandle("KERNEL32");
1116 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1117 "GetFinalPathNameByHandleA");
1118 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1119 "GetFinalPathNameByHandleW");
Brian Curtin74e45612010-07-09 15:58:59 +00001120 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1121 Py_GetFinalPathNameByHandleW;
Brian Curtind40e6f72010-07-08 21:39:08 +00001122 }
1123 return has_GetFinalPathNameByHandle;
1124}
1125
1126static int
1127win32_stat(const char* path, struct win32_stat *result)
1128{
1129 /* Traverse the symlink to the target using
1130 GetFinalPathNameByHandle()
1131 */
1132 int code;
1133 HANDLE hFile;
1134 int buf_size;
1135 char *target_path;
1136 int result_length;
1137 WIN32_FILE_ATTRIBUTE_DATA info;
1138
1139 if(!check_GetFinalPathNameByHandle()) {
1140 /* if the OS doesn't have GetFinalPathNameByHandle, it doesn't
1141 have symlinks, so just fall back to the traditional behavior
1142 found in lstat. */
1143 return win32_lstat(path, result);
1144 }
1145
1146 hFile = CreateFileA(
1147 path,
1148 0, /* desired access */
1149 0, /* share mode */
1150 NULL, /* security attributes */
1151 OPEN_EXISTING,
1152 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
1153 FILE_FLAG_BACKUP_SEMANTICS,
1154 NULL);
1155
1156 if(hFile == INVALID_HANDLE_VALUE) {
1157 /* Either the target doesn't exist, or we don't have access to
1158 get a handle to it. If the former, we need to return an error.
1159 If the latter, we can use attributes_from_dir. */
1160 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1161 /* Protocol violation: we explicitly clear errno, instead of
1162 setting it to a POSIX error. Callers should use GetLastError. */
1163 errno = 0;
1164 return -1;
1165 } else {
1166 /* Could not get attributes on open file. Fall back to
1167 reading the directory. */
1168 if (!attributes_from_dir(path, &info)) {
1169 /* Very strange. This should not fail now */
1170 errno = 0;
1171 return -1;
1172 }
1173 }
1174 code = attribute_data_to_stat(&info, result);
1175 }
1176
1177 buf_size = Py_GetFinalPathNameByHandleA(hFile, 0, 0, VOLUME_NAME_DOS);
1178 if(!buf_size) return -1;
1179 target_path = (char *)malloc((buf_size+1)*sizeof(char));
1180 result_length = Py_GetFinalPathNameByHandleA(hFile, target_path,
1181 buf_size, VOLUME_NAME_DOS);
1182
1183 if(!result_length)
1184 return -1;
1185
1186 if(!CloseHandle(hFile))
1187 return -1;
1188
1189 target_path[result_length] = 0;
1190 code = win32_lstat(target_path, result);
1191 free(target_path);
1192
1193 return code;
1194}
1195
1196static int
1197win32_stat_w(const wchar_t* path, struct win32_stat *result)
1198{
1199 /* Traverse the symlink to the target using GetFinalPathNameByHandle() */
1200 int code;
1201 HANDLE hFile;
1202 int buf_size;
1203 wchar_t *target_path;
1204 int result_length;
1205 WIN32_FILE_ATTRIBUTE_DATA info;
1206
1207 if(!check_GetFinalPathNameByHandle()) {
1208 /* If the OS doesn't have GetFinalPathNameByHandle, it doesn't have
1209 symlinks, so just fall back to the traditional behavior found
1210 in lstat. */
1211 return win32_lstat_w(path, result);
1212 }
1213
1214 hFile = CreateFileW(
1215 path,
1216 0, /* desired access */
1217 0, /* share mode */
1218 NULL, /* security attributes */
1219 OPEN_EXISTING,
1220 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
1221 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1222 NULL);
1223
1224 if(hFile == INVALID_HANDLE_VALUE) {
1225 /* Either the target doesn't exist, or we don't have access to
1226 get a handle to it. If the former, we need to return an error.
1227 If the latter, we can use attributes_from_dir. */
1228 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1229 /* Protocol violation: we explicitly clear errno, instead of
1230 setting it to a POSIX error. Callers should use GetLastError. */
1231 errno = 0;
1232 return -1;
1233 } else {
Victor Stinner8c62be82010-05-06 00:08:46 +00001234 /* Could not get attributes on open file. Fall back to
1235 reading the directory. */
1236 if (!attributes_from_dir_w(path, &info)) {
1237 /* Very strange. This should not fail now */
1238 errno = 0;
1239 return -1;
1240 }
1241 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001242 code = attribute_data_to_stat(&info, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001243 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001244 else {
1245 /* We have a good handle to the target, use it to determine the target
1246 path name (then we'll call lstat on it). */
1247 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_DOS);
1248 if(!buf_size)
1249 return -1;
1250
1251 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
1252 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
1253 buf_size, VOLUME_NAME_DOS);
1254
1255 if(!result_length)
1256 return -1;
1257
1258 if(!CloseHandle(hFile))
1259 return -1;
1260
1261 target_path[result_length] = 0;
1262 code = win32_lstat_w(target_path, result);
1263 free(target_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001264 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001265
Victor Stinner8c62be82010-05-06 00:08:46 +00001266 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001267}
1268
1269static int
1270win32_fstat(int file_number, struct win32_stat *result)
1271{
Victor Stinner8c62be82010-05-06 00:08:46 +00001272 BY_HANDLE_FILE_INFORMATION info;
1273 HANDLE h;
1274 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001275
Victor Stinner8c62be82010-05-06 00:08:46 +00001276 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001277
Victor Stinner8c62be82010-05-06 00:08:46 +00001278 /* Protocol violation: we explicitly clear errno, instead of
1279 setting it to a POSIX error. Callers should use GetLastError. */
1280 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001281
Victor Stinner8c62be82010-05-06 00:08:46 +00001282 if (h == INVALID_HANDLE_VALUE) {
1283 /* This is really a C library error (invalid file handle).
1284 We set the Win32 error to the closes one matching. */
1285 SetLastError(ERROR_INVALID_HANDLE);
1286 return -1;
1287 }
1288 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001289
Victor Stinner8c62be82010-05-06 00:08:46 +00001290 type = GetFileType(h);
1291 if (type == FILE_TYPE_UNKNOWN) {
1292 DWORD error = GetLastError();
1293 if (error != 0) {
1294 return -1;
1295 }
1296 /* else: valid but unknown file */
1297 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001298
Victor Stinner8c62be82010-05-06 00:08:46 +00001299 if (type != FILE_TYPE_DISK) {
1300 if (type == FILE_TYPE_CHAR)
1301 result->st_mode = _S_IFCHR;
1302 else if (type == FILE_TYPE_PIPE)
1303 result->st_mode = _S_IFIFO;
1304 return 0;
1305 }
1306
1307 if (!GetFileInformationByHandle(h, &info)) {
1308 return -1;
1309 }
1310
1311 /* similar to stat() */
1312 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1313 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
Brian Curtin74e45612010-07-09 15:58:59 +00001314 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime,
1315 &result->st_ctime_nsec);
1316 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime,
1317 &result->st_mtime_nsec);
1318 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime,
1319 &result->st_atime_nsec);
Victor Stinner8c62be82010-05-06 00:08:46 +00001320 /* specific to fstat() */
1321 result->st_nlink = info.nNumberOfLinks;
1322 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1323 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001324}
1325
1326#endif /* MS_WINDOWS */
1327
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001328PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001329"stat_result: Result from stat or lstat.\n\n\
1330This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001331 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001332or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1333\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001334Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1335or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001336\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001337See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001338
1339static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001340 {"st_mode", "protection bits"},
1341 {"st_ino", "inode"},
1342 {"st_dev", "device"},
1343 {"st_nlink", "number of hard links"},
1344 {"st_uid", "user ID of owner"},
1345 {"st_gid", "group ID of owner"},
1346 {"st_size", "total size, in bytes"},
1347 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1348 {NULL, "integer time of last access"},
1349 {NULL, "integer time of last modification"},
1350 {NULL, "integer time of last change"},
1351 {"st_atime", "time of last access"},
1352 {"st_mtime", "time of last modification"},
1353 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001354#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001355 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001356#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001357#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001358 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001359#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001360#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001361 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001362#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001363#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001364 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001365#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001366#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001367 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001368#endif
1369#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001370 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001371#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001372 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001373};
1374
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001375#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001376#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001377#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001378#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001379#endif
1380
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001381#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001382#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1383#else
1384#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1385#endif
1386
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001387#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001388#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1389#else
1390#define ST_RDEV_IDX ST_BLOCKS_IDX
1391#endif
1392
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001393#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1394#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1395#else
1396#define ST_FLAGS_IDX ST_RDEV_IDX
1397#endif
1398
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001399#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001400#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001401#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001402#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001403#endif
1404
1405#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1406#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1407#else
1408#define ST_BIRTHTIME_IDX ST_GEN_IDX
1409#endif
1410
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001411static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001412 "stat_result", /* name */
1413 stat_result__doc__, /* doc */
1414 stat_result_fields,
1415 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001416};
1417
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001418PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001419"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1420This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001421 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001422or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001423\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001424See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001425
1426static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001427 {"f_bsize", },
1428 {"f_frsize", },
1429 {"f_blocks", },
1430 {"f_bfree", },
1431 {"f_bavail", },
1432 {"f_files", },
1433 {"f_ffree", },
1434 {"f_favail", },
1435 {"f_flag", },
1436 {"f_namemax",},
1437 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001438};
1439
1440static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001441 "statvfs_result", /* name */
1442 statvfs_result__doc__, /* doc */
1443 statvfs_result_fields,
1444 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001445};
1446
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001447static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001448static PyTypeObject StatResultType;
1449static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001450static newfunc structseq_new;
1451
1452static PyObject *
1453statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1454{
Victor Stinner8c62be82010-05-06 00:08:46 +00001455 PyStructSequence *result;
1456 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001457
Victor Stinner8c62be82010-05-06 00:08:46 +00001458 result = (PyStructSequence*)structseq_new(type, args, kwds);
1459 if (!result)
1460 return NULL;
1461 /* If we have been initialized from a tuple,
1462 st_?time might be set to None. Initialize it
1463 from the int slots. */
1464 for (i = 7; i <= 9; i++) {
1465 if (result->ob_item[i+3] == Py_None) {
1466 Py_DECREF(Py_None);
1467 Py_INCREF(result->ob_item[i]);
1468 result->ob_item[i+3] = result->ob_item[i];
1469 }
1470 }
1471 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001472}
1473
1474
1475
1476/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001477static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001478
1479PyDoc_STRVAR(stat_float_times__doc__,
1480"stat_float_times([newval]) -> oldval\n\n\
1481Determine whether os.[lf]stat represents time stamps as float objects.\n\
1482If newval is True, future calls to stat() return floats, if it is False,\n\
1483future calls return ints. \n\
1484If newval is omitted, return the current setting.\n");
1485
1486static PyObject*
1487stat_float_times(PyObject* self, PyObject *args)
1488{
Victor Stinner8c62be82010-05-06 00:08:46 +00001489 int newval = -1;
1490 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1491 return NULL;
1492 if (newval == -1)
1493 /* Return old value */
1494 return PyBool_FromLong(_stat_float_times);
1495 _stat_float_times = newval;
1496 Py_INCREF(Py_None);
1497 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001498}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001499
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001500static void
1501fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1502{
Victor Stinner8c62be82010-05-06 00:08:46 +00001503 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001504#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner8c62be82010-05-06 00:08:46 +00001505 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001506#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001507 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001508#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001509 if (!ival)
1510 return;
1511 if (_stat_float_times) {
1512 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1513 } else {
1514 fval = ival;
1515 Py_INCREF(fval);
1516 }
1517 PyStructSequence_SET_ITEM(v, index, ival);
1518 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001519}
1520
Tim Peters5aa91602002-01-30 05:46:57 +00001521/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001522 (used by posix_stat() and posix_fstat()) */
1523static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001524_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001525{
Victor Stinner8c62be82010-05-06 00:08:46 +00001526 unsigned long ansec, mnsec, cnsec;
1527 PyObject *v = PyStructSequence_New(&StatResultType);
1528 if (v == NULL)
1529 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001530
Victor Stinner8c62be82010-05-06 00:08:46 +00001531 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001532#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001533 PyStructSequence_SET_ITEM(v, 1,
1534 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001535#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001536 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001537#endif
1538#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001539 PyStructSequence_SET_ITEM(v, 2,
1540 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001541#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001542 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001543#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001544 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1545 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1546 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001547#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001548 PyStructSequence_SET_ITEM(v, 6,
1549 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001550#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001551 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001552#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001553
Martin v. Löwis14694662006-02-03 12:54:16 +00001554#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001555 ansec = st->st_atim.tv_nsec;
1556 mnsec = st->st_mtim.tv_nsec;
1557 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001558#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001559 ansec = st->st_atimespec.tv_nsec;
1560 mnsec = st->st_mtimespec.tv_nsec;
1561 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001562#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001563 ansec = st->st_atime_nsec;
1564 mnsec = st->st_mtime_nsec;
1565 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001566#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001567 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001568#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001569 fill_time(v, 7, st->st_atime, ansec);
1570 fill_time(v, 8, st->st_mtime, mnsec);
1571 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001572
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001573#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001574 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1575 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001576#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001577#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001578 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1579 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001580#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001581#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001582 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1583 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001584#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001585#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001586 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1587 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001588#endif
1589#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001590 {
1591 PyObject *val;
1592 unsigned long bsec,bnsec;
1593 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001594#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner8c62be82010-05-06 00:08:46 +00001595 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001596#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001597 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001598#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001599 if (_stat_float_times) {
1600 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1601 } else {
1602 val = PyLong_FromLong((long)bsec);
1603 }
1604 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1605 val);
1606 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001607#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001608#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001609 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1610 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001611#endif
Fred Drake699f3522000-06-29 21:12:41 +00001612
Victor Stinner8c62be82010-05-06 00:08:46 +00001613 if (PyErr_Occurred()) {
1614 Py_DECREF(v);
1615 return NULL;
1616 }
Fred Drake699f3522000-06-29 21:12:41 +00001617
Victor Stinner8c62be82010-05-06 00:08:46 +00001618 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001619}
1620
Martin v. Löwisd8948722004-06-02 09:57:56 +00001621#ifdef MS_WINDOWS
1622
1623/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1624 where / can be used in place of \ and the trailing slash is optional.
1625 Both SERVER and SHARE must have at least one character.
1626*/
1627
1628#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1629#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001630#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001631#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001632#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001633
Tim Peters4ad82172004-08-30 17:02:04 +00001634static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001635IsUNCRootA(char *path, int pathlen)
1636{
Victor Stinner8c62be82010-05-06 00:08:46 +00001637 #define ISSLASH ISSLASHA
Martin v. Löwisd8948722004-06-02 09:57:56 +00001638
Victor Stinner8c62be82010-05-06 00:08:46 +00001639 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001640
Victor Stinner8c62be82010-05-06 00:08:46 +00001641 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1642 /* minimum UNCRoot is \\x\y */
1643 return FALSE;
1644 for (i = 2; i < pathlen ; i++)
1645 if (ISSLASH(path[i])) break;
1646 if (i == 2 || i == pathlen)
1647 /* do not allow \\\SHARE or \\SERVER */
1648 return FALSE;
1649 share = i+1;
1650 for (i = share; i < pathlen; i++)
1651 if (ISSLASH(path[i])) break;
1652 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001653
Victor Stinner8c62be82010-05-06 00:08:46 +00001654 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001655}
1656
Tim Peters4ad82172004-08-30 17:02:04 +00001657static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001658IsUNCRootW(Py_UNICODE *path, int pathlen)
1659{
Victor Stinner8c62be82010-05-06 00:08:46 +00001660 #define ISSLASH ISSLASHW
Martin v. Löwisd8948722004-06-02 09:57:56 +00001661
Victor Stinner8c62be82010-05-06 00:08:46 +00001662 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001663
Victor Stinner8c62be82010-05-06 00:08:46 +00001664 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1665 /* minimum UNCRoot is \\x\y */
1666 return FALSE;
1667 for (i = 2; i < pathlen ; i++)
1668 if (ISSLASH(path[i])) break;
1669 if (i == 2 || i == pathlen)
1670 /* do not allow \\\SHARE or \\SERVER */
1671 return FALSE;
1672 share = i+1;
1673 for (i = share; i < pathlen; i++)
1674 if (ISSLASH(path[i])) break;
1675 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001676
Victor Stinner8c62be82010-05-06 00:08:46 +00001677 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001678}
Martin v. Löwisd8948722004-06-02 09:57:56 +00001679#endif /* MS_WINDOWS */
1680
Barry Warsaw53699e91996-12-10 23:23:01 +00001681static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001682posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +00001683 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001684#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00001685 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001686#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001687 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001688#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001689 char *wformat,
1690 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001691{
Victor Stinner8c62be82010-05-06 00:08:46 +00001692 STRUCT_STAT st;
1693 PyObject *opath;
1694 char *path;
1695 int res;
1696 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001697
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001698#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001699 PyUnicodeObject *po;
1700 if (PyArg_ParseTuple(args, wformat, &po)) {
1701 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001702
Victor Stinner8c62be82010-05-06 00:08:46 +00001703 Py_BEGIN_ALLOW_THREADS
1704 /* PyUnicode_AS_UNICODE result OK without
1705 thread lock as it is a simple dereference. */
1706 res = wstatfunc(wpath, &st);
1707 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001708
Victor Stinner8c62be82010-05-06 00:08:46 +00001709 if (res != 0)
1710 return win32_error_unicode("stat", wpath);
1711 return _pystat_fromstructstat(&st);
1712 }
1713 /* Drop the argument parsing error as narrow strings
1714 are also valid. */
1715 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001716#endif
1717
Victor Stinner8c62be82010-05-06 00:08:46 +00001718 if (!PyArg_ParseTuple(args, format,
1719 PyUnicode_FSConverter, &opath))
1720 return NULL;
1721 path = PyBytes_AsString(opath);
1722 Py_BEGIN_ALLOW_THREADS
1723 res = (*statfunc)(path, &st);
1724 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001725
Victor Stinner8c62be82010-05-06 00:08:46 +00001726 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001727#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001728 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001729#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001730 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001731#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001732 }
1733 else
1734 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001735
Victor Stinner8c62be82010-05-06 00:08:46 +00001736 Py_DECREF(opath);
1737 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001738}
1739
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001740/* POSIX methods */
1741
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001742PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001743"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001744Use the real uid/gid to test for access to a path. Note that most\n\
1745operations will use the effective uid/gid, therefore this routine can\n\
1746be used in a suid/sgid environment to test if the invoking user has the\n\
1747specified access to the path. The mode argument can be F_OK to test\n\
1748existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001749
1750static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001751posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001752{
Victor Stinner8c62be82010-05-06 00:08:46 +00001753 PyObject *opath;
1754 char *path;
1755 int mode;
1756
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001757#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001758 DWORD attr;
1759 PyUnicodeObject *po;
1760 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1761 Py_BEGIN_ALLOW_THREADS
1762 /* PyUnicode_AS_UNICODE OK without thread lock as
1763 it is a simple dereference. */
1764 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1765 Py_END_ALLOW_THREADS
1766 goto finish;
1767 }
1768 /* Drop the argument parsing error as narrow strings
1769 are also valid. */
1770 PyErr_Clear();
1771 if (!PyArg_ParseTuple(args, "O&i:access",
1772 PyUnicode_FSConverter, &opath, &mode))
1773 return NULL;
1774 path = PyBytes_AsString(opath);
1775 Py_BEGIN_ALLOW_THREADS
1776 attr = GetFileAttributesA(path);
1777 Py_END_ALLOW_THREADS
1778 Py_DECREF(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001779finish:
Victor Stinner8c62be82010-05-06 00:08:46 +00001780 if (attr == 0xFFFFFFFF)
1781 /* File does not exist, or cannot read attributes */
1782 return PyBool_FromLong(0);
1783 /* Access is possible if either write access wasn't requested, or
1784 the file isn't read-only, or if it's a directory, as there are
1785 no read-only directories on Windows. */
1786 return PyBool_FromLong(!(mode & 2)
1787 || !(attr & FILE_ATTRIBUTE_READONLY)
1788 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001789#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001790 int res;
1791 if (!PyArg_ParseTuple(args, "O&i:access",
1792 PyUnicode_FSConverter, &opath, &mode))
1793 return NULL;
1794 path = PyBytes_AsString(opath);
1795 Py_BEGIN_ALLOW_THREADS
1796 res = access(path, mode);
1797 Py_END_ALLOW_THREADS
1798 Py_DECREF(opath);
1799 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001800#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001801}
1802
Guido van Rossumd371ff11999-01-25 16:12:23 +00001803#ifndef F_OK
1804#define F_OK 0
1805#endif
1806#ifndef R_OK
1807#define R_OK 4
1808#endif
1809#ifndef W_OK
1810#define W_OK 2
1811#endif
1812#ifndef X_OK
1813#define X_OK 1
1814#endif
1815
1816#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001817PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001818"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001819Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001820
1821static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001822posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001823{
Victor Stinner8c62be82010-05-06 00:08:46 +00001824 int id;
1825 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001826
Victor Stinner8c62be82010-05-06 00:08:46 +00001827 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1828 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001829
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001830#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001831 /* file descriptor 0 only, the default input device (stdin) */
1832 if (id == 0) {
1833 ret = ttyname();
1834 }
1835 else {
1836 ret = NULL;
1837 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001838#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001839 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001840#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001841 if (ret == NULL)
1842 return posix_error();
1843 return PyUnicode_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001844}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001845#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001846
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001847#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001848PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001849"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001850Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001851
1852static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001853posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001854{
Victor Stinner8c62be82010-05-06 00:08:46 +00001855 char *ret;
1856 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001857
Greg Wardb48bc172000-03-01 21:51:56 +00001858#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00001859 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001860#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001861 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001862#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001863 if (ret == NULL)
1864 return posix_error();
1865 return PyUnicode_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001866}
1867#endif
1868
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001869PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001870"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001871Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001872
Barry Warsaw53699e91996-12-10 23:23:01 +00001873static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001874posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001875{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001876#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001877 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001878#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001879 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001880#elif defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001881 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001882#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001883 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001884#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001885}
1886
Fred Drake4d1e64b2002-04-15 19:40:07 +00001887#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001888PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001889"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001890Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001891opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001892
1893static PyObject *
1894posix_fchdir(PyObject *self, PyObject *fdobj)
1895{
Victor Stinner8c62be82010-05-06 00:08:46 +00001896 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001897}
1898#endif /* HAVE_FCHDIR */
1899
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001900
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001901PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001902"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001903Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001904
Barry Warsaw53699e91996-12-10 23:23:01 +00001905static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001906posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001907{
Victor Stinner8c62be82010-05-06 00:08:46 +00001908 PyObject *opath = NULL;
1909 char *path = NULL;
1910 int i;
1911 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001912#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001913 DWORD attr;
1914 PyUnicodeObject *po;
1915 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1916 Py_BEGIN_ALLOW_THREADS
1917 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1918 if (attr != 0xFFFFFFFF) {
1919 if (i & _S_IWRITE)
1920 attr &= ~FILE_ATTRIBUTE_READONLY;
1921 else
1922 attr |= FILE_ATTRIBUTE_READONLY;
1923 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1924 }
1925 else
1926 res = 0;
1927 Py_END_ALLOW_THREADS
1928 if (!res)
1929 return win32_error_unicode("chmod",
1930 PyUnicode_AS_UNICODE(po));
1931 Py_INCREF(Py_None);
1932 return Py_None;
1933 }
1934 /* Drop the argument parsing error as narrow strings
1935 are also valid. */
1936 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001937
Victor Stinner8c62be82010-05-06 00:08:46 +00001938 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1939 &opath, &i))
1940 return NULL;
1941 path = PyBytes_AsString(opath);
1942 Py_BEGIN_ALLOW_THREADS
1943 attr = GetFileAttributesA(path);
1944 if (attr != 0xFFFFFFFF) {
1945 if (i & _S_IWRITE)
1946 attr &= ~FILE_ATTRIBUTE_READONLY;
1947 else
1948 attr |= FILE_ATTRIBUTE_READONLY;
1949 res = SetFileAttributesA(path, attr);
1950 }
1951 else
1952 res = 0;
1953 Py_END_ALLOW_THREADS
1954 if (!res) {
1955 win32_error("chmod", path);
1956 Py_DECREF(opath);
1957 return NULL;
1958 }
1959 Py_DECREF(opath);
1960 Py_INCREF(Py_None);
1961 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001962#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00001963 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1964 &opath, &i))
1965 return NULL;
1966 path = PyBytes_AsString(opath);
1967 Py_BEGIN_ALLOW_THREADS
1968 res = chmod(path, i);
1969 Py_END_ALLOW_THREADS
1970 if (res < 0)
1971 return posix_error_with_allocated_filename(opath);
1972 Py_DECREF(opath);
1973 Py_INCREF(Py_None);
1974 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001975#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001976}
1977
Christian Heimes4e30a842007-11-30 22:12:06 +00001978#ifdef HAVE_FCHMOD
1979PyDoc_STRVAR(posix_fchmod__doc__,
1980"fchmod(fd, mode)\n\n\
1981Change the access permissions of the file given by file\n\
1982descriptor fd.");
1983
1984static PyObject *
1985posix_fchmod(PyObject *self, PyObject *args)
1986{
Victor Stinner8c62be82010-05-06 00:08:46 +00001987 int fd, mode, res;
1988 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1989 return NULL;
1990 Py_BEGIN_ALLOW_THREADS
1991 res = fchmod(fd, mode);
1992 Py_END_ALLOW_THREADS
1993 if (res < 0)
1994 return posix_error();
1995 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001996}
1997#endif /* HAVE_FCHMOD */
1998
1999#ifdef HAVE_LCHMOD
2000PyDoc_STRVAR(posix_lchmod__doc__,
2001"lchmod(path, mode)\n\n\
2002Change the access permissions of a file. If path is a symlink, this\n\
2003affects the link itself rather than the target.");
2004
2005static PyObject *
2006posix_lchmod(PyObject *self, PyObject *args)
2007{
Victor Stinner8c62be82010-05-06 00:08:46 +00002008 PyObject *opath;
2009 char *path;
2010 int i;
2011 int res;
2012 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2013 &opath, &i))
2014 return NULL;
2015 path = PyBytes_AsString(opath);
2016 Py_BEGIN_ALLOW_THREADS
2017 res = lchmod(path, i);
2018 Py_END_ALLOW_THREADS
2019 if (res < 0)
2020 return posix_error_with_allocated_filename(opath);
2021 Py_DECREF(opath);
2022 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002023}
2024#endif /* HAVE_LCHMOD */
2025
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002026
Thomas Wouterscf297e42007-02-23 15:07:44 +00002027#ifdef HAVE_CHFLAGS
2028PyDoc_STRVAR(posix_chflags__doc__,
2029"chflags(path, flags)\n\n\
2030Set file flags.");
2031
2032static PyObject *
2033posix_chflags(PyObject *self, PyObject *args)
2034{
Victor Stinner8c62be82010-05-06 00:08:46 +00002035 PyObject *opath;
2036 char *path;
2037 unsigned long flags;
2038 int res;
2039 if (!PyArg_ParseTuple(args, "O&k:chflags",
2040 PyUnicode_FSConverter, &opath, &flags))
2041 return NULL;
2042 path = PyBytes_AsString(opath);
2043 Py_BEGIN_ALLOW_THREADS
2044 res = chflags(path, flags);
2045 Py_END_ALLOW_THREADS
2046 if (res < 0)
2047 return posix_error_with_allocated_filename(opath);
2048 Py_DECREF(opath);
2049 Py_INCREF(Py_None);
2050 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002051}
2052#endif /* HAVE_CHFLAGS */
2053
2054#ifdef HAVE_LCHFLAGS
2055PyDoc_STRVAR(posix_lchflags__doc__,
2056"lchflags(path, flags)\n\n\
2057Set file flags.\n\
2058This function will not follow symbolic links.");
2059
2060static PyObject *
2061posix_lchflags(PyObject *self, PyObject *args)
2062{
Victor Stinner8c62be82010-05-06 00:08:46 +00002063 PyObject *opath;
2064 char *path;
2065 unsigned long flags;
2066 int res;
2067 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2068 PyUnicode_FSConverter, &opath, &flags))
2069 return NULL;
2070 path = PyBytes_AsString(opath);
2071 Py_BEGIN_ALLOW_THREADS
2072 res = lchflags(path, flags);
2073 Py_END_ALLOW_THREADS
2074 if (res < 0)
2075 return posix_error_with_allocated_filename(opath);
2076 Py_DECREF(opath);
2077 Py_INCREF(Py_None);
2078 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002079}
2080#endif /* HAVE_LCHFLAGS */
2081
Martin v. Löwis244edc82001-10-04 22:44:26 +00002082#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002083PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002084"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002085Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002086
2087static PyObject *
2088posix_chroot(PyObject *self, PyObject *args)
2089{
Victor Stinner8c62be82010-05-06 00:08:46 +00002090 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002091}
2092#endif
2093
Guido van Rossum21142a01999-01-08 21:05:37 +00002094#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002095PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002096"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002097force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002098
2099static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002100posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002101{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002102 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002103}
2104#endif /* HAVE_FSYNC */
2105
2106#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002107
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002108#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002109extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2110#endif
2111
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002112PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002113"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002114force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002115 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002116
2117static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002118posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002119{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002120 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002121}
2122#endif /* HAVE_FDATASYNC */
2123
2124
Fredrik Lundh10723342000-07-10 16:38:09 +00002125#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002126PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002127"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002128Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002129
Barry Warsaw53699e91996-12-10 23:23:01 +00002130static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002131posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002132{
Victor Stinner8c62be82010-05-06 00:08:46 +00002133 PyObject *opath;
2134 char *path;
2135 long uid, gid;
2136 int res;
2137 if (!PyArg_ParseTuple(args, "O&ll:chown",
2138 PyUnicode_FSConverter, &opath,
2139 &uid, &gid))
2140 return NULL;
2141 path = PyBytes_AsString(opath);
2142 Py_BEGIN_ALLOW_THREADS
2143 res = chown(path, (uid_t) uid, (gid_t) gid);
2144 Py_END_ALLOW_THREADS
2145 if (res < 0)
2146 return posix_error_with_allocated_filename(opath);
2147 Py_DECREF(opath);
2148 Py_INCREF(Py_None);
2149 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002150}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002151#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002152
Christian Heimes4e30a842007-11-30 22:12:06 +00002153#ifdef HAVE_FCHOWN
2154PyDoc_STRVAR(posix_fchown__doc__,
2155"fchown(fd, uid, gid)\n\n\
2156Change the owner and group id of the file given by file descriptor\n\
2157fd to the numeric uid and gid.");
2158
2159static PyObject *
2160posix_fchown(PyObject *self, PyObject *args)
2161{
Victor Stinner8c62be82010-05-06 00:08:46 +00002162 int fd;
2163 long uid, gid;
2164 int res;
2165 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
2166 return NULL;
2167 Py_BEGIN_ALLOW_THREADS
2168 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2169 Py_END_ALLOW_THREADS
2170 if (res < 0)
2171 return posix_error();
2172 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002173}
2174#endif /* HAVE_FCHOWN */
2175
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002176#ifdef HAVE_LCHOWN
2177PyDoc_STRVAR(posix_lchown__doc__,
2178"lchown(path, uid, gid)\n\n\
2179Change the owner and group id of path to the numeric uid and gid.\n\
2180This function will not follow symbolic links.");
2181
2182static PyObject *
2183posix_lchown(PyObject *self, PyObject *args)
2184{
Victor Stinner8c62be82010-05-06 00:08:46 +00002185 PyObject *opath;
2186 char *path;
2187 long uid, gid;
2188 int res;
2189 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2190 PyUnicode_FSConverter, &opath,
2191 &uid, &gid))
2192 return NULL;
2193 path = PyBytes_AsString(opath);
2194 Py_BEGIN_ALLOW_THREADS
2195 res = lchown(path, (uid_t) uid, (gid_t) gid);
2196 Py_END_ALLOW_THREADS
2197 if (res < 0)
2198 return posix_error_with_allocated_filename(opath);
2199 Py_DECREF(opath);
2200 Py_INCREF(Py_None);
2201 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002202}
2203#endif /* HAVE_LCHOWN */
2204
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002205
Guido van Rossum36bc6801995-06-14 22:54:23 +00002206#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002207static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002208posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002209{
Victor Stinner8c62be82010-05-06 00:08:46 +00002210 char buf[1026];
2211 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002212
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002213#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002214 if (!use_bytes) {
2215 wchar_t wbuf[1026];
2216 wchar_t *wbuf2 = wbuf;
2217 PyObject *resobj;
2218 DWORD len;
2219 Py_BEGIN_ALLOW_THREADS
2220 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2221 /* If the buffer is large enough, len does not include the
2222 terminating \0. If the buffer is too small, len includes
2223 the space needed for the terminator. */
2224 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2225 wbuf2 = malloc(len * sizeof(wchar_t));
2226 if (wbuf2)
2227 len = GetCurrentDirectoryW(len, wbuf2);
2228 }
2229 Py_END_ALLOW_THREADS
2230 if (!wbuf2) {
2231 PyErr_NoMemory();
2232 return NULL;
2233 }
2234 if (!len) {
2235 if (wbuf2 != wbuf) free(wbuf2);
2236 return win32_error("getcwdu", NULL);
2237 }
2238 resobj = PyUnicode_FromWideChar(wbuf2, len);
2239 if (wbuf2 != wbuf) free(wbuf2);
2240 return resobj;
2241 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002242#endif
2243
Victor Stinner8c62be82010-05-06 00:08:46 +00002244 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002245#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002246 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002247#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002248 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002249#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002250 Py_END_ALLOW_THREADS
2251 if (res == NULL)
2252 return posix_error();
2253 if (use_bytes)
2254 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002255 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002256}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002257
2258PyDoc_STRVAR(posix_getcwd__doc__,
2259"getcwd() -> path\n\n\
2260Return a unicode string representing the current working directory.");
2261
2262static PyObject *
2263posix_getcwd_unicode(PyObject *self)
2264{
2265 return posix_getcwd(0);
2266}
2267
2268PyDoc_STRVAR(posix_getcwdb__doc__,
2269"getcwdb() -> path\n\n\
2270Return a bytes string representing the current working directory.");
2271
2272static PyObject *
2273posix_getcwd_bytes(PyObject *self)
2274{
2275 return posix_getcwd(1);
2276}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002277#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002278
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002279
Guido van Rossumb6775db1994-08-01 11:34:53 +00002280#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002281PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002282"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002283Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002284
Barry Warsaw53699e91996-12-10 23:23:01 +00002285static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002286posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002287{
Victor Stinner8c62be82010-05-06 00:08:46 +00002288 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002289}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002290#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002291
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002292
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002293PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002294"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002295Return a list containing the names of the entries in the directory.\n\
2296\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00002297 path: path of directory to list\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002298\n\
2299The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002300entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002301
Barry Warsaw53699e91996-12-10 23:23:01 +00002302static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002303posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002304{
Victor Stinner8c62be82010-05-06 00:08:46 +00002305 /* XXX Should redo this putting the (now four) versions of opendir
2306 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002307#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002308
Victor Stinner8c62be82010-05-06 00:08:46 +00002309 PyObject *d, *v;
2310 HANDLE hFindFile;
2311 BOOL result;
2312 WIN32_FIND_DATA FileData;
2313 PyObject *opath;
2314 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2315 char *bufptr = namebuf;
2316 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002317
Victor Stinner8c62be82010-05-06 00:08:46 +00002318 PyObject *po;
2319 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2320 WIN32_FIND_DATAW wFileData;
2321 Py_UNICODE *wnamebuf;
2322 /* Overallocate for \\*.*\0 */
2323 len = PyUnicode_GET_SIZE(po);
2324 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2325 if (!wnamebuf) {
2326 PyErr_NoMemory();
2327 return NULL;
2328 }
2329 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2330 if (len > 0) {
2331 Py_UNICODE wch = wnamebuf[len-1];
2332 if (wch != L'/' && wch != L'\\' && wch != L':')
2333 wnamebuf[len++] = L'\\';
2334 wcscpy(wnamebuf + len, L"*.*");
2335 }
2336 if ((d = PyList_New(0)) == NULL) {
2337 free(wnamebuf);
2338 return NULL;
2339 }
2340 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2341 if (hFindFile == INVALID_HANDLE_VALUE) {
2342 int error = GetLastError();
2343 if (error == ERROR_FILE_NOT_FOUND) {
2344 free(wnamebuf);
2345 return d;
2346 }
2347 Py_DECREF(d);
2348 win32_error_unicode("FindFirstFileW", wnamebuf);
2349 free(wnamebuf);
2350 return NULL;
2351 }
2352 do {
2353 /* Skip over . and .. */
2354 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2355 wcscmp(wFileData.cFileName, L"..") != 0) {
2356 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2357 if (v == NULL) {
2358 Py_DECREF(d);
2359 d = NULL;
2360 break;
2361 }
2362 if (PyList_Append(d, v) != 0) {
2363 Py_DECREF(v);
2364 Py_DECREF(d);
2365 d = NULL;
2366 break;
2367 }
2368 Py_DECREF(v);
2369 }
2370 Py_BEGIN_ALLOW_THREADS
2371 result = FindNextFileW(hFindFile, &wFileData);
2372 Py_END_ALLOW_THREADS
2373 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2374 it got to the end of the directory. */
2375 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2376 Py_DECREF(d);
2377 win32_error_unicode("FindNextFileW", wnamebuf);
2378 FindClose(hFindFile);
2379 free(wnamebuf);
2380 return NULL;
2381 }
2382 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002383
Victor Stinner8c62be82010-05-06 00:08:46 +00002384 if (FindClose(hFindFile) == FALSE) {
2385 Py_DECREF(d);
2386 win32_error_unicode("FindClose", wnamebuf);
2387 free(wnamebuf);
2388 return NULL;
2389 }
2390 free(wnamebuf);
2391 return d;
2392 }
2393 /* Drop the argument parsing error as narrow strings
2394 are also valid. */
2395 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002396
Victor Stinner8c62be82010-05-06 00:08:46 +00002397 if (!PyArg_ParseTuple(args, "O&:listdir",
2398 PyUnicode_FSConverter, &opath))
2399 return NULL;
2400 if (PyBytes_GET_SIZE(opath)+1 > MAX_PATH) {
2401 PyErr_SetString(PyExc_ValueError, "path too long");
2402 Py_DECREF(opath);
2403 return NULL;
2404 }
2405 strcpy(namebuf, PyBytes_AsString(opath));
2406 len = PyObject_Size(opath);
2407 if (len > 0) {
2408 char ch = namebuf[len-1];
2409 if (ch != SEP && ch != ALTSEP && ch != ':')
2410 namebuf[len++] = '/';
2411 strcpy(namebuf + len, "*.*");
2412 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002413
Victor Stinner8c62be82010-05-06 00:08:46 +00002414 if ((d = PyList_New(0)) == NULL)
2415 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002416
Victor Stinner8c62be82010-05-06 00:08:46 +00002417 hFindFile = FindFirstFile(namebuf, &FileData);
2418 if (hFindFile == INVALID_HANDLE_VALUE) {
2419 int error = GetLastError();
2420 if (error == ERROR_FILE_NOT_FOUND)
2421 return d;
2422 Py_DECREF(d);
2423 return win32_error("FindFirstFile", namebuf);
2424 }
2425 do {
2426 /* Skip over . and .. */
2427 if (strcmp(FileData.cFileName, ".") != 0 &&
2428 strcmp(FileData.cFileName, "..") != 0) {
2429 v = PyBytes_FromString(FileData.cFileName);
2430 if (v == NULL) {
2431 Py_DECREF(d);
2432 d = NULL;
2433 break;
2434 }
2435 if (PyList_Append(d, v) != 0) {
2436 Py_DECREF(v);
2437 Py_DECREF(d);
2438 d = NULL;
2439 break;
2440 }
2441 Py_DECREF(v);
2442 }
2443 Py_BEGIN_ALLOW_THREADS
2444 result = FindNextFile(hFindFile, &FileData);
2445 Py_END_ALLOW_THREADS
2446 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2447 it got to the end of the directory. */
2448 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2449 Py_DECREF(d);
2450 win32_error("FindNextFile", namebuf);
2451 FindClose(hFindFile);
2452 return NULL;
2453 }
2454 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002455
Victor Stinner8c62be82010-05-06 00:08:46 +00002456 if (FindClose(hFindFile) == FALSE) {
2457 Py_DECREF(d);
2458 return win32_error("FindClose", namebuf);
2459 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002460
Victor Stinner8c62be82010-05-06 00:08:46 +00002461 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002462
Tim Peters0bb44a42000-09-15 07:44:49 +00002463#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002464
2465#ifndef MAX_PATH
2466#define MAX_PATH CCHMAXPATH
2467#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002468 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002469 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002470 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002471 PyObject *d, *v;
2472 char namebuf[MAX_PATH+5];
2473 HDIR hdir = 1;
2474 ULONG srchcnt = 1;
2475 FILEFINDBUF3 ep;
2476 APIRET rc;
2477
Victor Stinner8c62be82010-05-06 00:08:46 +00002478 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002479 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002480 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002481 name = PyBytes_AsString(oname);
2482 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002483 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002484 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002485 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002486 return NULL;
2487 }
2488 strcpy(namebuf, name);
2489 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002490 if (*pt == ALTSEP)
2491 *pt = SEP;
2492 if (namebuf[len-1] != SEP)
2493 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002494 strcpy(namebuf + len, "*.*");
2495
Neal Norwitz6c913782007-10-14 03:23:09 +00002496 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002497 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002498 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002499 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002500
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002501 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2502 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002503 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002504 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2505 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2506 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002507
2508 if (rc != NO_ERROR) {
2509 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002510 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002511 }
2512
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002513 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002514 do {
2515 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002516 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002517 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002518
2519 strcpy(namebuf, ep.achName);
2520
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002521 /* Leave Case of Name Alone -- In Native Form */
2522 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002523
Christian Heimes72b710a2008-05-26 13:28:38 +00002524 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002525 if (v == NULL) {
2526 Py_DECREF(d);
2527 d = NULL;
2528 break;
2529 }
2530 if (PyList_Append(d, v) != 0) {
2531 Py_DECREF(v);
2532 Py_DECREF(d);
2533 d = NULL;
2534 break;
2535 }
2536 Py_DECREF(v);
2537 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2538 }
2539
Victor Stinnerdcb24032010-04-22 12:08:36 +00002540 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002541 return d;
2542#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002543 PyObject *oname;
2544 char *name;
2545 PyObject *d, *v;
2546 DIR *dirp;
2547 struct dirent *ep;
2548 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002549
Victor Stinner8c62be82010-05-06 00:08:46 +00002550 errno = 0;
2551 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2552 arg_is_unicode = 0;
2553 PyErr_Clear();
2554 }
2555 if (!PyArg_ParseTuple(args, "O&:listdir", PyUnicode_FSConverter, &oname))
2556 return NULL;
2557 name = PyBytes_AsString(oname);
2558 if ((dirp = opendir(name)) == NULL) {
2559 return posix_error_with_allocated_filename(oname);
2560 }
2561 if ((d = PyList_New(0)) == NULL) {
2562 closedir(dirp);
2563 Py_DECREF(oname);
2564 return NULL;
2565 }
2566 for (;;) {
2567 errno = 0;
2568 Py_BEGIN_ALLOW_THREADS
2569 ep = readdir(dirp);
2570 Py_END_ALLOW_THREADS
2571 if (ep == NULL) {
2572 if (errno == 0) {
2573 break;
2574 } else {
2575 closedir(dirp);
2576 Py_DECREF(d);
2577 return posix_error_with_allocated_filename(oname);
2578 }
2579 }
2580 if (ep->d_name[0] == '.' &&
2581 (NAMLEN(ep) == 1 ||
2582 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2583 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002584 if (arg_is_unicode)
2585 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2586 else
2587 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002588 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002589 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002590 break;
2591 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002592 if (PyList_Append(d, v) != 0) {
2593 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002594 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002595 break;
2596 }
2597 Py_DECREF(v);
2598 }
2599 closedir(dirp);
2600 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002601
Victor Stinner8c62be82010-05-06 00:08:46 +00002602 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002603
Tim Peters0bb44a42000-09-15 07:44:49 +00002604#endif /* which OS */
2605} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002606
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002607#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002608/* A helper function for abspath on win32 */
2609static PyObject *
2610posix__getfullpathname(PyObject *self, PyObject *args)
2611{
Victor Stinner8c62be82010-05-06 00:08:46 +00002612 PyObject *opath;
2613 char *path;
2614 char outbuf[MAX_PATH*2];
2615 char *temp;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002616#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002617 PyUnicodeObject *po;
2618 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2619 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2620 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2621 Py_UNICODE *wtemp;
2622 DWORD result;
2623 PyObject *v;
2624 result = GetFullPathNameW(wpath,
2625 sizeof(woutbuf)/sizeof(woutbuf[0]),
2626 woutbuf, &wtemp);
2627 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2628 woutbufp = malloc(result * sizeof(Py_UNICODE));
2629 if (!woutbufp)
2630 return PyErr_NoMemory();
2631 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2632 }
2633 if (result)
2634 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2635 else
2636 v = win32_error_unicode("GetFullPathNameW", wpath);
2637 if (woutbufp != woutbuf)
2638 free(woutbufp);
2639 return v;
2640 }
2641 /* Drop the argument parsing error as narrow strings
2642 are also valid. */
2643 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002644
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002645#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002646 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2647 PyUnicode_FSConverter, &opath))
2648 return NULL;
2649 path = PyBytes_AsString(opath);
2650 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2651 outbuf, &temp)) {
2652 win32_error("GetFullPathName", path);
2653 Py_DECREF(opath);
2654 return NULL;
2655 }
2656 Py_DECREF(opath);
2657 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2658 return PyUnicode_Decode(outbuf, strlen(outbuf),
2659 Py_FileSystemDefaultEncoding, NULL);
2660 }
2661 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002662} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00002663
2664/* A helper function for samepath on windows */
2665static PyObject *
2666posix__getfinalpathname(PyObject *self, PyObject *args)
2667{
2668 HANDLE hFile;
2669 int buf_size;
2670 wchar_t *target_path;
2671 int result_length;
2672 PyObject *result;
2673 wchar_t *path;
2674
2675 if (!PyArg_ParseTuple(args, "u|:_getfullpathname", &path)) {
2676 return NULL;
2677 }
2678
2679 if(!check_GetFinalPathNameByHandle()) {
2680 /* If the OS doesn't have GetFinalPathNameByHandle, return a
2681 NotImplementedError. */
2682 return PyErr_Format(PyExc_NotImplementedError,
2683 "GetFinalPathNameByHandle not available on this platform");
2684 }
2685
2686 hFile = CreateFileW(
2687 path,
2688 0, /* desired access */
2689 0, /* share mode */
2690 NULL, /* security attributes */
2691 OPEN_EXISTING,
2692 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
2693 FILE_FLAG_BACKUP_SEMANTICS,
2694 NULL);
2695
2696 if(hFile == INVALID_HANDLE_VALUE) {
2697 return win32_error_unicode("GetFinalPathNamyByHandle", path);
Brian Curtin74e45612010-07-09 15:58:59 +00002698 return PyErr_Format(PyExc_RuntimeError,
2699 "Could not get a handle to file.");
Brian Curtind40e6f72010-07-08 21:39:08 +00002700 }
2701
2702 /* We have a good handle to the target, use it to determine the
2703 target path name. */
2704 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
2705
2706 if(!buf_size)
2707 return win32_error_unicode("GetFinalPathNameByHandle", path);
2708
2709 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
2710 if(!target_path)
2711 return PyErr_NoMemory();
2712
2713 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
2714 buf_size, VOLUME_NAME_DOS);
2715 if(!result_length)
2716 return win32_error_unicode("GetFinalPathNamyByHandle", path);
2717
2718 if(!CloseHandle(hFile))
2719 return win32_error_unicode("GetFinalPathNameByHandle", path);
2720
2721 target_path[result_length] = 0;
2722 result = PyUnicode_FromUnicode(target_path, result_length);
2723 free(target_path);
2724 return result;
2725
2726} /* end of posix__getfinalpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002727#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002728
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002729PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002730"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002731Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002732
Barry Warsaw53699e91996-12-10 23:23:01 +00002733static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002734posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002735{
Victor Stinner8c62be82010-05-06 00:08:46 +00002736 int res;
2737 PyObject *opath;
2738 char *path;
2739 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002740
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002741#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002742 PyUnicodeObject *po;
2743 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2744 Py_BEGIN_ALLOW_THREADS
2745 /* PyUnicode_AS_UNICODE OK without thread lock as
2746 it is a simple dereference. */
2747 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2748 Py_END_ALLOW_THREADS
2749 if (!res)
2750 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2751 Py_INCREF(Py_None);
2752 return Py_None;
2753 }
2754 /* Drop the argument parsing error as narrow strings
2755 are also valid. */
2756 PyErr_Clear();
2757 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2758 PyUnicode_FSConverter, &opath, &mode))
2759 return NULL;
2760 path = PyBytes_AsString(opath);
2761 Py_BEGIN_ALLOW_THREADS
2762 /* PyUnicode_AS_UNICODE OK without thread lock as
2763 it is a simple dereference. */
2764 res = CreateDirectoryA(path, NULL);
2765 Py_END_ALLOW_THREADS
2766 if (!res) {
2767 win32_error("mkdir", path);
2768 Py_DECREF(opath);
2769 return NULL;
2770 }
2771 Py_DECREF(opath);
2772 Py_INCREF(Py_None);
2773 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002774#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002775
Victor Stinner8c62be82010-05-06 00:08:46 +00002776 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2777 PyUnicode_FSConverter, &opath, &mode))
2778 return NULL;
2779 path = PyBytes_AsString(opath);
2780 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002781#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00002782 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002783#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002784 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002785#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002786 Py_END_ALLOW_THREADS
2787 if (res < 0)
2788 return posix_error_with_allocated_filename(opath);
2789 Py_DECREF(opath);
2790 Py_INCREF(Py_None);
2791 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002792#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002793}
2794
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002795
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002796/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2797#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002798#include <sys/resource.h>
2799#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002800
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002801
2802#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002803PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002804"nice(inc) -> new_priority\n\n\
2805Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002806
Barry Warsaw53699e91996-12-10 23:23:01 +00002807static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002808posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002809{
Victor Stinner8c62be82010-05-06 00:08:46 +00002810 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002811
Victor Stinner8c62be82010-05-06 00:08:46 +00002812 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2813 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002814
Victor Stinner8c62be82010-05-06 00:08:46 +00002815 /* There are two flavours of 'nice': one that returns the new
2816 priority (as required by almost all standards out there) and the
2817 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2818 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002819
Victor Stinner8c62be82010-05-06 00:08:46 +00002820 If we are of the nice family that returns the new priority, we
2821 need to clear errno before the call, and check if errno is filled
2822 before calling posix_error() on a returnvalue of -1, because the
2823 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002824
Victor Stinner8c62be82010-05-06 00:08:46 +00002825 errno = 0;
2826 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002827#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00002828 if (value == 0)
2829 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002830#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002831 if (value == -1 && errno != 0)
2832 /* either nice() or getpriority() returned an error */
2833 return posix_error();
2834 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002835}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002836#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002837
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002838PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002839"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002840Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002841
Barry Warsaw53699e91996-12-10 23:23:01 +00002842static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002843posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002844{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002845#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002846 PyObject *o1, *o2;
2847 char *p1, *p2;
2848 BOOL result;
2849 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2850 goto error;
2851 if (!convert_to_unicode(&o1))
2852 goto error;
2853 if (!convert_to_unicode(&o2)) {
2854 Py_DECREF(o1);
2855 goto error;
2856 }
2857 Py_BEGIN_ALLOW_THREADS
2858 result = MoveFileW(PyUnicode_AsUnicode(o1),
2859 PyUnicode_AsUnicode(o2));
2860 Py_END_ALLOW_THREADS
2861 Py_DECREF(o1);
2862 Py_DECREF(o2);
2863 if (!result)
2864 return win32_error("rename", NULL);
2865 Py_INCREF(Py_None);
2866 return Py_None;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002867error:
Victor Stinner8c62be82010-05-06 00:08:46 +00002868 PyErr_Clear();
2869 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2870 return NULL;
2871 Py_BEGIN_ALLOW_THREADS
2872 result = MoveFileA(p1, p2);
2873 Py_END_ALLOW_THREADS
2874 if (!result)
2875 return win32_error("rename", NULL);
2876 Py_INCREF(Py_None);
2877 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002878#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002879 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002880#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002881}
2882
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002883
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002884PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002885"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002886Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002887
Barry Warsaw53699e91996-12-10 23:23:01 +00002888static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002889posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002890{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002891#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002892 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002893#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002894 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002895#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002896}
2897
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002898
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002899PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002900"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002901Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002902
Barry Warsaw53699e91996-12-10 23:23:01 +00002903static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002904posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002905{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002906#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00002907 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002908#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002909 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002910#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002911}
2912
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002913
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002914#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002915PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002916"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002917Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002918
Barry Warsaw53699e91996-12-10 23:23:01 +00002919static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002920posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002921{
Victor Stinner8c62be82010-05-06 00:08:46 +00002922 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002923#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002924 wchar_t *command;
2925 if (!PyArg_ParseTuple(args, "u:system", &command))
2926 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00002927
Victor Stinner8c62be82010-05-06 00:08:46 +00002928 Py_BEGIN_ALLOW_THREADS
2929 sts = _wsystem(command);
2930 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00002931#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002932 PyObject *command_obj;
2933 char *command;
2934 if (!PyArg_ParseTuple(args, "O&:system",
2935 PyUnicode_FSConverter, &command_obj))
2936 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00002937
Victor Stinner8c62be82010-05-06 00:08:46 +00002938 command = PyBytes_AsString(command_obj);
2939 Py_BEGIN_ALLOW_THREADS
2940 sts = system(command);
2941 Py_END_ALLOW_THREADS
2942 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00002943#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002944 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002945}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002946#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002947
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002948
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002949PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002950"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002951Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002952
Barry Warsaw53699e91996-12-10 23:23:01 +00002953static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002954posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002955{
Victor Stinner8c62be82010-05-06 00:08:46 +00002956 int i;
2957 if (!PyArg_ParseTuple(args, "i:umask", &i))
2958 return NULL;
2959 i = (int)umask(i);
2960 if (i < 0)
2961 return posix_error();
2962 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002963}
2964
Brian Curtind40e6f72010-07-08 21:39:08 +00002965#ifdef MS_WINDOWS
2966
2967/* override the default DeleteFileW behavior so that directory
2968symlinks can be removed with this function, the same as with
2969Unix symlinks */
2970BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
2971{
2972 WIN32_FILE_ATTRIBUTE_DATA info;
2973 WIN32_FIND_DATAW find_data;
2974 HANDLE find_data_handle;
2975 int is_directory = 0;
2976 int is_link = 0;
2977
2978 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
2979 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
2980
2981 /* Get WIN32_FIND_DATA structure for the path to determine if
2982 it is a symlink */
2983 if(is_directory &&
2984 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
2985 find_data_handle = FindFirstFileW(lpFileName, &find_data);
2986
2987 if(find_data_handle != INVALID_HANDLE_VALUE) {
2988 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
2989 FindClose(find_data_handle);
2990 }
2991 }
2992 }
2993
2994 if (is_directory && is_link)
2995 return RemoveDirectoryW(lpFileName);
2996
2997 return DeleteFileW(lpFileName);
2998}
2999#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003000
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003001PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003002"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003003Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003004
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003005PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003006"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003007Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003008
Barry Warsaw53699e91996-12-10 23:23:01 +00003009static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003010posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003011{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003012#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003013 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3014 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003015#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003016 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003017#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003018}
3019
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003020
Guido van Rossumb6775db1994-08-01 11:34:53 +00003021#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003022PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003023"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003024Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003025
Barry Warsaw53699e91996-12-10 23:23:01 +00003026static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003027posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003028{
Victor Stinner8c62be82010-05-06 00:08:46 +00003029 struct utsname u;
3030 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003031
Victor Stinner8c62be82010-05-06 00:08:46 +00003032 Py_BEGIN_ALLOW_THREADS
3033 res = uname(&u);
3034 Py_END_ALLOW_THREADS
3035 if (res < 0)
3036 return posix_error();
3037 return Py_BuildValue("(sssss)",
3038 u.sysname,
3039 u.nodename,
3040 u.release,
3041 u.version,
3042 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003043}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003044#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003045
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003046static int
3047extract_time(PyObject *t, long* sec, long* usec)
3048{
Victor Stinner8c62be82010-05-06 00:08:46 +00003049 long intval;
3050 if (PyFloat_Check(t)) {
3051 double tval = PyFloat_AsDouble(t);
3052 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
3053 if (!intobj)
3054 return -1;
3055 intval = PyLong_AsLong(intobj);
3056 Py_DECREF(intobj);
3057 if (intval == -1 && PyErr_Occurred())
3058 return -1;
3059 *sec = intval;
3060 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
3061 if (*usec < 0)
3062 /* If rounding gave us a negative number,
3063 truncate. */
3064 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00003065 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003066 }
3067 intval = PyLong_AsLong(t);
3068 if (intval == -1 && PyErr_Occurred())
3069 return -1;
3070 *sec = intval;
3071 *usec = 0;
3072 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003073}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003074
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003075PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00003076"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00003077utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00003078Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003079second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003080
Barry Warsaw53699e91996-12-10 23:23:01 +00003081static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003082posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003083{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003084#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003085 PyObject *arg;
3086 PyUnicodeObject *obwpath;
3087 wchar_t *wpath = NULL;
3088 PyObject *oapath;
3089 char *apath;
3090 HANDLE hFile;
3091 long atimesec, mtimesec, ausec, musec;
3092 FILETIME atime, mtime;
3093 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003094
Victor Stinner8c62be82010-05-06 00:08:46 +00003095 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
3096 wpath = PyUnicode_AS_UNICODE(obwpath);
3097 Py_BEGIN_ALLOW_THREADS
3098 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3099 NULL, OPEN_EXISTING,
3100 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3101 Py_END_ALLOW_THREADS
3102 if (hFile == INVALID_HANDLE_VALUE)
3103 return win32_error_unicode("utime", wpath);
3104 } else
3105 /* Drop the argument parsing error as narrow strings
3106 are also valid. */
3107 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003108
Victor Stinner8c62be82010-05-06 00:08:46 +00003109 if (!wpath) {
3110 if (!PyArg_ParseTuple(args, "O&O:utime",
3111 PyUnicode_FSConverter, &oapath, &arg))
3112 return NULL;
3113 apath = PyBytes_AsString(oapath);
3114 Py_BEGIN_ALLOW_THREADS
3115 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3116 NULL, OPEN_EXISTING,
3117 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3118 Py_END_ALLOW_THREADS
3119 if (hFile == INVALID_HANDLE_VALUE) {
3120 win32_error("utime", apath);
3121 Py_DECREF(oapath);
3122 return NULL;
3123 }
3124 Py_DECREF(oapath);
3125 }
3126
3127 if (arg == Py_None) {
3128 SYSTEMTIME now;
3129 GetSystemTime(&now);
3130 if (!SystemTimeToFileTime(&now, &mtime) ||
3131 !SystemTimeToFileTime(&now, &atime)) {
3132 win32_error("utime", NULL);
3133 goto done;
3134 }
3135 }
3136 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3137 PyErr_SetString(PyExc_TypeError,
3138 "utime() arg 2 must be a tuple (atime, mtime)");
3139 goto done;
3140 }
3141 else {
3142 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3143 &atimesec, &ausec) == -1)
3144 goto done;
3145 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3146 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3147 &mtimesec, &musec) == -1)
3148 goto done;
3149 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3150 }
3151 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3152 /* Avoid putting the file name into the error here,
3153 as that may confuse the user into believing that
3154 something is wrong with the file, when it also
3155 could be the time stamp that gives a problem. */
3156 win32_error("utime", NULL);
3157 }
3158 Py_INCREF(Py_None);
3159 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003160done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003161 CloseHandle(hFile);
3162 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003163#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003164
Victor Stinner8c62be82010-05-06 00:08:46 +00003165 PyObject *opath;
3166 char *path;
3167 long atime, mtime, ausec, musec;
3168 int res;
3169 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003170
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003171#if defined(HAVE_UTIMES)
Victor Stinner8c62be82010-05-06 00:08:46 +00003172 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003173#define ATIME buf[0].tv_sec
3174#define MTIME buf[1].tv_sec
3175#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003176/* XXX should define struct utimbuf instead, above */
Victor Stinner8c62be82010-05-06 00:08:46 +00003177 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003178#define ATIME buf.actime
3179#define MTIME buf.modtime
3180#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003181#else /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003182 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003183#define ATIME buf[0]
3184#define MTIME buf[1]
3185#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003186#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003187
Mark Hammond817c9292003-12-03 01:22:38 +00003188
Victor Stinner8c62be82010-05-06 00:08:46 +00003189 if (!PyArg_ParseTuple(args, "O&O:utime",
3190 PyUnicode_FSConverter, &opath, &arg))
3191 return NULL;
3192 path = PyBytes_AsString(opath);
3193 if (arg == Py_None) {
3194 /* optional time values not given */
3195 Py_BEGIN_ALLOW_THREADS
3196 res = utime(path, NULL);
3197 Py_END_ALLOW_THREADS
3198 }
3199 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3200 PyErr_SetString(PyExc_TypeError,
3201 "utime() arg 2 must be a tuple (atime, mtime)");
3202 Py_DECREF(opath);
3203 return NULL;
3204 }
3205 else {
3206 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3207 &atime, &ausec) == -1) {
3208 Py_DECREF(opath);
3209 return NULL;
3210 }
3211 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3212 &mtime, &musec) == -1) {
3213 Py_DECREF(opath);
3214 return NULL;
3215 }
3216 ATIME = atime;
3217 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003218#ifdef HAVE_UTIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00003219 buf[0].tv_usec = ausec;
3220 buf[1].tv_usec = musec;
3221 Py_BEGIN_ALLOW_THREADS
3222 res = utimes(path, buf);
3223 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003224#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003225 Py_BEGIN_ALLOW_THREADS
3226 res = utime(path, UTIME_ARG);
3227 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003228#endif /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003229 }
3230 if (res < 0) {
3231 return posix_error_with_allocated_filename(opath);
3232 }
3233 Py_DECREF(opath);
3234 Py_INCREF(Py_None);
3235 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003236#undef UTIME_ARG
3237#undef ATIME
3238#undef MTIME
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003239#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003240}
3241
Guido van Rossum85e3b011991-06-03 12:42:10 +00003242
Guido van Rossum3b066191991-06-04 19:40:25 +00003243/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003244
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003245PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003246"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003247Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003248
Barry Warsaw53699e91996-12-10 23:23:01 +00003249static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003250posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003251{
Victor Stinner8c62be82010-05-06 00:08:46 +00003252 int sts;
3253 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3254 return NULL;
3255 _exit(sts);
3256 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003257}
3258
Martin v. Löwis114619e2002-10-07 06:44:21 +00003259#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3260static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003261free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003262{
Victor Stinner8c62be82010-05-06 00:08:46 +00003263 Py_ssize_t i;
3264 for (i = 0; i < count; i++)
3265 PyMem_Free(array[i]);
3266 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003267}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003268
Antoine Pitrou69f71142009-05-24 21:25:49 +00003269static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003270int fsconvert_strdup(PyObject *o, char**out)
3271{
Victor Stinner8c62be82010-05-06 00:08:46 +00003272 PyObject *bytes;
3273 Py_ssize_t size;
3274 if (!PyUnicode_FSConverter(o, &bytes))
3275 return 0;
3276 size = PyBytes_GET_SIZE(bytes);
3277 *out = PyMem_Malloc(size+1);
3278 if (!*out)
3279 return 0;
3280 memcpy(*out, PyBytes_AsString(bytes), size+1);
3281 Py_DECREF(bytes);
3282 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003283}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003284#endif
3285
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003286
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003287#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003288PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003289"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003290Execute an executable path with arguments, replacing current process.\n\
3291\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003292 path: path of executable file\n\
3293 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003294
Barry Warsaw53699e91996-12-10 23:23:01 +00003295static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003296posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003297{
Victor Stinner8c62be82010-05-06 00:08:46 +00003298 PyObject *opath;
3299 char *path;
3300 PyObject *argv;
3301 char **argvlist;
3302 Py_ssize_t i, argc;
3303 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003304
Victor Stinner8c62be82010-05-06 00:08:46 +00003305 /* execv has two arguments: (path, argv), where
3306 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003307
Victor Stinner8c62be82010-05-06 00:08:46 +00003308 if (!PyArg_ParseTuple(args, "O&O:execv",
3309 PyUnicode_FSConverter,
3310 &opath, &argv))
3311 return NULL;
3312 path = PyBytes_AsString(opath);
3313 if (PyList_Check(argv)) {
3314 argc = PyList_Size(argv);
3315 getitem = PyList_GetItem;
3316 }
3317 else if (PyTuple_Check(argv)) {
3318 argc = PyTuple_Size(argv);
3319 getitem = PyTuple_GetItem;
3320 }
3321 else {
3322 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3323 Py_DECREF(opath);
3324 return NULL;
3325 }
3326 if (argc < 1) {
3327 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3328 Py_DECREF(opath);
3329 return NULL;
3330 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003331
Victor Stinner8c62be82010-05-06 00:08:46 +00003332 argvlist = PyMem_NEW(char *, argc+1);
3333 if (argvlist == NULL) {
3334 Py_DECREF(opath);
3335 return PyErr_NoMemory();
3336 }
3337 for (i = 0; i < argc; i++) {
3338 if (!fsconvert_strdup((*getitem)(argv, i),
3339 &argvlist[i])) {
3340 free_string_array(argvlist, i);
3341 PyErr_SetString(PyExc_TypeError,
3342 "execv() arg 2 must contain only strings");
3343 Py_DECREF(opath);
3344 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003345
Victor Stinner8c62be82010-05-06 00:08:46 +00003346 }
3347 }
3348 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003349
Victor Stinner8c62be82010-05-06 00:08:46 +00003350 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003351
Victor Stinner8c62be82010-05-06 00:08:46 +00003352 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003353
Victor Stinner8c62be82010-05-06 00:08:46 +00003354 free_string_array(argvlist, argc);
3355 Py_DECREF(opath);
3356 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003357}
3358
Victor Stinner13bb71c2010-04-23 21:41:56 +00003359static char**
3360parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3361{
Victor Stinner8c62be82010-05-06 00:08:46 +00003362 char **envlist;
3363 Py_ssize_t i, pos, envc;
3364 PyObject *keys=NULL, *vals=NULL;
3365 PyObject *key, *val, *key2, *val2;
3366 char *p, *k, *v;
3367 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003368
Victor Stinner8c62be82010-05-06 00:08:46 +00003369 i = PyMapping_Size(env);
3370 if (i < 0)
3371 return NULL;
3372 envlist = PyMem_NEW(char *, i + 1);
3373 if (envlist == NULL) {
3374 PyErr_NoMemory();
3375 return NULL;
3376 }
3377 envc = 0;
3378 keys = PyMapping_Keys(env);
3379 vals = PyMapping_Values(env);
3380 if (!keys || !vals)
3381 goto error;
3382 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3383 PyErr_Format(PyExc_TypeError,
3384 "env.keys() or env.values() is not a list");
3385 goto error;
3386 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003387
Victor Stinner8c62be82010-05-06 00:08:46 +00003388 for (pos = 0; pos < i; pos++) {
3389 key = PyList_GetItem(keys, pos);
3390 val = PyList_GetItem(vals, pos);
3391 if (!key || !val)
3392 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003393
Victor Stinner8c62be82010-05-06 00:08:46 +00003394 if (PyUnicode_FSConverter(key, &key2) == 0)
3395 goto error;
3396 if (PyUnicode_FSConverter(val, &val2) == 0) {
3397 Py_DECREF(key2);
3398 goto error;
3399 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003400
3401#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003402 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3403 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00003404#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003405 k = PyBytes_AsString(key2);
3406 v = PyBytes_AsString(val2);
3407 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003408
Victor Stinner8c62be82010-05-06 00:08:46 +00003409 p = PyMem_NEW(char, len);
3410 if (p == NULL) {
3411 PyErr_NoMemory();
3412 Py_DECREF(key2);
3413 Py_DECREF(val2);
3414 goto error;
3415 }
3416 PyOS_snprintf(p, len, "%s=%s", k, v);
3417 envlist[envc++] = p;
3418 Py_DECREF(key2);
3419 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003420#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003421 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003422#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003423 }
3424 Py_DECREF(vals);
3425 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003426
Victor Stinner8c62be82010-05-06 00:08:46 +00003427 envlist[envc] = 0;
3428 *envc_ptr = envc;
3429 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003430
3431error:
Victor Stinner8c62be82010-05-06 00:08:46 +00003432 Py_XDECREF(keys);
3433 Py_XDECREF(vals);
3434 while (--envc >= 0)
3435 PyMem_DEL(envlist[envc]);
3436 PyMem_DEL(envlist);
3437 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003438}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003439
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003440PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003441"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003442Execute a path with arguments and environment, replacing current process.\n\
3443\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003444 path: path of executable file\n\
3445 args: tuple or list of arguments\n\
3446 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003447
Barry Warsaw53699e91996-12-10 23:23:01 +00003448static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003449posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003450{
Victor Stinner8c62be82010-05-06 00:08:46 +00003451 PyObject *opath;
3452 char *path;
3453 PyObject *argv, *env;
3454 char **argvlist;
3455 char **envlist;
3456 Py_ssize_t i, argc, envc;
3457 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3458 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003459
Victor Stinner8c62be82010-05-06 00:08:46 +00003460 /* execve has three arguments: (path, argv, env), where
3461 argv is a list or tuple of strings and env is a dictionary
3462 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003463
Victor Stinner8c62be82010-05-06 00:08:46 +00003464 if (!PyArg_ParseTuple(args, "O&OO:execve",
3465 PyUnicode_FSConverter,
3466 &opath, &argv, &env))
3467 return NULL;
3468 path = PyBytes_AsString(opath);
3469 if (PyList_Check(argv)) {
3470 argc = PyList_Size(argv);
3471 getitem = PyList_GetItem;
3472 }
3473 else if (PyTuple_Check(argv)) {
3474 argc = PyTuple_Size(argv);
3475 getitem = PyTuple_GetItem;
3476 }
3477 else {
3478 PyErr_SetString(PyExc_TypeError,
3479 "execve() arg 2 must be a tuple or list");
3480 goto fail_0;
3481 }
3482 if (!PyMapping_Check(env)) {
3483 PyErr_SetString(PyExc_TypeError,
3484 "execve() arg 3 must be a mapping object");
3485 goto fail_0;
3486 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003487
Victor Stinner8c62be82010-05-06 00:08:46 +00003488 argvlist = PyMem_NEW(char *, argc+1);
3489 if (argvlist == NULL) {
3490 PyErr_NoMemory();
3491 goto fail_0;
3492 }
3493 for (i = 0; i < argc; i++) {
3494 if (!fsconvert_strdup((*getitem)(argv, i),
3495 &argvlist[i]))
3496 {
3497 lastarg = i;
3498 goto fail_1;
3499 }
3500 }
3501 lastarg = argc;
3502 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003503
Victor Stinner8c62be82010-05-06 00:08:46 +00003504 envlist = parse_envlist(env, &envc);
3505 if (envlist == NULL)
3506 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003507
Victor Stinner8c62be82010-05-06 00:08:46 +00003508 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003509
Victor Stinner8c62be82010-05-06 00:08:46 +00003510 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003511
Victor Stinner8c62be82010-05-06 00:08:46 +00003512 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003513
Victor Stinner8c62be82010-05-06 00:08:46 +00003514 while (--envc >= 0)
3515 PyMem_DEL(envlist[envc]);
3516 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003517 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003518 free_string_array(argvlist, lastarg);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003519 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003520 Py_DECREF(opath);
3521 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003522}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003523#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003524
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003525
Guido van Rossuma1065681999-01-25 23:20:23 +00003526#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003527PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003528"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003529Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003530\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003531 mode: mode of process creation\n\
3532 path: path of executable file\n\
3533 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003534
3535static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003536posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003537{
Victor Stinner8c62be82010-05-06 00:08:46 +00003538 PyObject *opath;
3539 char *path;
3540 PyObject *argv;
3541 char **argvlist;
3542 int mode, i;
3543 Py_ssize_t argc;
3544 Py_intptr_t spawnval;
3545 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003546
Victor Stinner8c62be82010-05-06 00:08:46 +00003547 /* spawnv has three arguments: (mode, path, argv), where
3548 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003549
Victor Stinner8c62be82010-05-06 00:08:46 +00003550 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3551 PyUnicode_FSConverter,
3552 &opath, &argv))
3553 return NULL;
3554 path = PyBytes_AsString(opath);
3555 if (PyList_Check(argv)) {
3556 argc = PyList_Size(argv);
3557 getitem = PyList_GetItem;
3558 }
3559 else if (PyTuple_Check(argv)) {
3560 argc = PyTuple_Size(argv);
3561 getitem = PyTuple_GetItem;
3562 }
3563 else {
3564 PyErr_SetString(PyExc_TypeError,
3565 "spawnv() arg 2 must be a tuple or list");
3566 Py_DECREF(opath);
3567 return NULL;
3568 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003569
Victor Stinner8c62be82010-05-06 00:08:46 +00003570 argvlist = PyMem_NEW(char *, argc+1);
3571 if (argvlist == NULL) {
3572 Py_DECREF(opath);
3573 return PyErr_NoMemory();
3574 }
3575 for (i = 0; i < argc; i++) {
3576 if (!fsconvert_strdup((*getitem)(argv, i),
3577 &argvlist[i])) {
3578 free_string_array(argvlist, i);
3579 PyErr_SetString(
3580 PyExc_TypeError,
3581 "spawnv() arg 2 must contain only strings");
3582 Py_DECREF(opath);
3583 return NULL;
3584 }
3585 }
3586 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003587
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003588#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003589 Py_BEGIN_ALLOW_THREADS
3590 spawnval = spawnv(mode, path, argvlist);
3591 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003592#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003593 if (mode == _OLD_P_OVERLAY)
3594 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003595
Victor Stinner8c62be82010-05-06 00:08:46 +00003596 Py_BEGIN_ALLOW_THREADS
3597 spawnval = _spawnv(mode, path, argvlist);
3598 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003599#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003600
Victor Stinner8c62be82010-05-06 00:08:46 +00003601 free_string_array(argvlist, argc);
3602 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003603
Victor Stinner8c62be82010-05-06 00:08:46 +00003604 if (spawnval == -1)
3605 return posix_error();
3606 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003607#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003608 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003609#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003610 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003611#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003612}
3613
3614
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003615PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003616"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003617Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003618\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003619 mode: mode of process creation\n\
3620 path: path of executable file\n\
3621 args: tuple or list of arguments\n\
3622 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003623
3624static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003625posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003626{
Victor Stinner8c62be82010-05-06 00:08:46 +00003627 PyObject *opath;
3628 char *path;
3629 PyObject *argv, *env;
3630 char **argvlist;
3631 char **envlist;
3632 PyObject *res = NULL;
3633 int mode, envc;
3634 Py_ssize_t argc, i;
3635 Py_intptr_t spawnval;
3636 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3637 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003638
Victor Stinner8c62be82010-05-06 00:08:46 +00003639 /* spawnve has four arguments: (mode, path, argv, env), where
3640 argv is a list or tuple of strings and env is a dictionary
3641 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003642
Victor Stinner8c62be82010-05-06 00:08:46 +00003643 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3644 PyUnicode_FSConverter,
3645 &opath, &argv, &env))
3646 return NULL;
3647 path = PyBytes_AsString(opath);
3648 if (PyList_Check(argv)) {
3649 argc = PyList_Size(argv);
3650 getitem = PyList_GetItem;
3651 }
3652 else if (PyTuple_Check(argv)) {
3653 argc = PyTuple_Size(argv);
3654 getitem = PyTuple_GetItem;
3655 }
3656 else {
3657 PyErr_SetString(PyExc_TypeError,
3658 "spawnve() arg 2 must be a tuple or list");
3659 goto fail_0;
3660 }
3661 if (!PyMapping_Check(env)) {
3662 PyErr_SetString(PyExc_TypeError,
3663 "spawnve() arg 3 must be a mapping object");
3664 goto fail_0;
3665 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003666
Victor Stinner8c62be82010-05-06 00:08:46 +00003667 argvlist = PyMem_NEW(char *, argc+1);
3668 if (argvlist == NULL) {
3669 PyErr_NoMemory();
3670 goto fail_0;
3671 }
3672 for (i = 0; i < argc; i++) {
3673 if (!fsconvert_strdup((*getitem)(argv, i),
3674 &argvlist[i]))
3675 {
3676 lastarg = i;
3677 goto fail_1;
3678 }
3679 }
3680 lastarg = argc;
3681 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003682
Victor Stinner8c62be82010-05-06 00:08:46 +00003683 envlist = parse_envlist(env, &envc);
3684 if (envlist == NULL)
3685 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003686
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003687#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003688 Py_BEGIN_ALLOW_THREADS
3689 spawnval = spawnve(mode, path, argvlist, envlist);
3690 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003691#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003692 if (mode == _OLD_P_OVERLAY)
3693 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003694
Victor Stinner8c62be82010-05-06 00:08:46 +00003695 Py_BEGIN_ALLOW_THREADS
3696 spawnval = _spawnve(mode, path, argvlist, envlist);
3697 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003698#endif
Tim Peters25059d32001-12-07 20:35:43 +00003699
Victor Stinner8c62be82010-05-06 00:08:46 +00003700 if (spawnval == -1)
3701 (void) posix_error();
3702 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003703#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003704 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003705#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003706 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003707#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003708
Victor Stinner8c62be82010-05-06 00:08:46 +00003709 while (--envc >= 0)
3710 PyMem_DEL(envlist[envc]);
3711 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003712 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003713 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003714 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003715 Py_DECREF(opath);
3716 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003717}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003718
3719/* OS/2 supports spawnvp & spawnvpe natively */
3720#if defined(PYOS_OS2)
3721PyDoc_STRVAR(posix_spawnvp__doc__,
3722"spawnvp(mode, file, args)\n\n\
3723Execute the program 'file' in a new process, using the environment\n\
3724search path to find the file.\n\
3725\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003726 mode: mode of process creation\n\
3727 file: executable file name\n\
3728 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003729
3730static PyObject *
3731posix_spawnvp(PyObject *self, PyObject *args)
3732{
Victor Stinner8c62be82010-05-06 00:08:46 +00003733 PyObject *opath;
3734 char *path;
3735 PyObject *argv;
3736 char **argvlist;
3737 int mode, i, argc;
3738 Py_intptr_t spawnval;
3739 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003740
Victor Stinner8c62be82010-05-06 00:08:46 +00003741 /* spawnvp has three arguments: (mode, path, argv), where
3742 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003743
Victor Stinner8c62be82010-05-06 00:08:46 +00003744 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3745 PyUnicode_FSConverter,
3746 &opath, &argv))
3747 return NULL;
3748 path = PyBytes_AsString(opath);
3749 if (PyList_Check(argv)) {
3750 argc = PyList_Size(argv);
3751 getitem = PyList_GetItem;
3752 }
3753 else if (PyTuple_Check(argv)) {
3754 argc = PyTuple_Size(argv);
3755 getitem = PyTuple_GetItem;
3756 }
3757 else {
3758 PyErr_SetString(PyExc_TypeError,
3759 "spawnvp() arg 2 must be a tuple or list");
3760 Py_DECREF(opath);
3761 return NULL;
3762 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003763
Victor Stinner8c62be82010-05-06 00:08:46 +00003764 argvlist = PyMem_NEW(char *, argc+1);
3765 if (argvlist == NULL) {
3766 Py_DECREF(opath);
3767 return PyErr_NoMemory();
3768 }
3769 for (i = 0; i < argc; i++) {
3770 if (!fsconvert_strdup((*getitem)(argv, i),
3771 &argvlist[i])) {
3772 free_string_array(argvlist, i);
3773 PyErr_SetString(
3774 PyExc_TypeError,
3775 "spawnvp() arg 2 must contain only strings");
3776 Py_DECREF(opath);
3777 return NULL;
3778 }
3779 }
3780 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003781
Victor Stinner8c62be82010-05-06 00:08:46 +00003782 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003783#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003784 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003785#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003786 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003787#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003788 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003789
Victor Stinner8c62be82010-05-06 00:08:46 +00003790 free_string_array(argvlist, argc);
3791 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003792
Victor Stinner8c62be82010-05-06 00:08:46 +00003793 if (spawnval == -1)
3794 return posix_error();
3795 else
3796 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003797}
3798
3799
3800PyDoc_STRVAR(posix_spawnvpe__doc__,
3801"spawnvpe(mode, file, args, env)\n\n\
3802Execute the program 'file' in a new process, using the environment\n\
3803search path to find the file.\n\
3804\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003805 mode: mode of process creation\n\
3806 file: executable file name\n\
3807 args: tuple or list of arguments\n\
3808 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003809
3810static PyObject *
3811posix_spawnvpe(PyObject *self, PyObject *args)
3812{
Victor Stinner8c62be82010-05-06 00:08:46 +00003813 PyObject *opath
3814 char *path;
3815 PyObject *argv, *env;
3816 char **argvlist;
3817 char **envlist;
3818 PyObject *res=NULL;
3819 int mode, i, argc, envc;
3820 Py_intptr_t spawnval;
3821 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3822 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003823
Victor Stinner8c62be82010-05-06 00:08:46 +00003824 /* spawnvpe has four arguments: (mode, path, argv, env), where
3825 argv is a list or tuple of strings and env is a dictionary
3826 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003827
Victor Stinner8c62be82010-05-06 00:08:46 +00003828 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3829 PyUnicode_FSConverter,
3830 &opath, &argv, &env))
3831 return NULL;
3832 path = PyBytes_AsString(opath);
3833 if (PyList_Check(argv)) {
3834 argc = PyList_Size(argv);
3835 getitem = PyList_GetItem;
3836 }
3837 else if (PyTuple_Check(argv)) {
3838 argc = PyTuple_Size(argv);
3839 getitem = PyTuple_GetItem;
3840 }
3841 else {
3842 PyErr_SetString(PyExc_TypeError,
3843 "spawnvpe() arg 2 must be a tuple or list");
3844 goto fail_0;
3845 }
3846 if (!PyMapping_Check(env)) {
3847 PyErr_SetString(PyExc_TypeError,
3848 "spawnvpe() arg 3 must be a mapping object");
3849 goto fail_0;
3850 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003851
Victor Stinner8c62be82010-05-06 00:08:46 +00003852 argvlist = PyMem_NEW(char *, argc+1);
3853 if (argvlist == NULL) {
3854 PyErr_NoMemory();
3855 goto fail_0;
3856 }
3857 for (i = 0; i < argc; i++) {
3858 if (!fsconvert_strdup((*getitem)(argv, i),
3859 &argvlist[i]))
3860 {
3861 lastarg = i;
3862 goto fail_1;
3863 }
3864 }
3865 lastarg = argc;
3866 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003867
Victor Stinner8c62be82010-05-06 00:08:46 +00003868 envlist = parse_envlist(env, &envc);
3869 if (envlist == NULL)
3870 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003871
Victor Stinner8c62be82010-05-06 00:08:46 +00003872 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003873#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003874 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003875#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003876 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003877#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003878 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003879
Victor Stinner8c62be82010-05-06 00:08:46 +00003880 if (spawnval == -1)
3881 (void) posix_error();
3882 else
3883 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003884
Victor Stinner8c62be82010-05-06 00:08:46 +00003885 while (--envc >= 0)
3886 PyMem_DEL(envlist[envc]);
3887 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003888 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003889 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003890 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003891 Py_DECREF(opath);
3892 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003893}
3894#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003895#endif /* HAVE_SPAWNV */
3896
3897
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003898#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003899PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003900"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003901Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3902\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003903Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003904
3905static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003906posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003907{
Victor Stinner8c62be82010-05-06 00:08:46 +00003908 pid_t pid;
3909 int result = 0;
3910 _PyImport_AcquireLock();
3911 pid = fork1();
3912 if (pid == 0) {
3913 /* child: this clobbers and resets the import lock. */
3914 PyOS_AfterFork();
3915 } else {
3916 /* parent: release the import lock. */
3917 result = _PyImport_ReleaseLock();
3918 }
3919 if (pid == -1)
3920 return posix_error();
3921 if (result < 0) {
3922 /* Don't clobber the OSError if the fork failed. */
3923 PyErr_SetString(PyExc_RuntimeError,
3924 "not holding the import lock");
3925 return NULL;
3926 }
3927 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003928}
3929#endif
3930
3931
Guido van Rossumad0ee831995-03-01 10:34:45 +00003932#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003933PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003934"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003935Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003936Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003937
Barry Warsaw53699e91996-12-10 23:23:01 +00003938static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003939posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003940{
Victor Stinner8c62be82010-05-06 00:08:46 +00003941 pid_t pid;
3942 int result = 0;
3943 _PyImport_AcquireLock();
3944 pid = fork();
3945 if (pid == 0) {
3946 /* child: this clobbers and resets the import lock. */
3947 PyOS_AfterFork();
3948 } else {
3949 /* parent: release the import lock. */
3950 result = _PyImport_ReleaseLock();
3951 }
3952 if (pid == -1)
3953 return posix_error();
3954 if (result < 0) {
3955 /* Don't clobber the OSError if the fork failed. */
3956 PyErr_SetString(PyExc_RuntimeError,
3957 "not holding the import lock");
3958 return NULL;
3959 }
3960 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003961}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003962#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003963
Neal Norwitzb59798b2003-03-21 01:43:31 +00003964/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003965/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3966#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003967#define DEV_PTY_FILE "/dev/ptc"
3968#define HAVE_DEV_PTMX
3969#else
3970#define DEV_PTY_FILE "/dev/ptmx"
3971#endif
3972
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003973#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003974#ifdef HAVE_PTY_H
3975#include <pty.h>
3976#else
3977#ifdef HAVE_LIBUTIL_H
3978#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00003979#else
3980#ifdef HAVE_UTIL_H
3981#include <util.h>
3982#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003983#endif /* HAVE_LIBUTIL_H */
3984#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003985#ifdef HAVE_STROPTS_H
3986#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003987#endif
3988#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003989
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003990#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003991PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003992"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003993Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003994
3995static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003996posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003997{
Victor Stinner8c62be82010-05-06 00:08:46 +00003998 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003999#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004000 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004001#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004002#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004003 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004004#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00004005 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004006#endif
4007#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00004008
Thomas Wouters70c21a12000-07-14 14:28:33 +00004009#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004010 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
4011 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004012#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004013 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
4014 if (slave_name == NULL)
4015 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00004016
Victor Stinner8c62be82010-05-06 00:08:46 +00004017 slave_fd = open(slave_name, O_RDWR);
4018 if (slave_fd < 0)
4019 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004020#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004021 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
4022 if (master_fd < 0)
4023 return posix_error();
4024 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
4025 /* change permission of slave */
4026 if (grantpt(master_fd) < 0) {
4027 PyOS_setsig(SIGCHLD, sig_saved);
4028 return posix_error();
4029 }
4030 /* unlock slave */
4031 if (unlockpt(master_fd) < 0) {
4032 PyOS_setsig(SIGCHLD, sig_saved);
4033 return posix_error();
4034 }
4035 PyOS_setsig(SIGCHLD, sig_saved);
4036 slave_name = ptsname(master_fd); /* get name of slave */
4037 if (slave_name == NULL)
4038 return posix_error();
4039 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
4040 if (slave_fd < 0)
4041 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004042#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004043 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
4044 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00004045#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00004046 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00004047#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004048#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00004049#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00004050
Victor Stinner8c62be82010-05-06 00:08:46 +00004051 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00004052
Fred Drake8cef4cf2000-06-28 16:40:38 +00004053}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004054#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004055
4056#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004057PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004058"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00004059Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
4060Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004061To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004062
4063static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004064posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004065{
Victor Stinner8c62be82010-05-06 00:08:46 +00004066 int master_fd = -1, result = 0;
4067 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00004068
Victor Stinner8c62be82010-05-06 00:08:46 +00004069 _PyImport_AcquireLock();
4070 pid = forkpty(&master_fd, NULL, NULL, NULL);
4071 if (pid == 0) {
4072 /* child: this clobbers and resets the import lock. */
4073 PyOS_AfterFork();
4074 } else {
4075 /* parent: release the import lock. */
4076 result = _PyImport_ReleaseLock();
4077 }
4078 if (pid == -1)
4079 return posix_error();
4080 if (result < 0) {
4081 /* Don't clobber the OSError if the fork failed. */
4082 PyErr_SetString(PyExc_RuntimeError,
4083 "not holding the import lock");
4084 return NULL;
4085 }
4086 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004087}
4088#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004089
Guido van Rossumad0ee831995-03-01 10:34:45 +00004090#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004091PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004092"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004093Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004094
Barry Warsaw53699e91996-12-10 23:23:01 +00004095static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004096posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004097{
Victor Stinner8c62be82010-05-06 00:08:46 +00004098 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004099}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004100#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004101
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004102
Guido van Rossumad0ee831995-03-01 10:34:45 +00004103#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004104PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004105"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004106Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004107
Barry Warsaw53699e91996-12-10 23:23:01 +00004108static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004109posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004110{
Victor Stinner8c62be82010-05-06 00:08:46 +00004111 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004112}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004113#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004114
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004115
Guido van Rossumad0ee831995-03-01 10:34:45 +00004116#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004117PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004118"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004119Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004120
Barry Warsaw53699e91996-12-10 23:23:01 +00004121static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004122posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004123{
Victor Stinner8c62be82010-05-06 00:08:46 +00004124 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004125}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004126#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004127
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004128
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004129PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004130"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004131Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004132
Barry Warsaw53699e91996-12-10 23:23:01 +00004133static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004134posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004135{
Victor Stinner8c62be82010-05-06 00:08:46 +00004136 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004137}
4138
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004139
Fred Drakec9680921999-12-13 16:37:25 +00004140#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004141PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004142"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004143Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004144
4145static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004146posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004147{
4148 PyObject *result = NULL;
4149
Fred Drakec9680921999-12-13 16:37:25 +00004150#ifdef NGROUPS_MAX
4151#define MAX_GROUPS NGROUPS_MAX
4152#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004153 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004154#define MAX_GROUPS 64
4155#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004156 gid_t grouplist[MAX_GROUPS];
4157 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004158
Victor Stinner8c62be82010-05-06 00:08:46 +00004159 n = getgroups(MAX_GROUPS, grouplist);
4160 if (n < 0)
4161 posix_error();
4162 else {
4163 result = PyList_New(n);
4164 if (result != NULL) {
4165 int i;
4166 for (i = 0; i < n; ++i) {
4167 PyObject *o = PyLong_FromLong((long)grouplist[i]);
4168 if (o == NULL) {
4169 Py_DECREF(result);
4170 result = NULL;
4171 break;
Fred Drakec9680921999-12-13 16:37:25 +00004172 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004173 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004174 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004175 }
4176 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004177
Fred Drakec9680921999-12-13 16:37:25 +00004178 return result;
4179}
4180#endif
4181
Antoine Pitroub7572f02009-12-02 20:46:48 +00004182#ifdef HAVE_INITGROUPS
4183PyDoc_STRVAR(posix_initgroups__doc__,
4184"initgroups(username, gid) -> None\n\n\
4185Call the system initgroups() to initialize the group access list with all of\n\
4186the groups of which the specified username is a member, plus the specified\n\
4187group id.");
4188
4189static PyObject *
4190posix_initgroups(PyObject *self, PyObject *args)
4191{
Victor Stinner8c62be82010-05-06 00:08:46 +00004192 char *username;
4193 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004194
Victor Stinner8c62be82010-05-06 00:08:46 +00004195 if (!PyArg_ParseTuple(args, "sl:initgroups", &username, &gid))
4196 return NULL;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004197
Victor Stinner8c62be82010-05-06 00:08:46 +00004198 if (initgroups(username, (gid_t) gid) == -1)
4199 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004200
Victor Stinner8c62be82010-05-06 00:08:46 +00004201 Py_INCREF(Py_None);
4202 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004203}
4204#endif
4205
Martin v. Löwis606edc12002-06-13 21:09:11 +00004206#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004207PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004208"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004209Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004210
4211static PyObject *
4212posix_getpgid(PyObject *self, PyObject *args)
4213{
Victor Stinner8c62be82010-05-06 00:08:46 +00004214 pid_t pid, pgid;
4215 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
4216 return NULL;
4217 pgid = getpgid(pid);
4218 if (pgid < 0)
4219 return posix_error();
4220 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004221}
4222#endif /* HAVE_GETPGID */
4223
4224
Guido van Rossumb6775db1994-08-01 11:34:53 +00004225#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004226PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004227"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004228Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004229
Barry Warsaw53699e91996-12-10 23:23:01 +00004230static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004231posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004232{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004233#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004234 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004235#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004236 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004237#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004238}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004239#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004240
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004241
Guido van Rossumb6775db1994-08-01 11:34:53 +00004242#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004243PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004244"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00004245Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004246
Barry Warsaw53699e91996-12-10 23:23:01 +00004247static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004248posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004249{
Guido van Rossum64933891994-10-20 21:56:42 +00004250#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004251 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004252#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004253 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004254#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004255 return posix_error();
4256 Py_INCREF(Py_None);
4257 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004258}
4259
Guido van Rossumb6775db1994-08-01 11:34:53 +00004260#endif /* HAVE_SETPGRP */
4261
Guido van Rossumad0ee831995-03-01 10:34:45 +00004262#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004263PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004264"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004265Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004266
Barry Warsaw53699e91996-12-10 23:23:01 +00004267static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004268posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004269{
Victor Stinner8c62be82010-05-06 00:08:46 +00004270 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004271}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004272#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004273
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004274
Fred Drake12c6e2d1999-12-14 21:25:03 +00004275#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004276PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004277"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004278Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004279
4280static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004281posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004282{
Victor Stinner8c62be82010-05-06 00:08:46 +00004283 PyObject *result = NULL;
4284 char *name;
4285 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004286
Victor Stinner8c62be82010-05-06 00:08:46 +00004287 errno = 0;
4288 name = getlogin();
4289 if (name == NULL) {
4290 if (errno)
4291 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004292 else
Victor Stinner8c62be82010-05-06 00:08:46 +00004293 PyErr_SetString(PyExc_OSError,
4294 "unable to determine login name");
4295 }
4296 else
4297 result = PyUnicode_FromString(name);
4298 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004299
Fred Drake12c6e2d1999-12-14 21:25:03 +00004300 return result;
4301}
4302#endif
4303
Guido van Rossumad0ee831995-03-01 10:34:45 +00004304#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004305PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004306"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004307Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004308
Barry Warsaw53699e91996-12-10 23:23:01 +00004309static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004310posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004311{
Victor Stinner8c62be82010-05-06 00:08:46 +00004312 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004313}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004314#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004315
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004316
Guido van Rossumad0ee831995-03-01 10:34:45 +00004317#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004318PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004319"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004320Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004321
Barry Warsaw53699e91996-12-10 23:23:01 +00004322static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004323posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004324{
Victor Stinner8c62be82010-05-06 00:08:46 +00004325 pid_t pid;
4326 int sig;
4327 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
4328 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004329#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004330 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4331 APIRET rc;
4332 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004333 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004334
4335 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4336 APIRET rc;
4337 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004338 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004339
4340 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004341 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004342#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004343 if (kill(pid, sig) == -1)
4344 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004345#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004346 Py_INCREF(Py_None);
4347 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004348}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004349#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004350
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004351#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004352PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004353"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004354Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004355
4356static PyObject *
4357posix_killpg(PyObject *self, PyObject *args)
4358{
Victor Stinner8c62be82010-05-06 00:08:46 +00004359 int sig;
4360 pid_t pgid;
4361 /* XXX some man pages make the `pgid` parameter an int, others
4362 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4363 take the same type. Moreover, pid_t is always at least as wide as
4364 int (else compilation of this module fails), which is safe. */
4365 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
4366 return NULL;
4367 if (killpg(pgid, sig) == -1)
4368 return posix_error();
4369 Py_INCREF(Py_None);
4370 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004371}
4372#endif
4373
Brian Curtineb24d742010-04-12 17:16:38 +00004374#ifdef MS_WINDOWS
4375PyDoc_STRVAR(win32_kill__doc__,
4376"kill(pid, sig)\n\n\
4377Kill a process with a signal.");
4378
4379static PyObject *
4380win32_kill(PyObject *self, PyObject *args)
4381{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00004382 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004383 DWORD pid, sig, err;
4384 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00004385
Victor Stinner8c62be82010-05-06 00:08:46 +00004386 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4387 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00004388
Victor Stinner8c62be82010-05-06 00:08:46 +00004389 /* Console processes which share a common console can be sent CTRL+C or
4390 CTRL+BREAK events, provided they handle said events. */
4391 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4392 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4393 err = GetLastError();
4394 PyErr_SetFromWindowsErr(err);
4395 }
4396 else
4397 Py_RETURN_NONE;
4398 }
Brian Curtineb24d742010-04-12 17:16:38 +00004399
Victor Stinner8c62be82010-05-06 00:08:46 +00004400 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4401 attempt to open and terminate the process. */
4402 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4403 if (handle == NULL) {
4404 err = GetLastError();
4405 return PyErr_SetFromWindowsErr(err);
4406 }
Brian Curtineb24d742010-04-12 17:16:38 +00004407
Victor Stinner8c62be82010-05-06 00:08:46 +00004408 if (TerminateProcess(handle, sig) == 0) {
4409 err = GetLastError();
4410 result = PyErr_SetFromWindowsErr(err);
4411 } else {
4412 Py_INCREF(Py_None);
4413 result = Py_None;
4414 }
Brian Curtineb24d742010-04-12 17:16:38 +00004415
Victor Stinner8c62be82010-05-06 00:08:46 +00004416 CloseHandle(handle);
4417 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00004418}
4419#endif /* MS_WINDOWS */
4420
Guido van Rossumc0125471996-06-28 18:55:32 +00004421#ifdef HAVE_PLOCK
4422
4423#ifdef HAVE_SYS_LOCK_H
4424#include <sys/lock.h>
4425#endif
4426
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004427PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004428"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004429Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004430
Barry Warsaw53699e91996-12-10 23:23:01 +00004431static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004432posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004433{
Victor Stinner8c62be82010-05-06 00:08:46 +00004434 int op;
4435 if (!PyArg_ParseTuple(args, "i:plock", &op))
4436 return NULL;
4437 if (plock(op) == -1)
4438 return posix_error();
4439 Py_INCREF(Py_None);
4440 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004441}
4442#endif
4443
Guido van Rossumb6775db1994-08-01 11:34:53 +00004444#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004445PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004446"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004447Set the current process's user id.");
4448
Barry Warsaw53699e91996-12-10 23:23:01 +00004449static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004450posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004451{
Victor Stinner8c62be82010-05-06 00:08:46 +00004452 long uid_arg;
4453 uid_t uid;
4454 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
4455 return NULL;
4456 uid = uid_arg;
4457 if (uid != uid_arg) {
4458 PyErr_SetString(PyExc_OverflowError, "user id too big");
4459 return NULL;
4460 }
4461 if (setuid(uid) < 0)
4462 return posix_error();
4463 Py_INCREF(Py_None);
4464 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004465}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004466#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004467
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004468
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004469#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004470PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004471"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004472Set the current process's effective user id.");
4473
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004474static PyObject *
4475posix_seteuid (PyObject *self, PyObject *args)
4476{
Victor Stinner8c62be82010-05-06 00:08:46 +00004477 long euid_arg;
4478 uid_t euid;
4479 if (!PyArg_ParseTuple(args, "l", &euid_arg))
4480 return NULL;
4481 euid = euid_arg;
4482 if (euid != euid_arg) {
4483 PyErr_SetString(PyExc_OverflowError, "user id too big");
4484 return NULL;
4485 }
4486 if (seteuid(euid) < 0) {
4487 return posix_error();
4488 } else {
4489 Py_INCREF(Py_None);
4490 return Py_None;
4491 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004492}
4493#endif /* HAVE_SETEUID */
4494
4495#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004496PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004497"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004498Set the current process's effective group id.");
4499
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004500static PyObject *
4501posix_setegid (PyObject *self, PyObject *args)
4502{
Victor Stinner8c62be82010-05-06 00:08:46 +00004503 long egid_arg;
4504 gid_t egid;
4505 if (!PyArg_ParseTuple(args, "l", &egid_arg))
4506 return NULL;
4507 egid = egid_arg;
4508 if (egid != egid_arg) {
4509 PyErr_SetString(PyExc_OverflowError, "group id too big");
4510 return NULL;
4511 }
4512 if (setegid(egid) < 0) {
4513 return posix_error();
4514 } else {
4515 Py_INCREF(Py_None);
4516 return Py_None;
4517 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004518}
4519#endif /* HAVE_SETEGID */
4520
4521#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004522PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004523"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004524Set the current process's real and effective user ids.");
4525
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004526static PyObject *
4527posix_setreuid (PyObject *self, PyObject *args)
4528{
Victor Stinner8c62be82010-05-06 00:08:46 +00004529 long ruid_arg, euid_arg;
4530 uid_t ruid, euid;
4531 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
4532 return NULL;
4533 if (ruid_arg == -1)
4534 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
4535 else
4536 ruid = ruid_arg; /* otherwise, assign from our long */
4537 if (euid_arg == -1)
4538 euid = (uid_t)-1;
4539 else
4540 euid = euid_arg;
4541 if ((euid_arg != -1 && euid != euid_arg) ||
4542 (ruid_arg != -1 && ruid != ruid_arg)) {
4543 PyErr_SetString(PyExc_OverflowError, "user id too big");
4544 return NULL;
4545 }
4546 if (setreuid(ruid, euid) < 0) {
4547 return posix_error();
4548 } else {
4549 Py_INCREF(Py_None);
4550 return Py_None;
4551 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004552}
4553#endif /* HAVE_SETREUID */
4554
4555#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004556PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004557"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004558Set the current process's real and effective group ids.");
4559
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004560static PyObject *
4561posix_setregid (PyObject *self, PyObject *args)
4562{
Victor Stinner8c62be82010-05-06 00:08:46 +00004563 long rgid_arg, egid_arg;
4564 gid_t rgid, egid;
4565 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
4566 return NULL;
4567 if (rgid_arg == -1)
4568 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
4569 else
4570 rgid = rgid_arg; /* otherwise, assign from our long */
4571 if (egid_arg == -1)
4572 egid = (gid_t)-1;
4573 else
4574 egid = egid_arg;
4575 if ((egid_arg != -1 && egid != egid_arg) ||
4576 (rgid_arg != -1 && rgid != rgid_arg)) {
4577 PyErr_SetString(PyExc_OverflowError, "group id too big");
4578 return NULL;
4579 }
4580 if (setregid(rgid, egid) < 0) {
4581 return posix_error();
4582 } else {
4583 Py_INCREF(Py_None);
4584 return Py_None;
4585 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004586}
4587#endif /* HAVE_SETREGID */
4588
Guido van Rossumb6775db1994-08-01 11:34:53 +00004589#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004590PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004591"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004592Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004593
Barry Warsaw53699e91996-12-10 23:23:01 +00004594static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004595posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004596{
Victor Stinner8c62be82010-05-06 00:08:46 +00004597 long gid_arg;
4598 gid_t gid;
4599 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
4600 return NULL;
4601 gid = gid_arg;
4602 if (gid != gid_arg) {
4603 PyErr_SetString(PyExc_OverflowError, "group id too big");
4604 return NULL;
4605 }
4606 if (setgid(gid) < 0)
4607 return posix_error();
4608 Py_INCREF(Py_None);
4609 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004610}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004611#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004612
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004613#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004614PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004615"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004616Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004617
4618static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004619posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004620{
Victor Stinner8c62be82010-05-06 00:08:46 +00004621 int i, len;
4622 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004623
Victor Stinner8c62be82010-05-06 00:08:46 +00004624 if (!PySequence_Check(groups)) {
4625 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4626 return NULL;
4627 }
4628 len = PySequence_Size(groups);
4629 if (len > MAX_GROUPS) {
4630 PyErr_SetString(PyExc_ValueError, "too many groups");
4631 return NULL;
4632 }
4633 for(i = 0; i < len; i++) {
4634 PyObject *elem;
4635 elem = PySequence_GetItem(groups, i);
4636 if (!elem)
4637 return NULL;
4638 if (!PyLong_Check(elem)) {
4639 PyErr_SetString(PyExc_TypeError,
4640 "groups must be integers");
4641 Py_DECREF(elem);
4642 return NULL;
4643 } else {
4644 unsigned long x = PyLong_AsUnsignedLong(elem);
4645 if (PyErr_Occurred()) {
4646 PyErr_SetString(PyExc_TypeError,
4647 "group id too big");
4648 Py_DECREF(elem);
4649 return NULL;
4650 }
4651 grouplist[i] = x;
4652 /* read back the value to see if it fitted in gid_t */
4653 if (grouplist[i] != x) {
4654 PyErr_SetString(PyExc_TypeError,
4655 "group id too big");
4656 Py_DECREF(elem);
4657 return NULL;
4658 }
4659 }
4660 Py_DECREF(elem);
4661 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004662
Victor Stinner8c62be82010-05-06 00:08:46 +00004663 if (setgroups(len, grouplist) < 0)
4664 return posix_error();
4665 Py_INCREF(Py_None);
4666 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004667}
4668#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004669
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004670#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4671static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004672wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004673{
Victor Stinner8c62be82010-05-06 00:08:46 +00004674 PyObject *result;
4675 static PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004676
Victor Stinner8c62be82010-05-06 00:08:46 +00004677 if (pid == -1)
4678 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004679
Victor Stinner8c62be82010-05-06 00:08:46 +00004680 if (struct_rusage == NULL) {
4681 PyObject *m = PyImport_ImportModuleNoBlock("resource");
4682 if (m == NULL)
4683 return NULL;
4684 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4685 Py_DECREF(m);
4686 if (struct_rusage == NULL)
4687 return NULL;
4688 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004689
Victor Stinner8c62be82010-05-06 00:08:46 +00004690 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4691 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4692 if (!result)
4693 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004694
4695#ifndef doubletime
4696#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4697#endif
4698
Victor Stinner8c62be82010-05-06 00:08:46 +00004699 PyStructSequence_SET_ITEM(result, 0,
4700 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4701 PyStructSequence_SET_ITEM(result, 1,
4702 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004703#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00004704 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
4705 SET_INT(result, 2, ru->ru_maxrss);
4706 SET_INT(result, 3, ru->ru_ixrss);
4707 SET_INT(result, 4, ru->ru_idrss);
4708 SET_INT(result, 5, ru->ru_isrss);
4709 SET_INT(result, 6, ru->ru_minflt);
4710 SET_INT(result, 7, ru->ru_majflt);
4711 SET_INT(result, 8, ru->ru_nswap);
4712 SET_INT(result, 9, ru->ru_inblock);
4713 SET_INT(result, 10, ru->ru_oublock);
4714 SET_INT(result, 11, ru->ru_msgsnd);
4715 SET_INT(result, 12, ru->ru_msgrcv);
4716 SET_INT(result, 13, ru->ru_nsignals);
4717 SET_INT(result, 14, ru->ru_nvcsw);
4718 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004719#undef SET_INT
4720
Victor Stinner8c62be82010-05-06 00:08:46 +00004721 if (PyErr_Occurred()) {
4722 Py_DECREF(result);
4723 return NULL;
4724 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004725
Victor Stinner8c62be82010-05-06 00:08:46 +00004726 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004727}
4728#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4729
4730#ifdef HAVE_WAIT3
4731PyDoc_STRVAR(posix_wait3__doc__,
4732"wait3(options) -> (pid, status, rusage)\n\n\
4733Wait for completion of a child process.");
4734
4735static PyObject *
4736posix_wait3(PyObject *self, PyObject *args)
4737{
Victor Stinner8c62be82010-05-06 00:08:46 +00004738 pid_t pid;
4739 int options;
4740 struct rusage ru;
4741 WAIT_TYPE status;
4742 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004743
Victor Stinner8c62be82010-05-06 00:08:46 +00004744 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4745 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004746
Victor Stinner8c62be82010-05-06 00:08:46 +00004747 Py_BEGIN_ALLOW_THREADS
4748 pid = wait3(&status, options, &ru);
4749 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004750
Victor Stinner8c62be82010-05-06 00:08:46 +00004751 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004752}
4753#endif /* HAVE_WAIT3 */
4754
4755#ifdef HAVE_WAIT4
4756PyDoc_STRVAR(posix_wait4__doc__,
4757"wait4(pid, options) -> (pid, status, rusage)\n\n\
4758Wait for completion of a given child process.");
4759
4760static PyObject *
4761posix_wait4(PyObject *self, PyObject *args)
4762{
Victor Stinner8c62be82010-05-06 00:08:46 +00004763 pid_t pid;
4764 int options;
4765 struct rusage ru;
4766 WAIT_TYPE status;
4767 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004768
Victor Stinner8c62be82010-05-06 00:08:46 +00004769 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
4770 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004771
Victor Stinner8c62be82010-05-06 00:08:46 +00004772 Py_BEGIN_ALLOW_THREADS
4773 pid = wait4(pid, &status, options, &ru);
4774 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004775
Victor Stinner8c62be82010-05-06 00:08:46 +00004776 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004777}
4778#endif /* HAVE_WAIT4 */
4779
Guido van Rossumb6775db1994-08-01 11:34:53 +00004780#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004781PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004782"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004783Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004784
Barry Warsaw53699e91996-12-10 23:23:01 +00004785static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004786posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004787{
Victor Stinner8c62be82010-05-06 00:08:46 +00004788 pid_t pid;
4789 int options;
4790 WAIT_TYPE status;
4791 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004792
Victor Stinner8c62be82010-05-06 00:08:46 +00004793 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4794 return NULL;
4795 Py_BEGIN_ALLOW_THREADS
4796 pid = waitpid(pid, &status, options);
4797 Py_END_ALLOW_THREADS
4798 if (pid == -1)
4799 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004800
Victor Stinner8c62be82010-05-06 00:08:46 +00004801 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004802}
4803
Tim Petersab034fa2002-02-01 11:27:43 +00004804#elif defined(HAVE_CWAIT)
4805
4806/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004807PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004808"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004809"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004810
4811static PyObject *
4812posix_waitpid(PyObject *self, PyObject *args)
4813{
Victor Stinner8c62be82010-05-06 00:08:46 +00004814 Py_intptr_t pid;
4815 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004816
Victor Stinner8c62be82010-05-06 00:08:46 +00004817 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4818 return NULL;
4819 Py_BEGIN_ALLOW_THREADS
4820 pid = _cwait(&status, pid, options);
4821 Py_END_ALLOW_THREADS
4822 if (pid == -1)
4823 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004824
Victor Stinner8c62be82010-05-06 00:08:46 +00004825 /* shift the status left a byte so this is more like the POSIX waitpid */
4826 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004827}
4828#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004829
Guido van Rossumad0ee831995-03-01 10:34:45 +00004830#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004831PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004832"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004833Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004834
Barry Warsaw53699e91996-12-10 23:23:01 +00004835static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004836posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004837{
Victor Stinner8c62be82010-05-06 00:08:46 +00004838 pid_t pid;
4839 WAIT_TYPE status;
4840 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004841
Victor Stinner8c62be82010-05-06 00:08:46 +00004842 Py_BEGIN_ALLOW_THREADS
4843 pid = wait(&status);
4844 Py_END_ALLOW_THREADS
4845 if (pid == -1)
4846 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004847
Victor Stinner8c62be82010-05-06 00:08:46 +00004848 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00004849}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004850#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004851
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004852
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004853PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004854"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004855Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004856
Barry Warsaw53699e91996-12-10 23:23:01 +00004857static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004858posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004859{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004860#ifdef HAVE_LSTAT
Victor Stinner8c62be82010-05-06 00:08:46 +00004861 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004862#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004863#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00004864 return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat",
4865 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004866#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004867 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004868#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004869#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004870}
4871
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004872
Guido van Rossumb6775db1994-08-01 11:34:53 +00004873#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004874PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004875"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004876Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004877
Barry Warsaw53699e91996-12-10 23:23:01 +00004878static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004879posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004880{
Victor Stinner8c62be82010-05-06 00:08:46 +00004881 PyObject* v;
4882 char buf[MAXPATHLEN];
4883 PyObject *opath;
4884 char *path;
4885 int n;
4886 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004887
Victor Stinner8c62be82010-05-06 00:08:46 +00004888 if (!PyArg_ParseTuple(args, "O&:readlink",
4889 PyUnicode_FSConverter, &opath))
4890 return NULL;
4891 path = PyBytes_AsString(opath);
4892 v = PySequence_GetItem(args, 0);
4893 if (v == NULL) {
4894 Py_DECREF(opath);
4895 return NULL;
4896 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004897
Victor Stinner8c62be82010-05-06 00:08:46 +00004898 if (PyUnicode_Check(v)) {
4899 arg_is_unicode = 1;
4900 }
4901 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004902
Victor Stinner8c62be82010-05-06 00:08:46 +00004903 Py_BEGIN_ALLOW_THREADS
4904 n = readlink(path, buf, (int) sizeof buf);
4905 Py_END_ALLOW_THREADS
4906 if (n < 0)
4907 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004908
Victor Stinner8c62be82010-05-06 00:08:46 +00004909 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00004910 if (arg_is_unicode)
4911 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
4912 else
4913 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004914}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004915#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004916
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004917
Guido van Rossumb6775db1994-08-01 11:34:53 +00004918#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004919PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004920"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00004921Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004922
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004923static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004924posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004925{
Victor Stinner8c62be82010-05-06 00:08:46 +00004926 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004927}
4928#endif /* HAVE_SYMLINK */
4929
Brian Curtind40e6f72010-07-08 21:39:08 +00004930#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
4931
4932PyDoc_STRVAR(win_readlink__doc__,
4933"readlink(path) -> path\n\n\
4934Return a string representing the path to which the symbolic link points.");
4935
4936/* The following structure was copied from
4937 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
4938 include doesn't seem to be present in the Windows SDK (at least as included
4939 with Visual Studio Express). */
4940typedef struct _REPARSE_DATA_BUFFER {
4941 ULONG ReparseTag;
4942 USHORT ReparseDataLength;
4943 USHORT Reserved;
4944 union {
4945 struct {
4946 USHORT SubstituteNameOffset;
4947 USHORT SubstituteNameLength;
4948 USHORT PrintNameOffset;
4949 USHORT PrintNameLength;
4950 ULONG Flags;
4951 WCHAR PathBuffer[1];
4952 } SymbolicLinkReparseBuffer;
4953
4954 struct {
4955 USHORT SubstituteNameOffset;
4956 USHORT SubstituteNameLength;
4957 USHORT PrintNameOffset;
4958 USHORT PrintNameLength;
4959 WCHAR PathBuffer[1];
4960 } MountPointReparseBuffer;
4961
4962 struct {
4963 UCHAR DataBuffer[1];
4964 } GenericReparseBuffer;
4965 };
4966} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
4967
Brian Curtin74e45612010-07-09 15:58:59 +00004968#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
4969 GenericReparseBuffer)
Brian Curtind40e6f72010-07-08 21:39:08 +00004970
4971#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
4972
4973/* Windows readlink implementation */
4974static PyObject *
4975win_readlink(PyObject *self, PyObject *args)
4976{
4977 wchar_t *path;
4978 DWORD n_bytes_returned;
4979 DWORD io_result;
4980 PyObject *result;
4981 HANDLE reparse_point_handle;
4982
4983 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
4984 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
4985 wchar_t *print_name;
4986
4987 if (!PyArg_ParseTuple(args,
4988 "u:readlink",
4989 &path))
4990 return NULL;
4991
4992 /* First get a handle to the reparse point */
4993 Py_BEGIN_ALLOW_THREADS
4994 reparse_point_handle = CreateFileW(
4995 path,
4996 0,
4997 0,
4998 0,
4999 OPEN_EXISTING,
5000 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
5001 0);
5002 Py_END_ALLOW_THREADS
5003
5004 if (reparse_point_handle==INVALID_HANDLE_VALUE)
5005 {
5006 return win32_error_unicode("readlink", path);
5007 }
5008
5009 Py_BEGIN_ALLOW_THREADS
5010 /* New call DeviceIoControl to read the reparse point */
5011 io_result = DeviceIoControl(
5012 reparse_point_handle,
5013 FSCTL_GET_REPARSE_POINT,
5014 0, 0, /* in buffer */
5015 target_buffer, sizeof(target_buffer),
5016 &n_bytes_returned,
5017 0 /* we're not using OVERLAPPED_IO */
5018 );
5019 CloseHandle(reparse_point_handle);
5020 Py_END_ALLOW_THREADS
5021
5022 if (io_result==0)
5023 {
5024 return win32_error_unicode("readlink", path);
5025 }
5026
5027 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
5028 {
5029 PyErr_SetString(PyExc_ValueError,
5030 "not a symbolic link");
5031 return NULL;
5032 }
Brian Curtin74e45612010-07-09 15:58:59 +00005033 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
5034 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
5035
5036 result = PyUnicode_FromWideChar(print_name,
5037 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00005038 return result;
5039}
5040
5041#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
5042
5043#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
5044
5045/* Grab CreateSymbolicLinkW dynamically from kernel32 */
5046static int has_CreateSymbolicLinkW = 0;
5047static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
5048static int
5049check_CreateSymbolicLinkW()
5050{
5051 HINSTANCE hKernel32;
5052 /* only recheck */
5053 if (has_CreateSymbolicLinkW)
5054 return has_CreateSymbolicLinkW;
5055 hKernel32 = GetModuleHandle("KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00005056 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
5057 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00005058 if (Py_CreateSymbolicLinkW)
5059 has_CreateSymbolicLinkW = 1;
5060 return has_CreateSymbolicLinkW;
5061}
5062
5063PyDoc_STRVAR(win_symlink__doc__,
5064"symlink(src, dst, target_is_directory=False)\n\n\
5065Create a symbolic link pointing to src named dst.\n\
5066target_is_directory is required if the target is to be interpreted as\n\
5067a directory.\n\
5068This function requires Windows 6.0 or greater, and raises a\n\
5069NotImplementedError otherwise.");
5070
5071static PyObject *
5072win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
5073{
5074 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
5075 PyObject *src, *dest;
5076 int target_is_directory = 0;
5077 DWORD res;
5078 WIN32_FILE_ATTRIBUTE_DATA src_info;
5079
5080 if (!check_CreateSymbolicLinkW())
5081 {
5082 /* raise NotImplementedError */
5083 return PyErr_Format(PyExc_NotImplementedError,
5084 "CreateSymbolicLinkW not found");
5085 }
5086 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:symlink",
5087 kwlist, &src, &dest, &target_is_directory))
5088 return NULL;
5089 if (!convert_to_unicode(&src)) { return NULL; }
5090 if (!convert_to_unicode(&dest)) {
5091 Py_DECREF(src);
5092 return NULL;
5093 }
5094
5095 /* if src is a directory, ensure target_is_directory==1 */
5096 if(
5097 GetFileAttributesExW(
5098 PyUnicode_AsUnicode(src), GetFileExInfoStandard, &src_info
5099 ))
5100 {
5101 target_is_directory = target_is_directory ||
5102 (src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
5103 }
5104
5105 Py_BEGIN_ALLOW_THREADS
5106 res = Py_CreateSymbolicLinkW(
5107 PyUnicode_AsUnicode(dest),
5108 PyUnicode_AsUnicode(src),
5109 target_is_directory);
5110 Py_END_ALLOW_THREADS
5111 Py_DECREF(src);
5112 Py_DECREF(dest);
5113 if (!res)
5114 {
5115 return win32_error_unicode("symlink", PyUnicode_AsUnicode(src));
5116 }
5117
5118 Py_INCREF(Py_None);
5119 return Py_None;
5120}
5121#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005122
5123#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00005124#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5125static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005126system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005127{
5128 ULONG value = 0;
5129
5130 Py_BEGIN_ALLOW_THREADS
5131 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5132 Py_END_ALLOW_THREADS
5133
5134 return value;
5135}
5136
5137static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005138posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005139{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005140 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00005141 return Py_BuildValue("ddddd",
5142 (double)0 /* t.tms_utime / HZ */,
5143 (double)0 /* t.tms_stime / HZ */,
5144 (double)0 /* t.tms_cutime / HZ */,
5145 (double)0 /* t.tms_cstime / HZ */,
5146 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005147}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005148#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00005149#define NEED_TICKS_PER_SECOND
5150static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00005151static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005152posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005153{
Victor Stinner8c62be82010-05-06 00:08:46 +00005154 struct tms t;
5155 clock_t c;
5156 errno = 0;
5157 c = times(&t);
5158 if (c == (clock_t) -1)
5159 return posix_error();
5160 return Py_BuildValue("ddddd",
5161 (double)t.tms_utime / ticks_per_second,
5162 (double)t.tms_stime / ticks_per_second,
5163 (double)t.tms_cutime / ticks_per_second,
5164 (double)t.tms_cstime / ticks_per_second,
5165 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005166}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005167#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005168#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005169
5170
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005171#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005172#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005173static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005174posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005175{
Victor Stinner8c62be82010-05-06 00:08:46 +00005176 FILETIME create, exit, kernel, user;
5177 HANDLE hProc;
5178 hProc = GetCurrentProcess();
5179 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5180 /* The fields of a FILETIME structure are the hi and lo part
5181 of a 64-bit value expressed in 100 nanosecond units.
5182 1e7 is one second in such units; 1e-7 the inverse.
5183 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5184 */
5185 return Py_BuildValue(
5186 "ddddd",
5187 (double)(user.dwHighDateTime*429.4967296 +
5188 user.dwLowDateTime*1e-7),
5189 (double)(kernel.dwHighDateTime*429.4967296 +
5190 kernel.dwLowDateTime*1e-7),
5191 (double)0,
5192 (double)0,
5193 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005194}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005195#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005196
5197#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005198PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005199"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005200Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005201#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005202
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005203
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005204#ifdef HAVE_GETSID
5205PyDoc_STRVAR(posix_getsid__doc__,
5206"getsid(pid) -> sid\n\n\
5207Call the system call getsid().");
5208
5209static PyObject *
5210posix_getsid(PyObject *self, PyObject *args)
5211{
Victor Stinner8c62be82010-05-06 00:08:46 +00005212 pid_t pid;
5213 int sid;
5214 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
5215 return NULL;
5216 sid = getsid(pid);
5217 if (sid < 0)
5218 return posix_error();
5219 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005220}
5221#endif /* HAVE_GETSID */
5222
5223
Guido van Rossumb6775db1994-08-01 11:34:53 +00005224#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005225PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005226"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005227Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005228
Barry Warsaw53699e91996-12-10 23:23:01 +00005229static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005230posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005231{
Victor Stinner8c62be82010-05-06 00:08:46 +00005232 if (setsid() < 0)
5233 return posix_error();
5234 Py_INCREF(Py_None);
5235 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005236}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005237#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005238
Guido van Rossumb6775db1994-08-01 11:34:53 +00005239#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005240PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005241"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005242Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005243
Barry Warsaw53699e91996-12-10 23:23:01 +00005244static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005245posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005246{
Victor Stinner8c62be82010-05-06 00:08:46 +00005247 pid_t pid;
5248 int pgrp;
5249 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
5250 return NULL;
5251 if (setpgid(pid, pgrp) < 0)
5252 return posix_error();
5253 Py_INCREF(Py_None);
5254 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005255}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005256#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005257
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005258
Guido van Rossumb6775db1994-08-01 11:34:53 +00005259#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005260PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005261"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005262Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005263
Barry Warsaw53699e91996-12-10 23:23:01 +00005264static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005265posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005266{
Victor Stinner8c62be82010-05-06 00:08:46 +00005267 int fd;
5268 pid_t pgid;
5269 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
5270 return NULL;
5271 pgid = tcgetpgrp(fd);
5272 if (pgid < 0)
5273 return posix_error();
5274 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005275}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005276#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005277
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005278
Guido van Rossumb6775db1994-08-01 11:34:53 +00005279#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005280PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005281"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005282Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005283
Barry Warsaw53699e91996-12-10 23:23:01 +00005284static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005285posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005286{
Victor Stinner8c62be82010-05-06 00:08:46 +00005287 int fd;
5288 pid_t pgid;
5289 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
5290 return NULL;
5291 if (tcsetpgrp(fd, pgid) < 0)
5292 return posix_error();
5293 Py_INCREF(Py_None);
5294 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005295}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005296#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005297
Guido van Rossum687dd131993-05-17 08:34:16 +00005298/* Functions acting on file descriptors */
5299
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005300PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005301"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005302Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005303
Barry Warsaw53699e91996-12-10 23:23:01 +00005304static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005305posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005306{
Victor Stinner8c62be82010-05-06 00:08:46 +00005307 PyObject *ofile;
5308 char *file;
5309 int flag;
5310 int mode = 0777;
5311 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005312
5313#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005314 PyUnicodeObject *po;
5315 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5316 Py_BEGIN_ALLOW_THREADS
5317 /* PyUnicode_AS_UNICODE OK without thread
5318 lock as it is a simple dereference. */
5319 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5320 Py_END_ALLOW_THREADS
5321 if (fd < 0)
5322 return posix_error();
5323 return PyLong_FromLong((long)fd);
5324 }
5325 /* Drop the argument parsing error as narrow strings
5326 are also valid. */
5327 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005328#endif
5329
Victor Stinner8c62be82010-05-06 00:08:46 +00005330 if (!PyArg_ParseTuple(args, "O&i|i",
5331 PyUnicode_FSConverter, &ofile,
5332 &flag, &mode))
5333 return NULL;
5334 file = PyBytes_AsString(ofile);
5335 Py_BEGIN_ALLOW_THREADS
5336 fd = open(file, flag, mode);
5337 Py_END_ALLOW_THREADS
5338 if (fd < 0)
5339 return posix_error_with_allocated_filename(ofile);
5340 Py_DECREF(ofile);
5341 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005342}
5343
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005344
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005345PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005346"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005347Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005348
Barry Warsaw53699e91996-12-10 23:23:01 +00005349static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005350posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005351{
Victor Stinner8c62be82010-05-06 00:08:46 +00005352 int fd, res;
5353 if (!PyArg_ParseTuple(args, "i:close", &fd))
5354 return NULL;
5355 if (!_PyVerify_fd(fd))
5356 return posix_error();
5357 Py_BEGIN_ALLOW_THREADS
5358 res = close(fd);
5359 Py_END_ALLOW_THREADS
5360 if (res < 0)
5361 return posix_error();
5362 Py_INCREF(Py_None);
5363 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005364}
5365
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005366
Victor Stinner8c62be82010-05-06 00:08:46 +00005367PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00005368"closerange(fd_low, fd_high)\n\n\
5369Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
5370
5371static PyObject *
5372posix_closerange(PyObject *self, PyObject *args)
5373{
Victor Stinner8c62be82010-05-06 00:08:46 +00005374 int fd_from, fd_to, i;
5375 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
5376 return NULL;
5377 Py_BEGIN_ALLOW_THREADS
5378 for (i = fd_from; i < fd_to; i++)
5379 if (_PyVerify_fd(i))
5380 close(i);
5381 Py_END_ALLOW_THREADS
5382 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00005383}
5384
5385
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005386PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005387"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005388Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005389
Barry Warsaw53699e91996-12-10 23:23:01 +00005390static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005391posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005392{
Victor Stinner8c62be82010-05-06 00:08:46 +00005393 int fd;
5394 if (!PyArg_ParseTuple(args, "i:dup", &fd))
5395 return NULL;
5396 if (!_PyVerify_fd(fd))
5397 return posix_error();
5398 Py_BEGIN_ALLOW_THREADS
5399 fd = dup(fd);
5400 Py_END_ALLOW_THREADS
5401 if (fd < 0)
5402 return posix_error();
5403 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005404}
5405
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005406
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005407PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005408"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005409Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005410
Barry Warsaw53699e91996-12-10 23:23:01 +00005411static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005412posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005413{
Victor Stinner8c62be82010-05-06 00:08:46 +00005414 int fd, fd2, res;
5415 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5416 return NULL;
5417 if (!_PyVerify_fd_dup2(fd, fd2))
5418 return posix_error();
5419 Py_BEGIN_ALLOW_THREADS
5420 res = dup2(fd, fd2);
5421 Py_END_ALLOW_THREADS
5422 if (res < 0)
5423 return posix_error();
5424 Py_INCREF(Py_None);
5425 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005426}
5427
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005428
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005429PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005430"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005431Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005432
Barry Warsaw53699e91996-12-10 23:23:01 +00005433static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005434posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005435{
Victor Stinner8c62be82010-05-06 00:08:46 +00005436 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005437#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005438 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005439#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005440 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005441#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005442 PyObject *posobj;
5443 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5444 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005445#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00005446 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5447 switch (how) {
5448 case 0: how = SEEK_SET; break;
5449 case 1: how = SEEK_CUR; break;
5450 case 2: how = SEEK_END; break;
5451 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005452#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005453
5454#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005455 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005456#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005457 pos = PyLong_Check(posobj) ?
5458 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005459#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005460 if (PyErr_Occurred())
5461 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005462
Victor Stinner8c62be82010-05-06 00:08:46 +00005463 if (!_PyVerify_fd(fd))
5464 return posix_error();
5465 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005466#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005467 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005468#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005469 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005470#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005471 Py_END_ALLOW_THREADS
5472 if (res < 0)
5473 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005474
5475#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005476 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005477#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005478 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005479#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005480}
5481
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005482
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005483PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005484"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005485Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005486
Barry Warsaw53699e91996-12-10 23:23:01 +00005487static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005488posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005489{
Victor Stinner8c62be82010-05-06 00:08:46 +00005490 int fd, size;
5491 Py_ssize_t n;
5492 PyObject *buffer;
5493 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5494 return NULL;
5495 if (size < 0) {
5496 errno = EINVAL;
5497 return posix_error();
5498 }
5499 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
5500 if (buffer == NULL)
5501 return NULL;
5502 if (!_PyVerify_fd(fd))
5503 return posix_error();
5504 Py_BEGIN_ALLOW_THREADS
5505 n = read(fd, PyBytes_AS_STRING(buffer), size);
5506 Py_END_ALLOW_THREADS
5507 if (n < 0) {
5508 Py_DECREF(buffer);
5509 return posix_error();
5510 }
5511 if (n != size)
5512 _PyBytes_Resize(&buffer, n);
5513 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00005514}
5515
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005516
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005517PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005518"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005519Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005520
Barry Warsaw53699e91996-12-10 23:23:01 +00005521static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005522posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005523{
Victor Stinner8c62be82010-05-06 00:08:46 +00005524 Py_buffer pbuf;
5525 int fd;
5526 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005527
Victor Stinner8c62be82010-05-06 00:08:46 +00005528 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
5529 return NULL;
5530 if (!_PyVerify_fd(fd))
5531 return posix_error();
5532 Py_BEGIN_ALLOW_THREADS
5533 size = write(fd, pbuf.buf, (size_t)pbuf.len);
5534 Py_END_ALLOW_THREADS
5535 PyBuffer_Release(&pbuf);
5536 if (size < 0)
5537 return posix_error();
5538 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005539}
5540
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005541
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005542PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005543"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005544Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005545
Barry Warsaw53699e91996-12-10 23:23:01 +00005546static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005547posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005548{
Victor Stinner8c62be82010-05-06 00:08:46 +00005549 int fd;
5550 STRUCT_STAT st;
5551 int res;
5552 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5553 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005554#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00005555 /* on OpenVMS we must ensure that all bytes are written to the file */
5556 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005557#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005558 if (!_PyVerify_fd(fd))
5559 return posix_error();
5560 Py_BEGIN_ALLOW_THREADS
5561 res = FSTAT(fd, &st);
5562 Py_END_ALLOW_THREADS
5563 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00005564#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005565 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00005566#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005567 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005568#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005569 }
Tim Peters5aa91602002-01-30 05:46:57 +00005570
Victor Stinner8c62be82010-05-06 00:08:46 +00005571 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005572}
5573
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005574PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005575"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005576Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005577connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005578
5579static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005580posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005581{
Victor Stinner8c62be82010-05-06 00:08:46 +00005582 int fd;
5583 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5584 return NULL;
5585 if (!_PyVerify_fd(fd))
5586 return PyBool_FromLong(0);
5587 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005588}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005589
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005590#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005591PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005592"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005593Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005594
Barry Warsaw53699e91996-12-10 23:23:01 +00005595static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005596posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005597{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005598#if defined(PYOS_OS2)
5599 HFILE read, write;
5600 APIRET rc;
5601
Victor Stinner8c62be82010-05-06 00:08:46 +00005602 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005603 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinner8c62be82010-05-06 00:08:46 +00005604 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005605 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005606 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005607
5608 return Py_BuildValue("(ii)", read, write);
5609#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005610#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005611 int fds[2];
5612 int res;
5613 Py_BEGIN_ALLOW_THREADS
5614 res = pipe(fds);
5615 Py_END_ALLOW_THREADS
5616 if (res != 0)
5617 return posix_error();
5618 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005619#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00005620 HANDLE read, write;
5621 int read_fd, write_fd;
5622 BOOL ok;
5623 Py_BEGIN_ALLOW_THREADS
5624 ok = CreatePipe(&read, &write, NULL, 0);
5625 Py_END_ALLOW_THREADS
5626 if (!ok)
5627 return win32_error("CreatePipe", NULL);
5628 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5629 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5630 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005631#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005632#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005633}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005634#endif /* HAVE_PIPE */
5635
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005636
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005637#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005638PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005639"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005640Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005641
Barry Warsaw53699e91996-12-10 23:23:01 +00005642static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005643posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005644{
Victor Stinner8c62be82010-05-06 00:08:46 +00005645 char *filename;
5646 int mode = 0666;
5647 int res;
5648 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
5649 return NULL;
5650 Py_BEGIN_ALLOW_THREADS
5651 res = mkfifo(filename, mode);
5652 Py_END_ALLOW_THREADS
5653 if (res < 0)
5654 return posix_error();
5655 Py_INCREF(Py_None);
5656 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005657}
5658#endif
5659
5660
Neal Norwitz11690112002-07-30 01:08:28 +00005661#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005662PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005663"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005664Create a filesystem node (file, device special file or named pipe)\n\
5665named filename. mode specifies both the permissions to use and the\n\
5666type of node to be created, being combined (bitwise OR) with one of\n\
5667S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005668device defines the newly created device special file (probably using\n\
5669os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005670
5671
5672static PyObject *
5673posix_mknod(PyObject *self, PyObject *args)
5674{
Victor Stinner8c62be82010-05-06 00:08:46 +00005675 char *filename;
5676 int mode = 0600;
5677 int device = 0;
5678 int res;
5679 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
5680 return NULL;
5681 Py_BEGIN_ALLOW_THREADS
5682 res = mknod(filename, mode, device);
5683 Py_END_ALLOW_THREADS
5684 if (res < 0)
5685 return posix_error();
5686 Py_INCREF(Py_None);
5687 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005688}
5689#endif
5690
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005691#ifdef HAVE_DEVICE_MACROS
5692PyDoc_STRVAR(posix_major__doc__,
5693"major(device) -> major number\n\
5694Extracts a device major number from a raw device number.");
5695
5696static PyObject *
5697posix_major(PyObject *self, PyObject *args)
5698{
Victor Stinner8c62be82010-05-06 00:08:46 +00005699 int device;
5700 if (!PyArg_ParseTuple(args, "i:major", &device))
5701 return NULL;
5702 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005703}
5704
5705PyDoc_STRVAR(posix_minor__doc__,
5706"minor(device) -> minor number\n\
5707Extracts a device minor number from a raw device number.");
5708
5709static PyObject *
5710posix_minor(PyObject *self, PyObject *args)
5711{
Victor Stinner8c62be82010-05-06 00:08:46 +00005712 int device;
5713 if (!PyArg_ParseTuple(args, "i:minor", &device))
5714 return NULL;
5715 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005716}
5717
5718PyDoc_STRVAR(posix_makedev__doc__,
5719"makedev(major, minor) -> device number\n\
5720Composes a raw device number from the major and minor device numbers.");
5721
5722static PyObject *
5723posix_makedev(PyObject *self, PyObject *args)
5724{
Victor Stinner8c62be82010-05-06 00:08:46 +00005725 int major, minor;
5726 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5727 return NULL;
5728 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005729}
5730#endif /* device macros */
5731
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005732
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005733#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005734PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005735"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005736Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005737
Barry Warsaw53699e91996-12-10 23:23:01 +00005738static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005739posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005740{
Victor Stinner8c62be82010-05-06 00:08:46 +00005741 int fd;
5742 off_t length;
5743 int res;
5744 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005745
Victor Stinner8c62be82010-05-06 00:08:46 +00005746 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
5747 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005748
5749#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005750 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005751#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005752 length = PyLong_Check(lenobj) ?
5753 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005754#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005755 if (PyErr_Occurred())
5756 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005757
Victor Stinner8c62be82010-05-06 00:08:46 +00005758 Py_BEGIN_ALLOW_THREADS
5759 res = ftruncate(fd, length);
5760 Py_END_ALLOW_THREADS
5761 if (res < 0)
5762 return posix_error();
5763 Py_INCREF(Py_None);
5764 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005765}
5766#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005767
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005768#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005769PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005770"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005771Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005772
Fred Drake762e2061999-08-26 17:23:54 +00005773/* Save putenv() parameters as values here, so we can collect them when they
5774 * get re-set with another call for the same key. */
5775static PyObject *posix_putenv_garbage;
5776
Tim Peters5aa91602002-01-30 05:46:57 +00005777static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005778posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005779{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005780#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005781 wchar_t *s1, *s2;
5782 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005783#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005784 PyObject *os1, *os2;
5785 char *s1, *s2;
5786 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005787#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005788 PyObject *newstr = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005789 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005790
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005791#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005792 if (!PyArg_ParseTuple(args,
5793 "uu:putenv",
5794 &s1, &s2))
5795 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005796#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005797 if (!PyArg_ParseTuple(args,
5798 "O&O&:putenv",
5799 PyUnicode_FSConverter, &os1,
5800 PyUnicode_FSConverter, &os2))
5801 return NULL;
5802 s1 = PyBytes_AsString(os1);
5803 s2 = PyBytes_AsString(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005804#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005805
5806#if defined(PYOS_OS2)
5807 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5808 APIRET rc;
5809
Guido van Rossumd48f2521997-12-05 22:19:34 +00005810 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005811 if (rc != NO_ERROR) {
5812 os2_error(rc);
5813 goto error;
5814 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005815
5816 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5817 APIRET rc;
5818
Guido van Rossumd48f2521997-12-05 22:19:34 +00005819 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005820 if (rc != NO_ERROR) {
5821 os2_error(rc);
5822 goto error;
5823 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005824 } else {
5825#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005826 /* XXX This can leak memory -- not easy to fix :-( */
5827 /* len includes space for a trailing \0; the size arg to
5828 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005829#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005830 len = wcslen(s1) + wcslen(s2) + 2;
5831 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005832#else
Victor Stinner84ae1182010-05-06 22:05:07 +00005833 len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2;
Victor Stinner8c62be82010-05-06 00:08:46 +00005834 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005835#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005836 if (newstr == NULL) {
5837 PyErr_NoMemory();
5838 goto error;
5839 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005840#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005841 newenv = PyUnicode_AsUnicode(newstr);
5842 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5843 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005844 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00005845 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005846 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005847#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005848 newenv = PyBytes_AS_STRING(newstr);
5849 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5850 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005851 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00005852 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005853 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005854#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005855
Victor Stinner8c62be82010-05-06 00:08:46 +00005856 /* Install the first arg and newstr in posix_putenv_garbage;
5857 * this will cause previous value to be collected. This has to
5858 * happen after the real putenv() call because the old value
5859 * was still accessible until then. */
5860 if (PyDict_SetItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00005861#ifdef MS_WINDOWS
5862 PyTuple_GET_ITEM(args, 0),
5863#else
5864 os1,
5865#endif
5866 newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005867 /* really not much we can do; just leak */
5868 PyErr_Clear();
5869 }
5870 else {
5871 Py_DECREF(newstr);
5872 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005873
5874#if defined(PYOS_OS2)
5875 }
5876#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005877
Martin v. Löwis011e8422009-05-05 04:43:17 +00005878#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005879 Py_DECREF(os1);
5880 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005881#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005882 Py_RETURN_NONE;
5883
5884error:
5885#ifndef MS_WINDOWS
5886 Py_DECREF(os1);
5887 Py_DECREF(os2);
5888#endif
5889 Py_XDECREF(newstr);
5890 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005891}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005892#endif /* putenv */
5893
Guido van Rossumc524d952001-10-19 01:31:59 +00005894#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005895PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005896"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005897Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005898
5899static PyObject *
5900posix_unsetenv(PyObject *self, PyObject *args)
5901{
Victor Stinner84ae1182010-05-06 22:05:07 +00005902#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005903 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00005904
Victor Stinner8c62be82010-05-06 00:08:46 +00005905 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5906 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00005907#else
5908 PyObject *os1;
5909 char *s1;
5910
5911 if (!PyArg_ParseTuple(args, "O&:unsetenv",
5912 PyUnicode_FSConverter, &os1))
5913 return NULL;
5914 s1 = PyBytes_AsString(os1);
5915#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00005916
Victor Stinner8c62be82010-05-06 00:08:46 +00005917 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00005918
Victor Stinner8c62be82010-05-06 00:08:46 +00005919 /* Remove the key from posix_putenv_garbage;
5920 * this will cause it to be collected. This has to
5921 * happen after the real unsetenv() call because the
5922 * old value was still accessible until then.
5923 */
5924 if (PyDict_DelItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00005925#ifdef MS_WINDOWS
5926 PyTuple_GET_ITEM(args, 0)
5927#else
5928 os1
5929#endif
5930 )) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005931 /* really not much we can do; just leak */
5932 PyErr_Clear();
5933 }
Guido van Rossumc524d952001-10-19 01:31:59 +00005934
Victor Stinner84ae1182010-05-06 22:05:07 +00005935#ifndef MS_WINDOWS
5936 Py_DECREF(os1);
5937#endif
5938 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00005939}
5940#endif /* unsetenv */
5941
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005942PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005943"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005944Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005945
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005946static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005947posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005948{
Victor Stinner8c62be82010-05-06 00:08:46 +00005949 int code;
5950 char *message;
5951 if (!PyArg_ParseTuple(args, "i:strerror", &code))
5952 return NULL;
5953 message = strerror(code);
5954 if (message == NULL) {
5955 PyErr_SetString(PyExc_ValueError,
5956 "strerror() argument out of range");
5957 return NULL;
5958 }
5959 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00005960}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005961
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005962
Guido van Rossumc9641791998-08-04 15:26:23 +00005963#ifdef HAVE_SYS_WAIT_H
5964
Fred Drake106c1a02002-04-23 15:58:02 +00005965#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005966PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005967"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005968Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005969
5970static PyObject *
5971posix_WCOREDUMP(PyObject *self, PyObject *args)
5972{
Victor Stinner8c62be82010-05-06 00:08:46 +00005973 WAIT_TYPE status;
5974 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005975
Victor Stinner8c62be82010-05-06 00:08:46 +00005976 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
5977 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005978
Victor Stinner8c62be82010-05-06 00:08:46 +00005979 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005980}
5981#endif /* WCOREDUMP */
5982
5983#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005984PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005985"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005986Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005987job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005988
5989static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005990posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005991{
Victor Stinner8c62be82010-05-06 00:08:46 +00005992 WAIT_TYPE status;
5993 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005994
Victor Stinner8c62be82010-05-06 00:08:46 +00005995 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
5996 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005997
Victor Stinner8c62be82010-05-06 00:08:46 +00005998 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005999}
6000#endif /* WIFCONTINUED */
6001
Guido van Rossumc9641791998-08-04 15:26:23 +00006002#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006003PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006004"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006005Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006006
6007static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006008posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006009{
Victor Stinner8c62be82010-05-06 00:08:46 +00006010 WAIT_TYPE status;
6011 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006012
Victor Stinner8c62be82010-05-06 00:08:46 +00006013 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
6014 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006015
Victor Stinner8c62be82010-05-06 00:08:46 +00006016 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006017}
6018#endif /* WIFSTOPPED */
6019
6020#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006021PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006022"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006023Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006024
6025static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006026posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006027{
Victor Stinner8c62be82010-05-06 00:08:46 +00006028 WAIT_TYPE status;
6029 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006030
Victor Stinner8c62be82010-05-06 00:08:46 +00006031 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
6032 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006033
Victor Stinner8c62be82010-05-06 00:08:46 +00006034 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006035}
6036#endif /* WIFSIGNALED */
6037
6038#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006039PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006040"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006041Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006042system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006043
6044static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006045posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006046{
Victor Stinner8c62be82010-05-06 00:08:46 +00006047 WAIT_TYPE status;
6048 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006049
Victor Stinner8c62be82010-05-06 00:08:46 +00006050 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
6051 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006052
Victor Stinner8c62be82010-05-06 00:08:46 +00006053 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006054}
6055#endif /* WIFEXITED */
6056
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006057#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006058PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006059"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006060Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006061
6062static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006063posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006064{
Victor Stinner8c62be82010-05-06 00:08:46 +00006065 WAIT_TYPE status;
6066 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006067
Victor Stinner8c62be82010-05-06 00:08:46 +00006068 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
6069 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006070
Victor Stinner8c62be82010-05-06 00:08:46 +00006071 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006072}
6073#endif /* WEXITSTATUS */
6074
6075#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006076PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006077"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006078Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006079value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006080
6081static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006082posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006083{
Victor Stinner8c62be82010-05-06 00:08:46 +00006084 WAIT_TYPE status;
6085 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006086
Victor Stinner8c62be82010-05-06 00:08:46 +00006087 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
6088 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006089
Victor Stinner8c62be82010-05-06 00:08:46 +00006090 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006091}
6092#endif /* WTERMSIG */
6093
6094#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006095PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006096"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006097Return the signal that stopped the process that provided\n\
6098the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006099
6100static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006101posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006102{
Victor Stinner8c62be82010-05-06 00:08:46 +00006103 WAIT_TYPE status;
6104 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006105
Victor Stinner8c62be82010-05-06 00:08:46 +00006106 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
6107 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006108
Victor Stinner8c62be82010-05-06 00:08:46 +00006109 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006110}
6111#endif /* WSTOPSIG */
6112
6113#endif /* HAVE_SYS_WAIT_H */
6114
6115
Thomas Wouters477c8d52006-05-27 19:21:47 +00006116#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006117#ifdef _SCO_DS
6118/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6119 needed definitions in sys/statvfs.h */
6120#define _SVID3
6121#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006122#include <sys/statvfs.h>
6123
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006124static PyObject*
6125_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006126 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6127 if (v == NULL)
6128 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006129
6130#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006131 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6132 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6133 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
6134 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
6135 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
6136 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
6137 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
6138 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
6139 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6140 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006141#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006142 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6143 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6144 PyStructSequence_SET_ITEM(v, 2,
6145 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
6146 PyStructSequence_SET_ITEM(v, 3,
6147 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
6148 PyStructSequence_SET_ITEM(v, 4,
6149 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
6150 PyStructSequence_SET_ITEM(v, 5,
6151 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
6152 PyStructSequence_SET_ITEM(v, 6,
6153 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
6154 PyStructSequence_SET_ITEM(v, 7,
6155 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
6156 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6157 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006158#endif
6159
Victor Stinner8c62be82010-05-06 00:08:46 +00006160 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006161}
6162
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006163PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006164"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006165Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006166
6167static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006168posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006169{
Victor Stinner8c62be82010-05-06 00:08:46 +00006170 int fd, res;
6171 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006172
Victor Stinner8c62be82010-05-06 00:08:46 +00006173 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
6174 return NULL;
6175 Py_BEGIN_ALLOW_THREADS
6176 res = fstatvfs(fd, &st);
6177 Py_END_ALLOW_THREADS
6178 if (res != 0)
6179 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006180
Victor Stinner8c62be82010-05-06 00:08:46 +00006181 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006182}
Thomas Wouters477c8d52006-05-27 19:21:47 +00006183#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006184
6185
Thomas Wouters477c8d52006-05-27 19:21:47 +00006186#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006187#include <sys/statvfs.h>
6188
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006189PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006190"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006191Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006192
6193static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006194posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006195{
Victor Stinner8c62be82010-05-06 00:08:46 +00006196 char *path;
6197 int res;
6198 struct statvfs st;
6199 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
6200 return NULL;
6201 Py_BEGIN_ALLOW_THREADS
6202 res = statvfs(path, &st);
6203 Py_END_ALLOW_THREADS
6204 if (res != 0)
6205 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006206
Victor Stinner8c62be82010-05-06 00:08:46 +00006207 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006208}
6209#endif /* HAVE_STATVFS */
6210
Fred Drakec9680921999-12-13 16:37:25 +00006211/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6212 * It maps strings representing configuration variable names to
6213 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006214 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006215 * rarely-used constants. There are three separate tables that use
6216 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006217 *
6218 * This code is always included, even if none of the interfaces that
6219 * need it are included. The #if hackery needed to avoid it would be
6220 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006221 */
6222struct constdef {
6223 char *name;
6224 long value;
6225};
6226
Fred Drake12c6e2d1999-12-14 21:25:03 +00006227static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006228conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00006229 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006230{
Christian Heimes217cfd12007-12-02 14:31:20 +00006231 if (PyLong_Check(arg)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006232 *valuep = PyLong_AS_LONG(arg);
6233 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006234 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00006235 else {
Victor Stinner8c62be82010-05-06 00:08:46 +00006236 /* look up the value in the table using a binary search */
6237 size_t lo = 0;
6238 size_t mid;
6239 size_t hi = tablesize;
6240 int cmp;
6241 const char *confname;
6242 if (!PyUnicode_Check(arg)) {
6243 PyErr_SetString(PyExc_TypeError,
6244 "configuration names must be strings or integers");
Guido van Rossumbce56a62007-05-10 18:04:33 +00006245 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006246 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006247 confname = _PyUnicode_AsString(arg);
6248 if (confname == NULL)
6249 return 0;
6250 while (lo < hi) {
6251 mid = (lo + hi) / 2;
6252 cmp = strcmp(confname, table[mid].name);
6253 if (cmp < 0)
6254 hi = mid;
6255 else if (cmp > 0)
6256 lo = mid + 1;
6257 else {
6258 *valuep = table[mid].value;
6259 return 1;
6260 }
6261 }
6262 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6263 return 0;
6264 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00006265}
6266
6267
6268#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6269static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006270#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006271 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006272#endif
6273#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006274 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006275#endif
Fred Drakec9680921999-12-13 16:37:25 +00006276#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006277 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006278#endif
6279#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00006280 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00006281#endif
6282#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00006283 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00006284#endif
6285#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00006286 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00006287#endif
6288#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006289 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006290#endif
6291#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00006292 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00006293#endif
6294#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00006295 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00006296#endif
6297#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006298 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006299#endif
6300#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006301 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00006302#endif
6303#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006304 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006305#endif
6306#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006307 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00006308#endif
6309#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006310 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006311#endif
6312#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006313 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00006314#endif
6315#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006316 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006317#endif
6318#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00006319 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00006320#endif
6321};
6322
Fred Drakec9680921999-12-13 16:37:25 +00006323static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006324conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006325{
6326 return conv_confname(arg, valuep, posix_constants_pathconf,
6327 sizeof(posix_constants_pathconf)
6328 / sizeof(struct constdef));
6329}
6330#endif
6331
6332#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006333PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006334"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006335Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006336If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006337
6338static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006339posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006340{
6341 PyObject *result = NULL;
6342 int name, fd;
6343
Fred Drake12c6e2d1999-12-14 21:25:03 +00006344 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6345 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006346 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006347
Victor Stinner8c62be82010-05-06 00:08:46 +00006348 errno = 0;
6349 limit = fpathconf(fd, name);
6350 if (limit == -1 && errno != 0)
6351 posix_error();
6352 else
6353 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006354 }
6355 return result;
6356}
6357#endif
6358
6359
6360#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006361PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006362"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006363Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006364If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006365
6366static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006367posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006368{
6369 PyObject *result = NULL;
6370 int name;
6371 char *path;
6372
6373 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6374 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006375 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006376
Victor Stinner8c62be82010-05-06 00:08:46 +00006377 errno = 0;
6378 limit = pathconf(path, name);
6379 if (limit == -1 && errno != 0) {
6380 if (errno == EINVAL)
6381 /* could be a path or name problem */
6382 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00006383 else
Victor Stinner8c62be82010-05-06 00:08:46 +00006384 posix_error_with_filename(path);
6385 }
6386 else
6387 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006388 }
6389 return result;
6390}
6391#endif
6392
6393#ifdef HAVE_CONFSTR
6394static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006395#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00006396 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00006397#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00006398#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006399 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006400#endif
6401#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006402 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006403#endif
Fred Draked86ed291999-12-15 15:34:33 +00006404#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006405 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006406#endif
6407#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006408 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006409#endif
6410#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006411 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006412#endif
6413#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006414 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006415#endif
Fred Drakec9680921999-12-13 16:37:25 +00006416#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006417 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006418#endif
6419#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006420 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006421#endif
6422#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006423 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006424#endif
6425#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006426 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006427#endif
6428#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006429 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006430#endif
6431#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006432 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006433#endif
6434#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006435 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006436#endif
6437#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006438 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006439#endif
Fred Draked86ed291999-12-15 15:34:33 +00006440#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00006441 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00006442#endif
Fred Drakec9680921999-12-13 16:37:25 +00006443#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00006444 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00006445#endif
Fred Draked86ed291999-12-15 15:34:33 +00006446#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006447 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00006448#endif
6449#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006450 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00006451#endif
6452#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006453 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006454#endif
6455#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006456 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00006457#endif
Fred Drakec9680921999-12-13 16:37:25 +00006458#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006459 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006460#endif
6461#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006462 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006463#endif
6464#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006465 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006466#endif
6467#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006468 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006469#endif
6470#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006471 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006472#endif
6473#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006474 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006475#endif
6476#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006477 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006478#endif
6479#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006480 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006481#endif
6482#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006483 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006484#endif
6485#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006486 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006487#endif
6488#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006489 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006490#endif
6491#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006492 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006493#endif
6494#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006495 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006496#endif
6497#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006498 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006499#endif
6500#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006501 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006502#endif
6503#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006504 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006505#endif
Fred Draked86ed291999-12-15 15:34:33 +00006506#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006507 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006508#endif
6509#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006510 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00006511#endif
6512#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00006513 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00006514#endif
6515#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006516 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006517#endif
6518#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006519 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006520#endif
6521#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00006522 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00006523#endif
6524#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006525 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00006526#endif
6527#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00006528 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00006529#endif
6530#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006531 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006532#endif
6533#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006534 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006535#endif
6536#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006537 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006538#endif
6539#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006540 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006541#endif
6542#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00006543 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00006544#endif
Fred Drakec9680921999-12-13 16:37:25 +00006545};
6546
6547static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006548conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006549{
6550 return conv_confname(arg, valuep, posix_constants_confstr,
6551 sizeof(posix_constants_confstr)
6552 / sizeof(struct constdef));
6553}
6554
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006555PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006556"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006557Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006558
6559static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006560posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006561{
6562 PyObject *result = NULL;
6563 int name;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006564 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00006565
6566 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006567 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006568
Fred Drakec9680921999-12-13 16:37:25 +00006569 errno = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006570 len = confstr(name, buffer, sizeof(buffer));
6571 if (len == 0) {
6572 if (errno) {
6573 posix_error();
6574 }
6575 else {
6576 result = Py_None;
6577 Py_INCREF(Py_None);
6578 }
Fred Drakec9680921999-12-13 16:37:25 +00006579 }
6580 else {
Victor Stinner8c62be82010-05-06 00:08:46 +00006581 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz93c56822007-08-26 07:10:06 +00006582 result = PyUnicode_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006583 if (result != NULL)
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00006584 confstr(name, _PyUnicode_AsString(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00006585 }
6586 else
Neal Norwitz93c56822007-08-26 07:10:06 +00006587 result = PyUnicode_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006588 }
6589 }
6590 return result;
6591}
6592#endif
6593
6594
6595#ifdef HAVE_SYSCONF
6596static struct constdef posix_constants_sysconf[] = {
6597#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00006598 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00006599#endif
6600#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00006601 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00006602#endif
6603#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006604 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006605#endif
6606#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006607 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006608#endif
6609#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006610 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006611#endif
6612#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00006613 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00006614#endif
6615#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00006616 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00006617#endif
6618#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006619 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006620#endif
6621#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00006622 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00006623#endif
6624#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006625 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006626#endif
Fred Draked86ed291999-12-15 15:34:33 +00006627#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006628 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006629#endif
6630#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00006631 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00006632#endif
Fred Drakec9680921999-12-13 16:37:25 +00006633#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006634 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006635#endif
Fred Drakec9680921999-12-13 16:37:25 +00006636#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006637 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006638#endif
6639#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006640 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006641#endif
6642#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006643 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006644#endif
6645#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006646 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006647#endif
6648#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006649 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006650#endif
Fred Draked86ed291999-12-15 15:34:33 +00006651#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006652 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00006653#endif
Fred Drakec9680921999-12-13 16:37:25 +00006654#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00006655 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006656#endif
6657#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006658 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006659#endif
6660#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006661 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006662#endif
6663#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006664 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006665#endif
6666#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006667 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006668#endif
Fred Draked86ed291999-12-15 15:34:33 +00006669#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00006670 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00006671#endif
Fred Drakec9680921999-12-13 16:37:25 +00006672#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006673 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006674#endif
6675#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006676 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006677#endif
6678#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006679 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006680#endif
6681#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006682 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006683#endif
6684#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006685 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006686#endif
6687#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006688 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00006689#endif
6690#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006691 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006692#endif
6693#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006694 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006695#endif
6696#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006697 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006698#endif
6699#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006700 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006701#endif
6702#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006703 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006704#endif
6705#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006706 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006707#endif
6708#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006709 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006710#endif
6711#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006712 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006713#endif
6714#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006715 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006716#endif
6717#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006718 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006719#endif
6720#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006721 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00006722#endif
6723#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006724 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006725#endif
6726#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006727 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006728#endif
6729#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006730 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006731#endif
6732#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006733 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006734#endif
6735#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006736 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006737#endif
6738#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006739 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006740#endif
Fred Draked86ed291999-12-15 15:34:33 +00006741#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00006742 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00006743#endif
Fred Drakec9680921999-12-13 16:37:25 +00006744#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006745 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006746#endif
6747#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006748 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006749#endif
6750#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006751 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006752#endif
Fred Draked86ed291999-12-15 15:34:33 +00006753#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006754 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00006755#endif
Fred Drakec9680921999-12-13 16:37:25 +00006756#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00006757 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00006758#endif
Fred Draked86ed291999-12-15 15:34:33 +00006759#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00006760 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00006761#endif
6762#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00006763 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00006764#endif
Fred Drakec9680921999-12-13 16:37:25 +00006765#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006766 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006767#endif
6768#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006769 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006770#endif
6771#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006772 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006773#endif
6774#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006775 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006776#endif
Fred Draked86ed291999-12-15 15:34:33 +00006777#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00006778 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00006779#endif
Fred Drakec9680921999-12-13 16:37:25 +00006780#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00006781 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00006782#endif
6783#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00006784 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00006785#endif
6786#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006787 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006788#endif
6789#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006790 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00006791#endif
6792#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00006793 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00006794#endif
6795#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00006796 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00006797#endif
6798#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00006800#endif
Fred Draked86ed291999-12-15 15:34:33 +00006801#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00006803#endif
Fred Drakec9680921999-12-13 16:37:25 +00006804#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006805 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006806#endif
6807#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006808 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006809#endif
Fred Draked86ed291999-12-15 15:34:33 +00006810#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006811 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006812#endif
Fred Drakec9680921999-12-13 16:37:25 +00006813#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006814 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006815#endif
6816#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006818#endif
6819#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006820 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006821#endif
6822#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006823 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006824#endif
6825#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006827#endif
6828#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006829 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006830#endif
6831#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006832 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006833#endif
6834#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00006835 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00006836#endif
6837#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00006838 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00006839#endif
Fred Draked86ed291999-12-15 15:34:33 +00006840#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00006841 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00006842#endif
6843#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00006844 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00006845#endif
Fred Drakec9680921999-12-13 16:37:25 +00006846#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00006847 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00006848#endif
6849#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006850 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006851#endif
6852#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00006853 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006854#endif
6855#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00006856 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006857#endif
6858#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006859 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006860#endif
6861#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00006862 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006863#endif
6864#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00006865 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00006866#endif
6867#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00006869#endif
6870#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00006871 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00006872#endif
6873#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00006874 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00006875#endif
6876#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00006877 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00006878#endif
6879#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006880 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00006881#endif
6882#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006883 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00006884#endif
6885#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00006886 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00006887#endif
6888#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00006889 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00006890#endif
6891#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00006892 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00006893#endif
6894#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00006895 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00006896#endif
6897#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006898 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006899#endif
6900#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00006901 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00006902#endif
6903#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00006904 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00006905#endif
6906#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006907 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006908#endif
6909#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006910 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006911#endif
6912#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00006913 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00006914#endif
6915#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006916 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006917#endif
6918#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006919 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006920#endif
6921#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00006922 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00006923#endif
6924#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00006925 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00006926#endif
6927#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006928 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006929#endif
6930#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006931 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006932#endif
6933#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006934 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00006935#endif
6936#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006937 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006938#endif
6939#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006940 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006941#endif
6942#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006943 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006944#endif
6945#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006946 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006947#endif
6948#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006949 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006950#endif
Fred Draked86ed291999-12-15 15:34:33 +00006951#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00006952 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00006953#endif
Fred Drakec9680921999-12-13 16:37:25 +00006954#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00006955 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00006956#endif
6957#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006958 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006959#endif
6960#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00006961 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00006962#endif
6963#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006964 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006965#endif
6966#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006967 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006968#endif
6969#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00006970 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00006971#endif
6972#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00006973 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00006974#endif
6975#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00006976 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006977#endif
6978#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00006979 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00006980#endif
6981#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006982 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006983#endif
6984#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00006985 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00006986#endif
6987#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006988 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00006989#endif
6990#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00006991 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00006992#endif
6993#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00006994 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00006995#endif
6996#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00006997 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00006998#endif
6999#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007000 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007001#endif
7002#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007003 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007004#endif
7005#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00007006 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00007007#endif
7008#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007009 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007010#endif
7011#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007012 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007013#endif
7014#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007015 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007016#endif
7017#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007018 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007019#endif
7020#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007021 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007022#endif
7023#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007024 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007025#endif
7026#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00007027 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00007028#endif
7029#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007030 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007031#endif
7032#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007033 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007034#endif
7035#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007036 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007037#endif
7038#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007039 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007040#endif
7041#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00007042 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00007043#endif
7044#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007045 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007046#endif
7047#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00007048 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00007049#endif
7050#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007051 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007052#endif
7053#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00007054 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00007055#endif
7056#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00007057 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00007058#endif
7059#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00007060 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00007061#endif
7062#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00007063 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00007064#endif
7065#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007066 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007067#endif
7068#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00007069 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00007070#endif
7071#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00007072 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00007073#endif
7074#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007075 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007076#endif
7077#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007078 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007079#endif
7080#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00007081 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00007082#endif
7083#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00007084 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00007085#endif
7086#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00007087 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00007088#endif
7089};
7090
7091static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007092conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007093{
7094 return conv_confname(arg, valuep, posix_constants_sysconf,
7095 sizeof(posix_constants_sysconf)
7096 / sizeof(struct constdef));
7097}
7098
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007099PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007100"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007101Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007102
7103static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007104posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007105{
7106 PyObject *result = NULL;
7107 int name;
7108
7109 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7110 int value;
7111
7112 errno = 0;
7113 value = sysconf(name);
7114 if (value == -1 && errno != 0)
7115 posix_error();
7116 else
Christian Heimes217cfd12007-12-02 14:31:20 +00007117 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00007118 }
7119 return result;
7120}
7121#endif
7122
7123
Fred Drakebec628d1999-12-15 18:31:10 +00007124/* This code is used to ensure that the tables of configuration value names
7125 * are in sorted order as required by conv_confname(), and also to build the
7126 * the exported dictionaries that are used to publish information about the
7127 * names available on the host platform.
7128 *
7129 * Sorting the table at runtime ensures that the table is properly ordered
7130 * when used, even for platforms we're not able to test on. It also makes
7131 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007132 */
Fred Drakebec628d1999-12-15 18:31:10 +00007133
7134static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007135cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007136{
7137 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007138 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00007139 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007140 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00007141
7142 return strcmp(c1->name, c2->name);
7143}
7144
7145static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007146setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00007147 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007148{
Fred Drakebec628d1999-12-15 18:31:10 +00007149 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007150 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007151
7152 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7153 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007154 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00007155 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007156
Barry Warsaw3155db32000-04-13 15:20:40 +00007157 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007158 PyObject *o = PyLong_FromLong(table[i].value);
7159 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7160 Py_XDECREF(o);
7161 Py_DECREF(d);
7162 return -1;
7163 }
7164 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007165 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007166 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007167}
7168
Fred Drakebec628d1999-12-15 18:31:10 +00007169/* Return -1 on failure, 0 on success. */
7170static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007171setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007172{
7173#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007174 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007175 sizeof(posix_constants_pathconf)
7176 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007177 "pathconf_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007178 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007179#endif
7180#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007181 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007182 sizeof(posix_constants_confstr)
7183 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007184 "confstr_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007185 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007186#endif
7187#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007188 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007189 sizeof(posix_constants_sysconf)
7190 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007191 "sysconf_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007192 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007193#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007194 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007195}
Fred Draked86ed291999-12-15 15:34:33 +00007196
7197
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007198PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007199"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007200Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007201in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007202
7203static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007204posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007205{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007206 abort();
7207 /*NOTREACHED*/
7208 Py_FatalError("abort() called from Python code didn't abort!");
7209 return NULL;
7210}
Fred Drakebec628d1999-12-15 18:31:10 +00007211
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007212#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007213PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007214"startfile(filepath [, operation]) - Start a file with its associated\n\
7215application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007216\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007217When \"operation\" is not specified or \"open\", this acts like\n\
7218double-clicking the file in Explorer, or giving the file name as an\n\
7219argument to the DOS \"start\" command: the file is opened with whatever\n\
7220application (if any) its extension is associated.\n\
7221When another \"operation\" is given, it specifies what should be done with\n\
7222the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007223\n\
7224startfile returns as soon as the associated application is launched.\n\
7225There is no option to wait for the application to close, and no way\n\
7226to retrieve the application's exit status.\n\
7227\n\
7228The filepath is relative to the current directory. If you want to use\n\
7229an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007230the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007231
7232static PyObject *
7233win32_startfile(PyObject *self, PyObject *args)
7234{
Victor Stinner8c62be82010-05-06 00:08:46 +00007235 PyObject *ofilepath;
7236 char *filepath;
7237 char *operation = NULL;
7238 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00007239
Victor Stinner8c62be82010-05-06 00:08:46 +00007240 PyObject *unipath, *woperation = NULL;
7241 if (!PyArg_ParseTuple(args, "U|s:startfile",
7242 &unipath, &operation)) {
7243 PyErr_Clear();
7244 goto normal;
7245 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007246
Victor Stinner8c62be82010-05-06 00:08:46 +00007247 if (operation) {
7248 woperation = PyUnicode_DecodeASCII(operation,
7249 strlen(operation), NULL);
7250 if (!woperation) {
7251 PyErr_Clear();
7252 operation = NULL;
7253 goto normal;
7254 }
7255 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007256
Victor Stinner8c62be82010-05-06 00:08:46 +00007257 Py_BEGIN_ALLOW_THREADS
7258 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
7259 PyUnicode_AS_UNICODE(unipath),
7260 NULL, NULL, SW_SHOWNORMAL);
7261 Py_END_ALLOW_THREADS
7262
7263 Py_XDECREF(woperation);
7264 if (rc <= (HINSTANCE)32) {
7265 PyObject *errval = win32_error_unicode("startfile",
7266 PyUnicode_AS_UNICODE(unipath));
7267 return errval;
7268 }
7269 Py_INCREF(Py_None);
7270 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007271
7272normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00007273 if (!PyArg_ParseTuple(args, "O&|s:startfile",
7274 PyUnicode_FSConverter, &ofilepath,
7275 &operation))
7276 return NULL;
7277 filepath = PyBytes_AsString(ofilepath);
7278 Py_BEGIN_ALLOW_THREADS
7279 rc = ShellExecute((HWND)0, operation, filepath,
7280 NULL, NULL, SW_SHOWNORMAL);
7281 Py_END_ALLOW_THREADS
7282 if (rc <= (HINSTANCE)32) {
7283 PyObject *errval = win32_error("startfile", filepath);
7284 Py_DECREF(ofilepath);
7285 return errval;
7286 }
7287 Py_DECREF(ofilepath);
7288 Py_INCREF(Py_None);
7289 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007290}
7291#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007292
Martin v. Löwis438b5342002-12-27 10:16:42 +00007293#ifdef HAVE_GETLOADAVG
7294PyDoc_STRVAR(posix_getloadavg__doc__,
7295"getloadavg() -> (float, float, float)\n\n\
7296Return the number of processes in the system run queue averaged over\n\
7297the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7298was unobtainable");
7299
7300static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007301posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007302{
7303 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007304 if (getloadavg(loadavg, 3)!=3) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007305 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7306 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00007307 } else
Victor Stinner8c62be82010-05-06 00:08:46 +00007308 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00007309}
7310#endif
7311
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007312#ifdef MS_WINDOWS
7313
7314PyDoc_STRVAR(win32_urandom__doc__,
7315"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007316Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007317
7318typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7319 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7320 DWORD dwFlags );
7321typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7322 BYTE *pbBuffer );
7323
7324static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00007325/* This handle is never explicitly released. Instead, the operating
7326 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007327static HCRYPTPROV hCryptProv = 0;
7328
Tim Peters4ad82172004-08-30 17:02:04 +00007329static PyObject*
7330win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007331{
Victor Stinner8c62be82010-05-06 00:08:46 +00007332 int howMany;
7333 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007334
Victor Stinner8c62be82010-05-06 00:08:46 +00007335 /* Read arguments */
7336 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7337 return NULL;
7338 if (howMany < 0)
7339 return PyErr_Format(PyExc_ValueError,
7340 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007341
Victor Stinner8c62be82010-05-06 00:08:46 +00007342 if (hCryptProv == 0) {
7343 HINSTANCE hAdvAPI32 = NULL;
7344 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007345
Victor Stinner8c62be82010-05-06 00:08:46 +00007346 /* Obtain handle to the DLL containing CryptoAPI
7347 This should not fail */
7348 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7349 if(hAdvAPI32 == NULL)
7350 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007351
Victor Stinner8c62be82010-05-06 00:08:46 +00007352 /* Obtain pointers to the CryptoAPI functions
7353 This will fail on some early versions of Win95 */
7354 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7355 hAdvAPI32,
7356 "CryptAcquireContextA");
7357 if (pCryptAcquireContext == NULL)
7358 return PyErr_Format(PyExc_NotImplementedError,
7359 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007360
Victor Stinner8c62be82010-05-06 00:08:46 +00007361 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7362 hAdvAPI32, "CryptGenRandom");
7363 if (pCryptGenRandom == NULL)
7364 return PyErr_Format(PyExc_NotImplementedError,
7365 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007366
Victor Stinner8c62be82010-05-06 00:08:46 +00007367 /* Acquire context */
7368 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7369 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7370 return win32_error("CryptAcquireContext", NULL);
7371 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007372
Victor Stinner8c62be82010-05-06 00:08:46 +00007373 /* Allocate bytes */
7374 result = PyBytes_FromStringAndSize(NULL, howMany);
7375 if (result != NULL) {
7376 /* Get random data */
7377 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
7378 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7379 PyBytes_AS_STRING(result))) {
7380 Py_DECREF(result);
7381 return win32_error("CryptGenRandom", NULL);
7382 }
7383 }
7384 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007385}
7386#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007387
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007388PyDoc_STRVAR(device_encoding__doc__,
7389"device_encoding(fd) -> str\n\n\
7390Return a string describing the encoding of the device\n\
7391if the output is a terminal; else return None.");
7392
7393static PyObject *
7394device_encoding(PyObject *self, PyObject *args)
7395{
Victor Stinner8c62be82010-05-06 00:08:46 +00007396 int fd;
7397 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
7398 return NULL;
7399 if (!_PyVerify_fd(fd) || !isatty(fd)) {
7400 Py_INCREF(Py_None);
7401 return Py_None;
7402 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007403#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner8c62be82010-05-06 00:08:46 +00007404 if (fd == 0) {
7405 char buf[100];
7406 sprintf(buf, "cp%d", GetConsoleCP());
7407 return PyUnicode_FromString(buf);
7408 }
7409 if (fd == 1 || fd == 2) {
7410 char buf[100];
7411 sprintf(buf, "cp%d", GetConsoleOutputCP());
7412 return PyUnicode_FromString(buf);
7413 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007414#elif defined(CODESET)
Victor Stinner8c62be82010-05-06 00:08:46 +00007415 {
7416 char *codeset = nl_langinfo(CODESET);
7417 if (codeset != NULL && codeset[0] != 0)
7418 return PyUnicode_FromString(codeset);
7419 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007420#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007421 Py_INCREF(Py_None);
7422 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007423}
7424
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007425#ifdef __VMS
7426/* Use openssl random routine */
7427#include <openssl/rand.h>
7428PyDoc_STRVAR(vms_urandom__doc__,
7429"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007430Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007431
7432static PyObject*
7433vms_urandom(PyObject *self, PyObject *args)
7434{
Victor Stinner8c62be82010-05-06 00:08:46 +00007435 int howMany;
7436 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007437
Victor Stinner8c62be82010-05-06 00:08:46 +00007438 /* Read arguments */
7439 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7440 return NULL;
7441 if (howMany < 0)
7442 return PyErr_Format(PyExc_ValueError,
7443 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007444
Victor Stinner8c62be82010-05-06 00:08:46 +00007445 /* Allocate bytes */
7446 result = PyBytes_FromStringAndSize(NULL, howMany);
7447 if (result != NULL) {
7448 /* Get random data */
7449 if (RAND_pseudo_bytes((unsigned char*)
7450 PyBytes_AS_STRING(result),
7451 howMany) < 0) {
7452 Py_DECREF(result);
7453 return PyErr_Format(PyExc_ValueError,
7454 "RAND_pseudo_bytes");
7455 }
7456 }
7457 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007458}
7459#endif
7460
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007461#ifdef HAVE_SETRESUID
7462PyDoc_STRVAR(posix_setresuid__doc__,
7463"setresuid(ruid, euid, suid)\n\n\
7464Set the current process's real, effective, and saved user ids.");
7465
7466static PyObject*
7467posix_setresuid (PyObject *self, PyObject *args)
7468{
Victor Stinner8c62be82010-05-06 00:08:46 +00007469 /* We assume uid_t is no larger than a long. */
7470 long ruid, euid, suid;
7471 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
7472 return NULL;
7473 if (setresuid(ruid, euid, suid) < 0)
7474 return posix_error();
7475 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007476}
7477#endif
7478
7479#ifdef HAVE_SETRESGID
7480PyDoc_STRVAR(posix_setresgid__doc__,
7481"setresgid(rgid, egid, sgid)\n\n\
7482Set the current process's real, effective, and saved group ids.");
7483
7484static PyObject*
7485posix_setresgid (PyObject *self, PyObject *args)
7486{
Victor Stinner8c62be82010-05-06 00:08:46 +00007487 /* We assume uid_t is no larger than a long. */
7488 long rgid, egid, sgid;
7489 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
7490 return NULL;
7491 if (setresgid(rgid, egid, sgid) < 0)
7492 return posix_error();
7493 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007494}
7495#endif
7496
7497#ifdef HAVE_GETRESUID
7498PyDoc_STRVAR(posix_getresuid__doc__,
7499"getresuid() -> (ruid, euid, suid)\n\n\
7500Get tuple of the current process's real, effective, and saved user ids.");
7501
7502static PyObject*
7503posix_getresuid (PyObject *self, PyObject *noargs)
7504{
Victor Stinner8c62be82010-05-06 00:08:46 +00007505 uid_t ruid, euid, suid;
7506 long l_ruid, l_euid, l_suid;
7507 if (getresuid(&ruid, &euid, &suid) < 0)
7508 return posix_error();
7509 /* Force the values into long's as we don't know the size of uid_t. */
7510 l_ruid = ruid;
7511 l_euid = euid;
7512 l_suid = suid;
7513 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007514}
7515#endif
7516
7517#ifdef HAVE_GETRESGID
7518PyDoc_STRVAR(posix_getresgid__doc__,
7519"getresgid() -> (rgid, egid, sgid)\n\n\
7520Get tuple of the current process's real, effective, and saved user ids.");
7521
7522static PyObject*
7523posix_getresgid (PyObject *self, PyObject *noargs)
7524{
Victor Stinner8c62be82010-05-06 00:08:46 +00007525 uid_t rgid, egid, sgid;
7526 long l_rgid, l_egid, l_sgid;
7527 if (getresgid(&rgid, &egid, &sgid) < 0)
7528 return posix_error();
7529 /* Force the values into long's as we don't know the size of uid_t. */
7530 l_rgid = rgid;
7531 l_egid = egid;
7532 l_sgid = sgid;
7533 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007534}
7535#endif
7536
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007537static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00007538 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007539#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007540 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007541#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007542 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007543#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007544 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007545#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007546 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007547#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007548 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007549#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007550#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007551 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007552#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00007553#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007554 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007555#endif /* HAVE_LCHMOD */
7556#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007557 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007558#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00007559#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007560 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007561#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007562#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007563 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007564#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007565#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +00007566 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00007567#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007568#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +00007569 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007570#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007571#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +00007572 {"getcwd", (PyCFunction)posix_getcwd_unicode,
7573 METH_NOARGS, posix_getcwd__doc__},
7574 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
7575 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007576#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007577#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007578 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007579#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +00007580 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7581 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7582 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007583#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +00007584 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007585#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007586#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007587 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007588#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007589#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7590 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
7591#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7592 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7593 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7594 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +00007595 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007596#ifdef HAVE_SYMLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007597 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007598#endif /* HAVE_SYMLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007599#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin74e45612010-07-09 15:58:59 +00007600 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
7601 win_symlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007602#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007603#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +00007604 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007605#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007606 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007607#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007608 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007609#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +00007610 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7611 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7612 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007613#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00007614 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007615#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00007616 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007617#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +00007618 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7619 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007620#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007621#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +00007622 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7623 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007624#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00007625 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7626 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007627#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007628#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007629#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +00007630 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007631#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007632#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +00007633 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007634#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007635#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +00007636 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007637#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007638#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007639 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007640#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007641#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007642 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007643#endif /* HAVE_GETEGID */
7644#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007645 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007646#endif /* HAVE_GETEUID */
7647#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007648 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007649#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007650#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007651 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007652#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007653 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007654#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007655 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007656#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007657#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +00007658 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007659#endif /* HAVE_GETPPID */
7660#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007661 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007662#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007663#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007664 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007665#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007666#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +00007667 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007668#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007669#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +00007670 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007671#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007672#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007673 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007674#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007675#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007676 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7677 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +00007678#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007679#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007680 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007681#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007682#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007683 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007684#endif /* HAVE_SETEUID */
7685#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007686 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007687#endif /* HAVE_SETEGID */
7688#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007689 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007690#endif /* HAVE_SETREUID */
7691#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007692 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007693#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007694#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007695 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007696#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007697#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007698 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007699#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +00007700#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007701 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +00007702#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007703#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007704 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00007705#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007706#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007707 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007708#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007709#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007710 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007711#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007712#ifdef HAVE_WAIT3
Victor Stinner8c62be82010-05-06 00:08:46 +00007713 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007714#endif /* HAVE_WAIT3 */
7715#ifdef HAVE_WAIT4
Victor Stinner8c62be82010-05-06 00:08:46 +00007716 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007717#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007718#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007719 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007720#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007721#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007722 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007723#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007724#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007725 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007726#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007727#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007728 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007729#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007730#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007731 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007732#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007733#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007734 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007735#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +00007736 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7737 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7738 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
7739 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
7740 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7741 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7742 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7743 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7744 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7745 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7746 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007747#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +00007748 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007749#endif
7750#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +00007751 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007752#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007753#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +00007754 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007755#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007756#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +00007757 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7758 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7759 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007760#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007761#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +00007762 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007763#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007764#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007765 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007766#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007767#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007768 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00007769#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007770 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007771#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +00007772 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007773#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007774#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007775 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007776#endif
7777#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007778 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007779#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007780#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007781#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +00007782 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00007783#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007784#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00007785 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007786#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007787#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +00007788 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007789#endif /* WIFSTOPPED */
7790#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +00007791 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007792#endif /* WIFSIGNALED */
7793#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +00007794 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007795#endif /* WIFEXITED */
7796#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +00007797 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007798#endif /* WEXITSTATUS */
7799#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007800 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007801#endif /* WTERMSIG */
7802#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007803 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007804#endif /* WSTOPSIG */
7805#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007806#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007807 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007808#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007809#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007810 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007811#endif
Fred Drakec9680921999-12-13 16:37:25 +00007812#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +00007813 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007814#endif
7815#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007816 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007817#endif
7818#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007819 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007820#endif
7821#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007822 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007823#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007824 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007825#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007826 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +00007827 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Mark Hammondef8b6542001-05-13 08:04:26 +00007828#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007829#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +00007830 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007831#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007832 #ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007833 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007834 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007835 #ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007836 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007837 #endif
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007838#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007839 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007840#endif
7841#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007842 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007843#endif
7844#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007845 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007846#endif
7847#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007848 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007849#endif
7850
Victor Stinner8c62be82010-05-06 00:08:46 +00007851 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007852};
7853
7854
Barry Warsaw4a342091996-12-19 23:50:02 +00007855static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007856ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007857{
Victor Stinner8c62be82010-05-06 00:08:46 +00007858 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007859}
7860
Guido van Rossumd48f2521997-12-05 22:19:34 +00007861#if defined(PYOS_OS2)
7862/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007863static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007864{
7865 APIRET rc;
7866 ULONG values[QSV_MAX+1];
7867 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007868 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007869
7870 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007871 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007872 Py_END_ALLOW_THREADS
7873
7874 if (rc != NO_ERROR) {
7875 os2_error(rc);
7876 return -1;
7877 }
7878
Fred Drake4d1e64b2002-04-15 19:40:07 +00007879 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7880 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7881 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7882 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7883 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7884 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7885 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007886
7887 switch (values[QSV_VERSION_MINOR]) {
7888 case 0: ver = "2.00"; break;
7889 case 10: ver = "2.10"; break;
7890 case 11: ver = "2.11"; break;
7891 case 30: ver = "3.00"; break;
7892 case 40: ver = "4.00"; break;
7893 case 50: ver = "5.00"; break;
7894 default:
Tim Peters885d4572001-11-28 20:27:42 +00007895 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +00007896 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00007897 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007898 ver = &tmp[0];
7899 }
7900
7901 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007902 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007903 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007904
7905 /* Add Indicator of Which Drive was Used to Boot the System */
7906 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7907 tmp[1] = ':';
7908 tmp[2] = '\0';
7909
Fred Drake4d1e64b2002-04-15 19:40:07 +00007910 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007911}
7912#endif
7913
Barry Warsaw4a342091996-12-19 23:50:02 +00007914static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007915all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007916{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007917#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00007918 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007919#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007920#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00007921 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007922#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007923#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00007924 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007925#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007926#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00007927 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007928#endif
Fred Drakec9680921999-12-13 16:37:25 +00007929#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007930 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00007931#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007932#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007933 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007934#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007935#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00007936 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00007937#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007938#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +00007939 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007940#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007941#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +00007942 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00007943#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007944#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00007945 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007946#endif
7947#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00007948 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007949#endif
7950#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +00007951 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007952#endif
7953#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +00007954 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007955#endif
7956#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007957 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007958#endif
7959#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +00007960 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007961#endif
7962#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007963 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007964#endif
7965#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007966 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007967#endif
7968#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007969 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007970#endif
7971#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007972 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007973#endif
7974#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00007975 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007976#endif
7977#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +00007978 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007979#endif
7980#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007981 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007982#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007983#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +00007984 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00007985#endif
7986#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +00007987 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00007988#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007989#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00007990 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007991#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007992#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007993 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00007994#endif
7995#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007996 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00007997#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007998
Tim Peters5aa91602002-01-30 05:46:57 +00007999/* MS Windows */
8000#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008001 /* Don't inherit in child processes. */
8002 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008003#endif
8004#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +00008005 /* Optimize for short life (keep in memory). */
8006 /* MS forgot to define this one with a non-underscore form too. */
8007 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008008#endif
8009#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008010 /* Automatically delete when last handle is closed. */
8011 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008012#endif
8013#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +00008014 /* Optimize for random access. */
8015 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008016#endif
8017#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008018 /* Optimize for sequential access. */
8019 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008020#endif
8021
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008022/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008023#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008024 /* Send a SIGIO signal whenever input or output
8025 becomes available on file descriptor */
8026 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008027#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008028#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008029 /* Direct disk access. */
8030 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008031#endif
8032#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +00008033 /* Must be a directory. */
8034 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008035#endif
8036#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +00008037 /* Do not follow links. */
8038 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008039#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008040#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +00008041 /* Do not update the access time. */
8042 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008043#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008044
Victor Stinner8c62be82010-05-06 00:08:46 +00008045 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008046#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008047 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008048#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008049#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008050 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008051#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008052#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008053 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008054#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008055#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008056 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008057#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008058#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +00008059 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008060#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008061#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +00008062 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008063#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008064#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008065 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008066#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008067#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +00008068 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008069#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008070#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008071 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008072#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008073#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008074 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008075#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008076#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008077 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008078#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008079#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008080 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008081#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008082#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +00008083 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008084#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008085#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +00008086 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008087#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008088#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008089 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008090#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008091#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008092 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008093#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008094#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +00008095 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008096#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008097
Guido van Rossum246bc171999-02-01 23:54:31 +00008098#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008099#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00008100 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8101 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8102 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8103 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8104 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8105 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8106 if (ins(d, "P_PM", (long)P_PM)) return -1;
8107 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8108 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8109 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8110 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8111 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8112 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8113 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8114 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8115 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8116 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8117 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8118 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8119 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008120#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008121 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8122 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8123 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8124 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8125 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008126#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008127#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008128
Guido van Rossumd48f2521997-12-05 22:19:34 +00008129#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00008130 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008131#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008132 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00008133}
8134
8135
Tim Peters5aa91602002-01-30 05:46:57 +00008136#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008137#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008138#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008139
8140#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008141#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008142#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008143
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008144#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00008145#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008146#define MODNAME "posix"
8147#endif
8148
Martin v. Löwis1a214512008-06-11 05:26:20 +00008149static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +00008150 PyModuleDef_HEAD_INIT,
8151 MODNAME,
8152 posix__doc__,
8153 -1,
8154 posix_methods,
8155 NULL,
8156 NULL,
8157 NULL,
8158 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00008159};
8160
8161
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008162PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008163INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008164{
Victor Stinner8c62be82010-05-06 00:08:46 +00008165 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008166
Victor Stinner8c62be82010-05-06 00:08:46 +00008167 m = PyModule_Create(&posixmodule);
8168 if (m == NULL)
8169 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008170
Victor Stinner8c62be82010-05-06 00:08:46 +00008171 /* Initialize environ dictionary */
8172 v = convertenviron();
8173 Py_XINCREF(v);
8174 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
8175 return NULL;
8176 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008177
Victor Stinner8c62be82010-05-06 00:08:46 +00008178 if (all_ins(m))
8179 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00008180
Victor Stinner8c62be82010-05-06 00:08:46 +00008181 if (setup_confname_tables(m))
8182 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00008183
Victor Stinner8c62be82010-05-06 00:08:46 +00008184 Py_INCREF(PyExc_OSError);
8185 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008186
Guido van Rossumb3d39562000-01-31 18:41:26 +00008187#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00008188 if (posix_putenv_garbage == NULL)
8189 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008190#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008191
Victor Stinner8c62be82010-05-06 00:08:46 +00008192 if (!initialized) {
8193 stat_result_desc.name = MODNAME ".stat_result";
8194 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8195 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8196 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8197 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8198 structseq_new = StatResultType.tp_new;
8199 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008200
Victor Stinner8c62be82010-05-06 00:08:46 +00008201 statvfs_result_desc.name = MODNAME ".statvfs_result";
8202 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008203#ifdef NEED_TICKS_PER_SECOND
8204# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +00008205 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008206# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +00008207 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008208# else
Victor Stinner8c62be82010-05-06 00:08:46 +00008209 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008210# endif
8211#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008212 }
8213 Py_INCREF((PyObject*) &StatResultType);
8214 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
8215 Py_INCREF((PyObject*) &StatVFSResultType);
8216 PyModule_AddObject(m, "statvfs_result",
8217 (PyObject*) &StatVFSResultType);
8218 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008219
8220#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +00008221 /*
8222 * Step 2 of weak-linking support on Mac OS X.
8223 *
8224 * The code below removes functions that are not available on the
8225 * currently active platform.
8226 *
8227 * This block allow one to use a python binary that was build on
8228 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8229 * OSX 10.4.
8230 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008231#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008232 if (fstatvfs == NULL) {
8233 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8234 return NULL;
8235 }
8236 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008237#endif /* HAVE_FSTATVFS */
8238
8239#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008240 if (statvfs == NULL) {
8241 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8242 return NULL;
8243 }
8244 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008245#endif /* HAVE_STATVFS */
8246
8247# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00008248 if (lchown == NULL) {
8249 if (PyObject_DelAttrString(m, "lchown") == -1) {
8250 return NULL;
8251 }
8252 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008253#endif /* HAVE_LCHOWN */
8254
8255
8256#endif /* __APPLE__ */
Victor Stinner8c62be82010-05-06 00:08:46 +00008257 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008258
Guido van Rossumb6775db1994-08-01 11:34:53 +00008259}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008260
8261#ifdef __cplusplus
8262}
8263#endif