blob: 6fb990a0272fb19b68fdb480eadf5136dffec95a [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");
1120 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA && Py_GetFinalPathNameByHandleW;
1121 }
1122 return has_GetFinalPathNameByHandle;
1123}
1124
1125static int
1126win32_stat(const char* path, struct win32_stat *result)
1127{
1128 /* Traverse the symlink to the target using
1129 GetFinalPathNameByHandle()
1130 */
1131 int code;
1132 HANDLE hFile;
1133 int buf_size;
1134 char *target_path;
1135 int result_length;
1136 WIN32_FILE_ATTRIBUTE_DATA info;
1137
1138 if(!check_GetFinalPathNameByHandle()) {
1139 /* if the OS doesn't have GetFinalPathNameByHandle, it doesn't
1140 have symlinks, so just fall back to the traditional behavior
1141 found in lstat. */
1142 return win32_lstat(path, result);
1143 }
1144
1145 hFile = CreateFileA(
1146 path,
1147 0, /* desired access */
1148 0, /* share mode */
1149 NULL, /* security attributes */
1150 OPEN_EXISTING,
1151 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
1152 FILE_FLAG_BACKUP_SEMANTICS,
1153 NULL);
1154
1155 if(hFile == INVALID_HANDLE_VALUE) {
1156 /* Either the target doesn't exist, or we don't have access to
1157 get a handle to it. If the former, we need to return an error.
1158 If the latter, we can use attributes_from_dir. */
1159 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1160 /* Protocol violation: we explicitly clear errno, instead of
1161 setting it to a POSIX error. Callers should use GetLastError. */
1162 errno = 0;
1163 return -1;
1164 } else {
1165 /* Could not get attributes on open file. Fall back to
1166 reading the directory. */
1167 if (!attributes_from_dir(path, &info)) {
1168 /* Very strange. This should not fail now */
1169 errno = 0;
1170 return -1;
1171 }
1172 }
1173 code = attribute_data_to_stat(&info, result);
1174 }
1175
1176 buf_size = Py_GetFinalPathNameByHandleA(hFile, 0, 0, VOLUME_NAME_DOS);
1177 if(!buf_size) return -1;
1178 target_path = (char *)malloc((buf_size+1)*sizeof(char));
1179 result_length = Py_GetFinalPathNameByHandleA(hFile, target_path,
1180 buf_size, VOLUME_NAME_DOS);
1181
1182 if(!result_length)
1183 return -1;
1184
1185 if(!CloseHandle(hFile))
1186 return -1;
1187
1188 target_path[result_length] = 0;
1189 code = win32_lstat(target_path, result);
1190 free(target_path);
1191
1192 return code;
1193}
1194
1195static int
1196win32_stat_w(const wchar_t* path, struct win32_stat *result)
1197{
1198 /* Traverse the symlink to the target using GetFinalPathNameByHandle() */
1199 int code;
1200 HANDLE hFile;
1201 int buf_size;
1202 wchar_t *target_path;
1203 int result_length;
1204 WIN32_FILE_ATTRIBUTE_DATA info;
1205
1206 if(!check_GetFinalPathNameByHandle()) {
1207 /* If the OS doesn't have GetFinalPathNameByHandle, it doesn't have
1208 symlinks, so just fall back to the traditional behavior found
1209 in lstat. */
1210 return win32_lstat_w(path, result);
1211 }
1212
1213 hFile = CreateFileW(
1214 path,
1215 0, /* desired access */
1216 0, /* share mode */
1217 NULL, /* security attributes */
1218 OPEN_EXISTING,
1219 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
1220 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1221 NULL);
1222
1223 if(hFile == INVALID_HANDLE_VALUE) {
1224 /* Either the target doesn't exist, or we don't have access to
1225 get a handle to it. If the former, we need to return an error.
1226 If the latter, we can use attributes_from_dir. */
1227 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1228 /* Protocol violation: we explicitly clear errno, instead of
1229 setting it to a POSIX error. Callers should use GetLastError. */
1230 errno = 0;
1231 return -1;
1232 } else {
Victor Stinner8c62be82010-05-06 00:08:46 +00001233 /* Could not get attributes on open file. Fall back to
1234 reading the directory. */
1235 if (!attributes_from_dir_w(path, &info)) {
1236 /* Very strange. This should not fail now */
1237 errno = 0;
1238 return -1;
1239 }
1240 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001241 code = attribute_data_to_stat(&info, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001242 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001243 else {
1244 /* We have a good handle to the target, use it to determine the target
1245 path name (then we'll call lstat on it). */
1246 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_DOS);
1247 if(!buf_size)
1248 return -1;
1249
1250 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
1251 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
1252 buf_size, VOLUME_NAME_DOS);
1253
1254 if(!result_length)
1255 return -1;
1256
1257 if(!CloseHandle(hFile))
1258 return -1;
1259
1260 target_path[result_length] = 0;
1261 code = win32_lstat_w(target_path, result);
1262 free(target_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001263 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001264
Victor Stinner8c62be82010-05-06 00:08:46 +00001265 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001266}
1267
1268static int
1269win32_fstat(int file_number, struct win32_stat *result)
1270{
Victor Stinner8c62be82010-05-06 00:08:46 +00001271 BY_HANDLE_FILE_INFORMATION info;
1272 HANDLE h;
1273 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001274
Victor Stinner8c62be82010-05-06 00:08:46 +00001275 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001276
Victor Stinner8c62be82010-05-06 00:08:46 +00001277 /* Protocol violation: we explicitly clear errno, instead of
1278 setting it to a POSIX error. Callers should use GetLastError. */
1279 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001280
Victor Stinner8c62be82010-05-06 00:08:46 +00001281 if (h == INVALID_HANDLE_VALUE) {
1282 /* This is really a C library error (invalid file handle).
1283 We set the Win32 error to the closes one matching. */
1284 SetLastError(ERROR_INVALID_HANDLE);
1285 return -1;
1286 }
1287 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001288
Victor Stinner8c62be82010-05-06 00:08:46 +00001289 type = GetFileType(h);
1290 if (type == FILE_TYPE_UNKNOWN) {
1291 DWORD error = GetLastError();
1292 if (error != 0) {
1293 return -1;
1294 }
1295 /* else: valid but unknown file */
1296 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001297
Victor Stinner8c62be82010-05-06 00:08:46 +00001298 if (type != FILE_TYPE_DISK) {
1299 if (type == FILE_TYPE_CHAR)
1300 result->st_mode = _S_IFCHR;
1301 else if (type == FILE_TYPE_PIPE)
1302 result->st_mode = _S_IFIFO;
1303 return 0;
1304 }
1305
1306 if (!GetFileInformationByHandle(h, &info)) {
1307 return -1;
1308 }
1309
1310 /* similar to stat() */
1311 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1312 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1313 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1314 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1315 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1316 /* specific to fstat() */
1317 result->st_nlink = info.nNumberOfLinks;
1318 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1319 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001320}
1321
1322#endif /* MS_WINDOWS */
1323
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001324PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001325"stat_result: Result from stat or lstat.\n\n\
1326This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001327 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001328or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1329\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001330Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1331or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001332\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001333See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001334
1335static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001336 {"st_mode", "protection bits"},
1337 {"st_ino", "inode"},
1338 {"st_dev", "device"},
1339 {"st_nlink", "number of hard links"},
1340 {"st_uid", "user ID of owner"},
1341 {"st_gid", "group ID of owner"},
1342 {"st_size", "total size, in bytes"},
1343 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1344 {NULL, "integer time of last access"},
1345 {NULL, "integer time of last modification"},
1346 {NULL, "integer time of last change"},
1347 {"st_atime", "time of last access"},
1348 {"st_mtime", "time of last modification"},
1349 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001350#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001351 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001352#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001353#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001354 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001355#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001356#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001357 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001358#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001359#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001360 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001361#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001362#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001363 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001364#endif
1365#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001366 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001367#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001368 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001369};
1370
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001371#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001372#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001373#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001374#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001375#endif
1376
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001377#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001378#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1379#else
1380#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1381#endif
1382
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001383#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001384#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1385#else
1386#define ST_RDEV_IDX ST_BLOCKS_IDX
1387#endif
1388
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001389#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1390#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1391#else
1392#define ST_FLAGS_IDX ST_RDEV_IDX
1393#endif
1394
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001395#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001396#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001397#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001398#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001399#endif
1400
1401#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1402#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1403#else
1404#define ST_BIRTHTIME_IDX ST_GEN_IDX
1405#endif
1406
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001407static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001408 "stat_result", /* name */
1409 stat_result__doc__, /* doc */
1410 stat_result_fields,
1411 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001412};
1413
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001414PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001415"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1416This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001417 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001418or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001419\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001420See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001421
1422static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001423 {"f_bsize", },
1424 {"f_frsize", },
1425 {"f_blocks", },
1426 {"f_bfree", },
1427 {"f_bavail", },
1428 {"f_files", },
1429 {"f_ffree", },
1430 {"f_favail", },
1431 {"f_flag", },
1432 {"f_namemax",},
1433 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001434};
1435
1436static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001437 "statvfs_result", /* name */
1438 statvfs_result__doc__, /* doc */
1439 statvfs_result_fields,
1440 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001441};
1442
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001443static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001444static PyTypeObject StatResultType;
1445static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001446static newfunc structseq_new;
1447
1448static PyObject *
1449statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1450{
Victor Stinner8c62be82010-05-06 00:08:46 +00001451 PyStructSequence *result;
1452 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001453
Victor Stinner8c62be82010-05-06 00:08:46 +00001454 result = (PyStructSequence*)structseq_new(type, args, kwds);
1455 if (!result)
1456 return NULL;
1457 /* If we have been initialized from a tuple,
1458 st_?time might be set to None. Initialize it
1459 from the int slots. */
1460 for (i = 7; i <= 9; i++) {
1461 if (result->ob_item[i+3] == Py_None) {
1462 Py_DECREF(Py_None);
1463 Py_INCREF(result->ob_item[i]);
1464 result->ob_item[i+3] = result->ob_item[i];
1465 }
1466 }
1467 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001468}
1469
1470
1471
1472/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001473static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001474
1475PyDoc_STRVAR(stat_float_times__doc__,
1476"stat_float_times([newval]) -> oldval\n\n\
1477Determine whether os.[lf]stat represents time stamps as float objects.\n\
1478If newval is True, future calls to stat() return floats, if it is False,\n\
1479future calls return ints. \n\
1480If newval is omitted, return the current setting.\n");
1481
1482static PyObject*
1483stat_float_times(PyObject* self, PyObject *args)
1484{
Victor Stinner8c62be82010-05-06 00:08:46 +00001485 int newval = -1;
1486 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1487 return NULL;
1488 if (newval == -1)
1489 /* Return old value */
1490 return PyBool_FromLong(_stat_float_times);
1491 _stat_float_times = newval;
1492 Py_INCREF(Py_None);
1493 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001494}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001495
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001496static void
1497fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1498{
Victor Stinner8c62be82010-05-06 00:08:46 +00001499 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001500#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner8c62be82010-05-06 00:08:46 +00001501 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001502#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001503 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001504#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001505 if (!ival)
1506 return;
1507 if (_stat_float_times) {
1508 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1509 } else {
1510 fval = ival;
1511 Py_INCREF(fval);
1512 }
1513 PyStructSequence_SET_ITEM(v, index, ival);
1514 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001515}
1516
Tim Peters5aa91602002-01-30 05:46:57 +00001517/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001518 (used by posix_stat() and posix_fstat()) */
1519static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001520_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001521{
Victor Stinner8c62be82010-05-06 00:08:46 +00001522 unsigned long ansec, mnsec, cnsec;
1523 PyObject *v = PyStructSequence_New(&StatResultType);
1524 if (v == NULL)
1525 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001526
Victor Stinner8c62be82010-05-06 00:08:46 +00001527 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001528#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001529 PyStructSequence_SET_ITEM(v, 1,
1530 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001531#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001532 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001533#endif
1534#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001535 PyStructSequence_SET_ITEM(v, 2,
1536 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001537#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001538 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001539#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001540 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1541 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1542 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001543#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001544 PyStructSequence_SET_ITEM(v, 6,
1545 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001546#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001547 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001548#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001549
Martin v. Löwis14694662006-02-03 12:54:16 +00001550#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001551 ansec = st->st_atim.tv_nsec;
1552 mnsec = st->st_mtim.tv_nsec;
1553 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001554#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001555 ansec = st->st_atimespec.tv_nsec;
1556 mnsec = st->st_mtimespec.tv_nsec;
1557 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001558#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001559 ansec = st->st_atime_nsec;
1560 mnsec = st->st_mtime_nsec;
1561 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001562#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001563 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001564#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001565 fill_time(v, 7, st->st_atime, ansec);
1566 fill_time(v, 8, st->st_mtime, mnsec);
1567 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001568
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001569#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001570 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1571 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001572#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001573#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001574 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1575 PyLong_FromLong((long)st->st_blocks));
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_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001578 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1579 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001580#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001581#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001582 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1583 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001584#endif
1585#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001586 {
1587 PyObject *val;
1588 unsigned long bsec,bnsec;
1589 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001590#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner8c62be82010-05-06 00:08:46 +00001591 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001592#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001593 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001594#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001595 if (_stat_float_times) {
1596 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1597 } else {
1598 val = PyLong_FromLong((long)bsec);
1599 }
1600 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1601 val);
1602 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001603#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001604#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001605 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1606 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001607#endif
Fred Drake699f3522000-06-29 21:12:41 +00001608
Victor Stinner8c62be82010-05-06 00:08:46 +00001609 if (PyErr_Occurred()) {
1610 Py_DECREF(v);
1611 return NULL;
1612 }
Fred Drake699f3522000-06-29 21:12:41 +00001613
Victor Stinner8c62be82010-05-06 00:08:46 +00001614 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001615}
1616
Martin v. Löwisd8948722004-06-02 09:57:56 +00001617#ifdef MS_WINDOWS
1618
1619/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1620 where / can be used in place of \ and the trailing slash is optional.
1621 Both SERVER and SHARE must have at least one character.
1622*/
1623
1624#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1625#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001626#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001627#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001628#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001629
Tim Peters4ad82172004-08-30 17:02:04 +00001630static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001631IsUNCRootA(char *path, int pathlen)
1632{
Victor Stinner8c62be82010-05-06 00:08:46 +00001633 #define ISSLASH ISSLASHA
Martin v. Löwisd8948722004-06-02 09:57:56 +00001634
Victor Stinner8c62be82010-05-06 00:08:46 +00001635 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001636
Victor Stinner8c62be82010-05-06 00:08:46 +00001637 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1638 /* minimum UNCRoot is \\x\y */
1639 return FALSE;
1640 for (i = 2; i < pathlen ; i++)
1641 if (ISSLASH(path[i])) break;
1642 if (i == 2 || i == pathlen)
1643 /* do not allow \\\SHARE or \\SERVER */
1644 return FALSE;
1645 share = i+1;
1646 for (i = share; i < pathlen; i++)
1647 if (ISSLASH(path[i])) break;
1648 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001649
Victor Stinner8c62be82010-05-06 00:08:46 +00001650 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001651}
1652
Tim Peters4ad82172004-08-30 17:02:04 +00001653static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001654IsUNCRootW(Py_UNICODE *path, int pathlen)
1655{
Victor Stinner8c62be82010-05-06 00:08:46 +00001656 #define ISSLASH ISSLASHW
Martin v. Löwisd8948722004-06-02 09:57:56 +00001657
Victor Stinner8c62be82010-05-06 00:08:46 +00001658 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001659
Victor Stinner8c62be82010-05-06 00:08:46 +00001660 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1661 /* minimum UNCRoot is \\x\y */
1662 return FALSE;
1663 for (i = 2; i < pathlen ; i++)
1664 if (ISSLASH(path[i])) break;
1665 if (i == 2 || i == pathlen)
1666 /* do not allow \\\SHARE or \\SERVER */
1667 return FALSE;
1668 share = i+1;
1669 for (i = share; i < pathlen; i++)
1670 if (ISSLASH(path[i])) break;
1671 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001672
Victor Stinner8c62be82010-05-06 00:08:46 +00001673 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001674}
Martin v. Löwisd8948722004-06-02 09:57:56 +00001675#endif /* MS_WINDOWS */
1676
Barry Warsaw53699e91996-12-10 23:23:01 +00001677static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001678posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +00001679 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001680#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00001681 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001682#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001683 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001684#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001685 char *wformat,
1686 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001687{
Victor Stinner8c62be82010-05-06 00:08:46 +00001688 STRUCT_STAT st;
1689 PyObject *opath;
1690 char *path;
1691 int res;
1692 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001693
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001694#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001695 PyUnicodeObject *po;
1696 if (PyArg_ParseTuple(args, wformat, &po)) {
1697 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001698
Victor Stinner8c62be82010-05-06 00:08:46 +00001699 Py_BEGIN_ALLOW_THREADS
1700 /* PyUnicode_AS_UNICODE result OK without
1701 thread lock as it is a simple dereference. */
1702 res = wstatfunc(wpath, &st);
1703 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001704
Victor Stinner8c62be82010-05-06 00:08:46 +00001705 if (res != 0)
1706 return win32_error_unicode("stat", wpath);
1707 return _pystat_fromstructstat(&st);
1708 }
1709 /* Drop the argument parsing error as narrow strings
1710 are also valid. */
1711 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001712#endif
1713
Victor Stinner8c62be82010-05-06 00:08:46 +00001714 if (!PyArg_ParseTuple(args, format,
1715 PyUnicode_FSConverter, &opath))
1716 return NULL;
1717 path = PyBytes_AsString(opath);
1718 Py_BEGIN_ALLOW_THREADS
1719 res = (*statfunc)(path, &st);
1720 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001721
Victor Stinner8c62be82010-05-06 00:08:46 +00001722 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001723#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001724 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001725#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001726 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001727#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001728 }
1729 else
1730 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001731
Victor Stinner8c62be82010-05-06 00:08:46 +00001732 Py_DECREF(opath);
1733 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001734}
1735
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001736/* POSIX methods */
1737
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001738PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001739"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001740Use the real uid/gid to test for access to a path. Note that most\n\
1741operations will use the effective uid/gid, therefore this routine can\n\
1742be used in a suid/sgid environment to test if the invoking user has the\n\
1743specified access to the path. The mode argument can be F_OK to test\n\
1744existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001745
1746static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001747posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001748{
Victor Stinner8c62be82010-05-06 00:08:46 +00001749 PyObject *opath;
1750 char *path;
1751 int mode;
1752
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001753#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001754 DWORD attr;
1755 PyUnicodeObject *po;
1756 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1757 Py_BEGIN_ALLOW_THREADS
1758 /* PyUnicode_AS_UNICODE OK without thread lock as
1759 it is a simple dereference. */
1760 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1761 Py_END_ALLOW_THREADS
1762 goto finish;
1763 }
1764 /* Drop the argument parsing error as narrow strings
1765 are also valid. */
1766 PyErr_Clear();
1767 if (!PyArg_ParseTuple(args, "O&i:access",
1768 PyUnicode_FSConverter, &opath, &mode))
1769 return NULL;
1770 path = PyBytes_AsString(opath);
1771 Py_BEGIN_ALLOW_THREADS
1772 attr = GetFileAttributesA(path);
1773 Py_END_ALLOW_THREADS
1774 Py_DECREF(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001775finish:
Victor Stinner8c62be82010-05-06 00:08:46 +00001776 if (attr == 0xFFFFFFFF)
1777 /* File does not exist, or cannot read attributes */
1778 return PyBool_FromLong(0);
1779 /* Access is possible if either write access wasn't requested, or
1780 the file isn't read-only, or if it's a directory, as there are
1781 no read-only directories on Windows. */
1782 return PyBool_FromLong(!(mode & 2)
1783 || !(attr & FILE_ATTRIBUTE_READONLY)
1784 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001785#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001786 int res;
1787 if (!PyArg_ParseTuple(args, "O&i:access",
1788 PyUnicode_FSConverter, &opath, &mode))
1789 return NULL;
1790 path = PyBytes_AsString(opath);
1791 Py_BEGIN_ALLOW_THREADS
1792 res = access(path, mode);
1793 Py_END_ALLOW_THREADS
1794 Py_DECREF(opath);
1795 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001796#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001797}
1798
Guido van Rossumd371ff11999-01-25 16:12:23 +00001799#ifndef F_OK
1800#define F_OK 0
1801#endif
1802#ifndef R_OK
1803#define R_OK 4
1804#endif
1805#ifndef W_OK
1806#define W_OK 2
1807#endif
1808#ifndef X_OK
1809#define X_OK 1
1810#endif
1811
1812#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001813PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001814"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001815Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001816
1817static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001818posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001819{
Victor Stinner8c62be82010-05-06 00:08:46 +00001820 int id;
1821 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001822
Victor Stinner8c62be82010-05-06 00:08:46 +00001823 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1824 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001825
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001826#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001827 /* file descriptor 0 only, the default input device (stdin) */
1828 if (id == 0) {
1829 ret = ttyname();
1830 }
1831 else {
1832 ret = NULL;
1833 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001834#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001835 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001836#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001837 if (ret == NULL)
1838 return posix_error();
1839 return PyUnicode_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001840}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001841#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001842
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001843#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001844PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001845"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001846Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001847
1848static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001849posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001850{
Victor Stinner8c62be82010-05-06 00:08:46 +00001851 char *ret;
1852 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001853
Greg Wardb48bc172000-03-01 21:51:56 +00001854#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00001855 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001856#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001857 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001858#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001859 if (ret == NULL)
1860 return posix_error();
1861 return PyUnicode_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001862}
1863#endif
1864
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001865PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001866"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001867Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001868
Barry Warsaw53699e91996-12-10 23:23:01 +00001869static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001870posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001871{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001872#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001873 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001874#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001875 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001876#elif defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001877 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001878#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001879 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001880#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001881}
1882
Fred Drake4d1e64b2002-04-15 19:40:07 +00001883#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001884PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001885"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001886Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001887opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001888
1889static PyObject *
1890posix_fchdir(PyObject *self, PyObject *fdobj)
1891{
Victor Stinner8c62be82010-05-06 00:08:46 +00001892 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001893}
1894#endif /* HAVE_FCHDIR */
1895
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001896
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001897PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001898"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001899Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001900
Barry Warsaw53699e91996-12-10 23:23:01 +00001901static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001902posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001903{
Victor Stinner8c62be82010-05-06 00:08:46 +00001904 PyObject *opath = NULL;
1905 char *path = NULL;
1906 int i;
1907 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001908#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001909 DWORD attr;
1910 PyUnicodeObject *po;
1911 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1912 Py_BEGIN_ALLOW_THREADS
1913 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1914 if (attr != 0xFFFFFFFF) {
1915 if (i & _S_IWRITE)
1916 attr &= ~FILE_ATTRIBUTE_READONLY;
1917 else
1918 attr |= FILE_ATTRIBUTE_READONLY;
1919 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1920 }
1921 else
1922 res = 0;
1923 Py_END_ALLOW_THREADS
1924 if (!res)
1925 return win32_error_unicode("chmod",
1926 PyUnicode_AS_UNICODE(po));
1927 Py_INCREF(Py_None);
1928 return Py_None;
1929 }
1930 /* Drop the argument parsing error as narrow strings
1931 are also valid. */
1932 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001933
Victor Stinner8c62be82010-05-06 00:08:46 +00001934 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1935 &opath, &i))
1936 return NULL;
1937 path = PyBytes_AsString(opath);
1938 Py_BEGIN_ALLOW_THREADS
1939 attr = GetFileAttributesA(path);
1940 if (attr != 0xFFFFFFFF) {
1941 if (i & _S_IWRITE)
1942 attr &= ~FILE_ATTRIBUTE_READONLY;
1943 else
1944 attr |= FILE_ATTRIBUTE_READONLY;
1945 res = SetFileAttributesA(path, attr);
1946 }
1947 else
1948 res = 0;
1949 Py_END_ALLOW_THREADS
1950 if (!res) {
1951 win32_error("chmod", path);
1952 Py_DECREF(opath);
1953 return NULL;
1954 }
1955 Py_DECREF(opath);
1956 Py_INCREF(Py_None);
1957 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001958#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00001959 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1960 &opath, &i))
1961 return NULL;
1962 path = PyBytes_AsString(opath);
1963 Py_BEGIN_ALLOW_THREADS
1964 res = chmod(path, i);
1965 Py_END_ALLOW_THREADS
1966 if (res < 0)
1967 return posix_error_with_allocated_filename(opath);
1968 Py_DECREF(opath);
1969 Py_INCREF(Py_None);
1970 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001971#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001972}
1973
Christian Heimes4e30a842007-11-30 22:12:06 +00001974#ifdef HAVE_FCHMOD
1975PyDoc_STRVAR(posix_fchmod__doc__,
1976"fchmod(fd, mode)\n\n\
1977Change the access permissions of the file given by file\n\
1978descriptor fd.");
1979
1980static PyObject *
1981posix_fchmod(PyObject *self, PyObject *args)
1982{
Victor Stinner8c62be82010-05-06 00:08:46 +00001983 int fd, mode, res;
1984 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1985 return NULL;
1986 Py_BEGIN_ALLOW_THREADS
1987 res = fchmod(fd, mode);
1988 Py_END_ALLOW_THREADS
1989 if (res < 0)
1990 return posix_error();
1991 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001992}
1993#endif /* HAVE_FCHMOD */
1994
1995#ifdef HAVE_LCHMOD
1996PyDoc_STRVAR(posix_lchmod__doc__,
1997"lchmod(path, mode)\n\n\
1998Change the access permissions of a file. If path is a symlink, this\n\
1999affects the link itself rather than the target.");
2000
2001static PyObject *
2002posix_lchmod(PyObject *self, PyObject *args)
2003{
Victor Stinner8c62be82010-05-06 00:08:46 +00002004 PyObject *opath;
2005 char *path;
2006 int i;
2007 int res;
2008 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2009 &opath, &i))
2010 return NULL;
2011 path = PyBytes_AsString(opath);
2012 Py_BEGIN_ALLOW_THREADS
2013 res = lchmod(path, i);
2014 Py_END_ALLOW_THREADS
2015 if (res < 0)
2016 return posix_error_with_allocated_filename(opath);
2017 Py_DECREF(opath);
2018 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002019}
2020#endif /* HAVE_LCHMOD */
2021
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002022
Thomas Wouterscf297e42007-02-23 15:07:44 +00002023#ifdef HAVE_CHFLAGS
2024PyDoc_STRVAR(posix_chflags__doc__,
2025"chflags(path, flags)\n\n\
2026Set file flags.");
2027
2028static PyObject *
2029posix_chflags(PyObject *self, PyObject *args)
2030{
Victor Stinner8c62be82010-05-06 00:08:46 +00002031 PyObject *opath;
2032 char *path;
2033 unsigned long flags;
2034 int res;
2035 if (!PyArg_ParseTuple(args, "O&k:chflags",
2036 PyUnicode_FSConverter, &opath, &flags))
2037 return NULL;
2038 path = PyBytes_AsString(opath);
2039 Py_BEGIN_ALLOW_THREADS
2040 res = chflags(path, flags);
2041 Py_END_ALLOW_THREADS
2042 if (res < 0)
2043 return posix_error_with_allocated_filename(opath);
2044 Py_DECREF(opath);
2045 Py_INCREF(Py_None);
2046 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002047}
2048#endif /* HAVE_CHFLAGS */
2049
2050#ifdef HAVE_LCHFLAGS
2051PyDoc_STRVAR(posix_lchflags__doc__,
2052"lchflags(path, flags)\n\n\
2053Set file flags.\n\
2054This function will not follow symbolic links.");
2055
2056static PyObject *
2057posix_lchflags(PyObject *self, PyObject *args)
2058{
Victor Stinner8c62be82010-05-06 00:08:46 +00002059 PyObject *opath;
2060 char *path;
2061 unsigned long flags;
2062 int res;
2063 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2064 PyUnicode_FSConverter, &opath, &flags))
2065 return NULL;
2066 path = PyBytes_AsString(opath);
2067 Py_BEGIN_ALLOW_THREADS
2068 res = lchflags(path, flags);
2069 Py_END_ALLOW_THREADS
2070 if (res < 0)
2071 return posix_error_with_allocated_filename(opath);
2072 Py_DECREF(opath);
2073 Py_INCREF(Py_None);
2074 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002075}
2076#endif /* HAVE_LCHFLAGS */
2077
Martin v. Löwis244edc82001-10-04 22:44:26 +00002078#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002079PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002080"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002081Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002082
2083static PyObject *
2084posix_chroot(PyObject *self, PyObject *args)
2085{
Victor Stinner8c62be82010-05-06 00:08:46 +00002086 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002087}
2088#endif
2089
Guido van Rossum21142a01999-01-08 21:05:37 +00002090#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002091PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002092"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002093force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002094
2095static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002096posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002097{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002098 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002099}
2100#endif /* HAVE_FSYNC */
2101
2102#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002103
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002104#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002105extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2106#endif
2107
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002108PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002109"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002110force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002111 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002112
2113static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002114posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002115{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002116 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002117}
2118#endif /* HAVE_FDATASYNC */
2119
2120
Fredrik Lundh10723342000-07-10 16:38:09 +00002121#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002122PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002123"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002124Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002125
Barry Warsaw53699e91996-12-10 23:23:01 +00002126static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002127posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002128{
Victor Stinner8c62be82010-05-06 00:08:46 +00002129 PyObject *opath;
2130 char *path;
2131 long uid, gid;
2132 int res;
2133 if (!PyArg_ParseTuple(args, "O&ll:chown",
2134 PyUnicode_FSConverter, &opath,
2135 &uid, &gid))
2136 return NULL;
2137 path = PyBytes_AsString(opath);
2138 Py_BEGIN_ALLOW_THREADS
2139 res = chown(path, (uid_t) uid, (gid_t) gid);
2140 Py_END_ALLOW_THREADS
2141 if (res < 0)
2142 return posix_error_with_allocated_filename(opath);
2143 Py_DECREF(opath);
2144 Py_INCREF(Py_None);
2145 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002146}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002147#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002148
Christian Heimes4e30a842007-11-30 22:12:06 +00002149#ifdef HAVE_FCHOWN
2150PyDoc_STRVAR(posix_fchown__doc__,
2151"fchown(fd, uid, gid)\n\n\
2152Change the owner and group id of the file given by file descriptor\n\
2153fd to the numeric uid and gid.");
2154
2155static PyObject *
2156posix_fchown(PyObject *self, PyObject *args)
2157{
Victor Stinner8c62be82010-05-06 00:08:46 +00002158 int fd;
2159 long uid, gid;
2160 int res;
2161 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
2162 return NULL;
2163 Py_BEGIN_ALLOW_THREADS
2164 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2165 Py_END_ALLOW_THREADS
2166 if (res < 0)
2167 return posix_error();
2168 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002169}
2170#endif /* HAVE_FCHOWN */
2171
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002172#ifdef HAVE_LCHOWN
2173PyDoc_STRVAR(posix_lchown__doc__,
2174"lchown(path, uid, gid)\n\n\
2175Change the owner and group id of path to the numeric uid and gid.\n\
2176This function will not follow symbolic links.");
2177
2178static PyObject *
2179posix_lchown(PyObject *self, PyObject *args)
2180{
Victor Stinner8c62be82010-05-06 00:08:46 +00002181 PyObject *opath;
2182 char *path;
2183 long uid, gid;
2184 int res;
2185 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2186 PyUnicode_FSConverter, &opath,
2187 &uid, &gid))
2188 return NULL;
2189 path = PyBytes_AsString(opath);
2190 Py_BEGIN_ALLOW_THREADS
2191 res = lchown(path, (uid_t) uid, (gid_t) gid);
2192 Py_END_ALLOW_THREADS
2193 if (res < 0)
2194 return posix_error_with_allocated_filename(opath);
2195 Py_DECREF(opath);
2196 Py_INCREF(Py_None);
2197 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002198}
2199#endif /* HAVE_LCHOWN */
2200
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002201
Guido van Rossum36bc6801995-06-14 22:54:23 +00002202#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002203static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002204posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002205{
Victor Stinner8c62be82010-05-06 00:08:46 +00002206 char buf[1026];
2207 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002208
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002209#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002210 if (!use_bytes) {
2211 wchar_t wbuf[1026];
2212 wchar_t *wbuf2 = wbuf;
2213 PyObject *resobj;
2214 DWORD len;
2215 Py_BEGIN_ALLOW_THREADS
2216 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2217 /* If the buffer is large enough, len does not include the
2218 terminating \0. If the buffer is too small, len includes
2219 the space needed for the terminator. */
2220 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2221 wbuf2 = malloc(len * sizeof(wchar_t));
2222 if (wbuf2)
2223 len = GetCurrentDirectoryW(len, wbuf2);
2224 }
2225 Py_END_ALLOW_THREADS
2226 if (!wbuf2) {
2227 PyErr_NoMemory();
2228 return NULL;
2229 }
2230 if (!len) {
2231 if (wbuf2 != wbuf) free(wbuf2);
2232 return win32_error("getcwdu", NULL);
2233 }
2234 resobj = PyUnicode_FromWideChar(wbuf2, len);
2235 if (wbuf2 != wbuf) free(wbuf2);
2236 return resobj;
2237 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002238#endif
2239
Victor Stinner8c62be82010-05-06 00:08:46 +00002240 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002241#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002242 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002243#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002244 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002245#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002246 Py_END_ALLOW_THREADS
2247 if (res == NULL)
2248 return posix_error();
2249 if (use_bytes)
2250 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002251 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002252}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002253
2254PyDoc_STRVAR(posix_getcwd__doc__,
2255"getcwd() -> path\n\n\
2256Return a unicode string representing the current working directory.");
2257
2258static PyObject *
2259posix_getcwd_unicode(PyObject *self)
2260{
2261 return posix_getcwd(0);
2262}
2263
2264PyDoc_STRVAR(posix_getcwdb__doc__,
2265"getcwdb() -> path\n\n\
2266Return a bytes string representing the current working directory.");
2267
2268static PyObject *
2269posix_getcwd_bytes(PyObject *self)
2270{
2271 return posix_getcwd(1);
2272}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002273#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002274
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002275
Guido van Rossumb6775db1994-08-01 11:34:53 +00002276#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002277PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002278"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002279Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002280
Barry Warsaw53699e91996-12-10 23:23:01 +00002281static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002282posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002283{
Victor Stinner8c62be82010-05-06 00:08:46 +00002284 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002285}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002286#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002287
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002288
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002289PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002290"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002291Return a list containing the names of the entries in the directory.\n\
2292\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00002293 path: path of directory to list\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002294\n\
2295The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002296entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002297
Barry Warsaw53699e91996-12-10 23:23:01 +00002298static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002299posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002300{
Victor Stinner8c62be82010-05-06 00:08:46 +00002301 /* XXX Should redo this putting the (now four) versions of opendir
2302 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002303#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002304
Victor Stinner8c62be82010-05-06 00:08:46 +00002305 PyObject *d, *v;
2306 HANDLE hFindFile;
2307 BOOL result;
2308 WIN32_FIND_DATA FileData;
2309 PyObject *opath;
2310 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2311 char *bufptr = namebuf;
2312 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002313
Victor Stinner8c62be82010-05-06 00:08:46 +00002314 PyObject *po;
2315 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2316 WIN32_FIND_DATAW wFileData;
2317 Py_UNICODE *wnamebuf;
2318 /* Overallocate for \\*.*\0 */
2319 len = PyUnicode_GET_SIZE(po);
2320 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2321 if (!wnamebuf) {
2322 PyErr_NoMemory();
2323 return NULL;
2324 }
2325 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2326 if (len > 0) {
2327 Py_UNICODE wch = wnamebuf[len-1];
2328 if (wch != L'/' && wch != L'\\' && wch != L':')
2329 wnamebuf[len++] = L'\\';
2330 wcscpy(wnamebuf + len, L"*.*");
2331 }
2332 if ((d = PyList_New(0)) == NULL) {
2333 free(wnamebuf);
2334 return NULL;
2335 }
2336 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2337 if (hFindFile == INVALID_HANDLE_VALUE) {
2338 int error = GetLastError();
2339 if (error == ERROR_FILE_NOT_FOUND) {
2340 free(wnamebuf);
2341 return d;
2342 }
2343 Py_DECREF(d);
2344 win32_error_unicode("FindFirstFileW", wnamebuf);
2345 free(wnamebuf);
2346 return NULL;
2347 }
2348 do {
2349 /* Skip over . and .. */
2350 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2351 wcscmp(wFileData.cFileName, L"..") != 0) {
2352 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2353 if (v == NULL) {
2354 Py_DECREF(d);
2355 d = NULL;
2356 break;
2357 }
2358 if (PyList_Append(d, v) != 0) {
2359 Py_DECREF(v);
2360 Py_DECREF(d);
2361 d = NULL;
2362 break;
2363 }
2364 Py_DECREF(v);
2365 }
2366 Py_BEGIN_ALLOW_THREADS
2367 result = FindNextFileW(hFindFile, &wFileData);
2368 Py_END_ALLOW_THREADS
2369 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2370 it got to the end of the directory. */
2371 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2372 Py_DECREF(d);
2373 win32_error_unicode("FindNextFileW", wnamebuf);
2374 FindClose(hFindFile);
2375 free(wnamebuf);
2376 return NULL;
2377 }
2378 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002379
Victor Stinner8c62be82010-05-06 00:08:46 +00002380 if (FindClose(hFindFile) == FALSE) {
2381 Py_DECREF(d);
2382 win32_error_unicode("FindClose", wnamebuf);
2383 free(wnamebuf);
2384 return NULL;
2385 }
2386 free(wnamebuf);
2387 return d;
2388 }
2389 /* Drop the argument parsing error as narrow strings
2390 are also valid. */
2391 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002392
Victor Stinner8c62be82010-05-06 00:08:46 +00002393 if (!PyArg_ParseTuple(args, "O&:listdir",
2394 PyUnicode_FSConverter, &opath))
2395 return NULL;
2396 if (PyBytes_GET_SIZE(opath)+1 > MAX_PATH) {
2397 PyErr_SetString(PyExc_ValueError, "path too long");
2398 Py_DECREF(opath);
2399 return NULL;
2400 }
2401 strcpy(namebuf, PyBytes_AsString(opath));
2402 len = PyObject_Size(opath);
2403 if (len > 0) {
2404 char ch = namebuf[len-1];
2405 if (ch != SEP && ch != ALTSEP && ch != ':')
2406 namebuf[len++] = '/';
2407 strcpy(namebuf + len, "*.*");
2408 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002409
Victor Stinner8c62be82010-05-06 00:08:46 +00002410 if ((d = PyList_New(0)) == NULL)
2411 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002412
Victor Stinner8c62be82010-05-06 00:08:46 +00002413 hFindFile = FindFirstFile(namebuf, &FileData);
2414 if (hFindFile == INVALID_HANDLE_VALUE) {
2415 int error = GetLastError();
2416 if (error == ERROR_FILE_NOT_FOUND)
2417 return d;
2418 Py_DECREF(d);
2419 return win32_error("FindFirstFile", namebuf);
2420 }
2421 do {
2422 /* Skip over . and .. */
2423 if (strcmp(FileData.cFileName, ".") != 0 &&
2424 strcmp(FileData.cFileName, "..") != 0) {
2425 v = PyBytes_FromString(FileData.cFileName);
2426 if (v == NULL) {
2427 Py_DECREF(d);
2428 d = NULL;
2429 break;
2430 }
2431 if (PyList_Append(d, v) != 0) {
2432 Py_DECREF(v);
2433 Py_DECREF(d);
2434 d = NULL;
2435 break;
2436 }
2437 Py_DECREF(v);
2438 }
2439 Py_BEGIN_ALLOW_THREADS
2440 result = FindNextFile(hFindFile, &FileData);
2441 Py_END_ALLOW_THREADS
2442 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2443 it got to the end of the directory. */
2444 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2445 Py_DECREF(d);
2446 win32_error("FindNextFile", namebuf);
2447 FindClose(hFindFile);
2448 return NULL;
2449 }
2450 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002451
Victor Stinner8c62be82010-05-06 00:08:46 +00002452 if (FindClose(hFindFile) == FALSE) {
2453 Py_DECREF(d);
2454 return win32_error("FindClose", namebuf);
2455 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002456
Victor Stinner8c62be82010-05-06 00:08:46 +00002457 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002458
Tim Peters0bb44a42000-09-15 07:44:49 +00002459#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002460
2461#ifndef MAX_PATH
2462#define MAX_PATH CCHMAXPATH
2463#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002464 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002465 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002466 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002467 PyObject *d, *v;
2468 char namebuf[MAX_PATH+5];
2469 HDIR hdir = 1;
2470 ULONG srchcnt = 1;
2471 FILEFINDBUF3 ep;
2472 APIRET rc;
2473
Victor Stinner8c62be82010-05-06 00:08:46 +00002474 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002475 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002476 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002477 name = PyBytes_AsString(oname);
2478 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002479 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002480 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002481 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002482 return NULL;
2483 }
2484 strcpy(namebuf, name);
2485 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002486 if (*pt == ALTSEP)
2487 *pt = SEP;
2488 if (namebuf[len-1] != SEP)
2489 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002490 strcpy(namebuf + len, "*.*");
2491
Neal Norwitz6c913782007-10-14 03:23:09 +00002492 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002493 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002494 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002495 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002496
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002497 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2498 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002499 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002500 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2501 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2502 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002503
2504 if (rc != NO_ERROR) {
2505 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002506 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002507 }
2508
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002509 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002510 do {
2511 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002512 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002513 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002514
2515 strcpy(namebuf, ep.achName);
2516
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002517 /* Leave Case of Name Alone -- In Native Form */
2518 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002519
Christian Heimes72b710a2008-05-26 13:28:38 +00002520 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002521 if (v == NULL) {
2522 Py_DECREF(d);
2523 d = NULL;
2524 break;
2525 }
2526 if (PyList_Append(d, v) != 0) {
2527 Py_DECREF(v);
2528 Py_DECREF(d);
2529 d = NULL;
2530 break;
2531 }
2532 Py_DECREF(v);
2533 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2534 }
2535
Victor Stinnerdcb24032010-04-22 12:08:36 +00002536 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002537 return d;
2538#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002539 PyObject *oname;
2540 char *name;
2541 PyObject *d, *v;
2542 DIR *dirp;
2543 struct dirent *ep;
2544 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002545
Victor Stinner8c62be82010-05-06 00:08:46 +00002546 errno = 0;
2547 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2548 arg_is_unicode = 0;
2549 PyErr_Clear();
2550 }
2551 if (!PyArg_ParseTuple(args, "O&:listdir", PyUnicode_FSConverter, &oname))
2552 return NULL;
2553 name = PyBytes_AsString(oname);
2554 if ((dirp = opendir(name)) == NULL) {
2555 return posix_error_with_allocated_filename(oname);
2556 }
2557 if ((d = PyList_New(0)) == NULL) {
2558 closedir(dirp);
2559 Py_DECREF(oname);
2560 return NULL;
2561 }
2562 for (;;) {
2563 errno = 0;
2564 Py_BEGIN_ALLOW_THREADS
2565 ep = readdir(dirp);
2566 Py_END_ALLOW_THREADS
2567 if (ep == NULL) {
2568 if (errno == 0) {
2569 break;
2570 } else {
2571 closedir(dirp);
2572 Py_DECREF(d);
2573 return posix_error_with_allocated_filename(oname);
2574 }
2575 }
2576 if (ep->d_name[0] == '.' &&
2577 (NAMLEN(ep) == 1 ||
2578 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2579 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002580 if (arg_is_unicode)
2581 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2582 else
2583 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002584 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002585 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002586 break;
2587 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002588 if (PyList_Append(d, v) != 0) {
2589 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002590 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002591 break;
2592 }
2593 Py_DECREF(v);
2594 }
2595 closedir(dirp);
2596 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002597
Victor Stinner8c62be82010-05-06 00:08:46 +00002598 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002599
Tim Peters0bb44a42000-09-15 07:44:49 +00002600#endif /* which OS */
2601} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002602
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002603#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002604/* A helper function for abspath on win32 */
2605static PyObject *
2606posix__getfullpathname(PyObject *self, PyObject *args)
2607{
Victor Stinner8c62be82010-05-06 00:08:46 +00002608 PyObject *opath;
2609 char *path;
2610 char outbuf[MAX_PATH*2];
2611 char *temp;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002612#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002613 PyUnicodeObject *po;
2614 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2615 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2616 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2617 Py_UNICODE *wtemp;
2618 DWORD result;
2619 PyObject *v;
2620 result = GetFullPathNameW(wpath,
2621 sizeof(woutbuf)/sizeof(woutbuf[0]),
2622 woutbuf, &wtemp);
2623 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2624 woutbufp = malloc(result * sizeof(Py_UNICODE));
2625 if (!woutbufp)
2626 return PyErr_NoMemory();
2627 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2628 }
2629 if (result)
2630 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2631 else
2632 v = win32_error_unicode("GetFullPathNameW", wpath);
2633 if (woutbufp != woutbuf)
2634 free(woutbufp);
2635 return v;
2636 }
2637 /* Drop the argument parsing error as narrow strings
2638 are also valid. */
2639 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002640
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002641#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002642 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2643 PyUnicode_FSConverter, &opath))
2644 return NULL;
2645 path = PyBytes_AsString(opath);
2646 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2647 outbuf, &temp)) {
2648 win32_error("GetFullPathName", path);
2649 Py_DECREF(opath);
2650 return NULL;
2651 }
2652 Py_DECREF(opath);
2653 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2654 return PyUnicode_Decode(outbuf, strlen(outbuf),
2655 Py_FileSystemDefaultEncoding, NULL);
2656 }
2657 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002658} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00002659
2660/* A helper function for samepath on windows */
2661static PyObject *
2662posix__getfinalpathname(PyObject *self, PyObject *args)
2663{
2664 HANDLE hFile;
2665 int buf_size;
2666 wchar_t *target_path;
2667 int result_length;
2668 PyObject *result;
2669 wchar_t *path;
2670
2671 if (!PyArg_ParseTuple(args, "u|:_getfullpathname", &path)) {
2672 return NULL;
2673 }
2674
2675 if(!check_GetFinalPathNameByHandle()) {
2676 /* If the OS doesn't have GetFinalPathNameByHandle, return a
2677 NotImplementedError. */
2678 return PyErr_Format(PyExc_NotImplementedError,
2679 "GetFinalPathNameByHandle not available on this platform");
2680 }
2681
2682 hFile = CreateFileW(
2683 path,
2684 0, /* desired access */
2685 0, /* share mode */
2686 NULL, /* security attributes */
2687 OPEN_EXISTING,
2688 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
2689 FILE_FLAG_BACKUP_SEMANTICS,
2690 NULL);
2691
2692 if(hFile == INVALID_HANDLE_VALUE) {
2693 return win32_error_unicode("GetFinalPathNamyByHandle", path);
2694 return PyErr_Format(PyExc_RuntimeError, "Could not get a handle to file.");
2695 }
2696
2697 /* We have a good handle to the target, use it to determine the
2698 target path name. */
2699 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
2700
2701 if(!buf_size)
2702 return win32_error_unicode("GetFinalPathNameByHandle", path);
2703
2704 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
2705 if(!target_path)
2706 return PyErr_NoMemory();
2707
2708 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
2709 buf_size, VOLUME_NAME_DOS);
2710 if(!result_length)
2711 return win32_error_unicode("GetFinalPathNamyByHandle", path);
2712
2713 if(!CloseHandle(hFile))
2714 return win32_error_unicode("GetFinalPathNameByHandle", path);
2715
2716 target_path[result_length] = 0;
2717 result = PyUnicode_FromUnicode(target_path, result_length);
2718 free(target_path);
2719 return result;
2720
2721} /* end of posix__getfinalpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002722#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002723
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002724PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002725"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002726Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002727
Barry Warsaw53699e91996-12-10 23:23:01 +00002728static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002729posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002730{
Victor Stinner8c62be82010-05-06 00:08:46 +00002731 int res;
2732 PyObject *opath;
2733 char *path;
2734 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002735
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002736#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002737 PyUnicodeObject *po;
2738 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2739 Py_BEGIN_ALLOW_THREADS
2740 /* PyUnicode_AS_UNICODE OK without thread lock as
2741 it is a simple dereference. */
2742 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2743 Py_END_ALLOW_THREADS
2744 if (!res)
2745 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2746 Py_INCREF(Py_None);
2747 return Py_None;
2748 }
2749 /* Drop the argument parsing error as narrow strings
2750 are also valid. */
2751 PyErr_Clear();
2752 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2753 PyUnicode_FSConverter, &opath, &mode))
2754 return NULL;
2755 path = PyBytes_AsString(opath);
2756 Py_BEGIN_ALLOW_THREADS
2757 /* PyUnicode_AS_UNICODE OK without thread lock as
2758 it is a simple dereference. */
2759 res = CreateDirectoryA(path, NULL);
2760 Py_END_ALLOW_THREADS
2761 if (!res) {
2762 win32_error("mkdir", path);
2763 Py_DECREF(opath);
2764 return NULL;
2765 }
2766 Py_DECREF(opath);
2767 Py_INCREF(Py_None);
2768 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002769#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002770
Victor Stinner8c62be82010-05-06 00:08:46 +00002771 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2772 PyUnicode_FSConverter, &opath, &mode))
2773 return NULL;
2774 path = PyBytes_AsString(opath);
2775 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002776#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00002777 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002778#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002779 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002780#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002781 Py_END_ALLOW_THREADS
2782 if (res < 0)
2783 return posix_error_with_allocated_filename(opath);
2784 Py_DECREF(opath);
2785 Py_INCREF(Py_None);
2786 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002787#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002788}
2789
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002790
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002791/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2792#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002793#include <sys/resource.h>
2794#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002795
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002796
2797#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002798PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002799"nice(inc) -> new_priority\n\n\
2800Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002801
Barry Warsaw53699e91996-12-10 23:23:01 +00002802static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002803posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002804{
Victor Stinner8c62be82010-05-06 00:08:46 +00002805 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002806
Victor Stinner8c62be82010-05-06 00:08:46 +00002807 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2808 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002809
Victor Stinner8c62be82010-05-06 00:08:46 +00002810 /* There are two flavours of 'nice': one that returns the new
2811 priority (as required by almost all standards out there) and the
2812 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2813 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002814
Victor Stinner8c62be82010-05-06 00:08:46 +00002815 If we are of the nice family that returns the new priority, we
2816 need to clear errno before the call, and check if errno is filled
2817 before calling posix_error() on a returnvalue of -1, because the
2818 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002819
Victor Stinner8c62be82010-05-06 00:08:46 +00002820 errno = 0;
2821 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002822#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00002823 if (value == 0)
2824 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002825#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002826 if (value == -1 && errno != 0)
2827 /* either nice() or getpriority() returned an error */
2828 return posix_error();
2829 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002830}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002831#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002832
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002833PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002834"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002835Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002836
Barry Warsaw53699e91996-12-10 23:23:01 +00002837static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002838posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002839{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002840#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002841 PyObject *o1, *o2;
2842 char *p1, *p2;
2843 BOOL result;
2844 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2845 goto error;
2846 if (!convert_to_unicode(&o1))
2847 goto error;
2848 if (!convert_to_unicode(&o2)) {
2849 Py_DECREF(o1);
2850 goto error;
2851 }
2852 Py_BEGIN_ALLOW_THREADS
2853 result = MoveFileW(PyUnicode_AsUnicode(o1),
2854 PyUnicode_AsUnicode(o2));
2855 Py_END_ALLOW_THREADS
2856 Py_DECREF(o1);
2857 Py_DECREF(o2);
2858 if (!result)
2859 return win32_error("rename", NULL);
2860 Py_INCREF(Py_None);
2861 return Py_None;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002862error:
Victor Stinner8c62be82010-05-06 00:08:46 +00002863 PyErr_Clear();
2864 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2865 return NULL;
2866 Py_BEGIN_ALLOW_THREADS
2867 result = MoveFileA(p1, p2);
2868 Py_END_ALLOW_THREADS
2869 if (!result)
2870 return win32_error("rename", NULL);
2871 Py_INCREF(Py_None);
2872 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002873#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002874 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002875#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002876}
2877
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002878
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002879PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002880"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002881Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002882
Barry Warsaw53699e91996-12-10 23:23:01 +00002883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002884posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002885{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002886#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002887 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002888#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002889 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002890#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002891}
2892
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002893
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002894PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002895"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002896Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002897
Barry Warsaw53699e91996-12-10 23:23:01 +00002898static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002899posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002900{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002901#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00002902 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002903#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002904 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002905#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002906}
2907
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002908
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002909#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002910PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002911"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002912Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002913
Barry Warsaw53699e91996-12-10 23:23:01 +00002914static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002915posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002916{
Victor Stinner8c62be82010-05-06 00:08:46 +00002917 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002918#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002919 wchar_t *command;
2920 if (!PyArg_ParseTuple(args, "u:system", &command))
2921 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00002922
Victor Stinner8c62be82010-05-06 00:08:46 +00002923 Py_BEGIN_ALLOW_THREADS
2924 sts = _wsystem(command);
2925 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00002926#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002927 PyObject *command_obj;
2928 char *command;
2929 if (!PyArg_ParseTuple(args, "O&:system",
2930 PyUnicode_FSConverter, &command_obj))
2931 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00002932
Victor Stinner8c62be82010-05-06 00:08:46 +00002933 command = PyBytes_AsString(command_obj);
2934 Py_BEGIN_ALLOW_THREADS
2935 sts = system(command);
2936 Py_END_ALLOW_THREADS
2937 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00002938#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002939 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002940}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002941#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002942
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002943
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002944PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002945"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002946Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002947
Barry Warsaw53699e91996-12-10 23:23:01 +00002948static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002949posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002950{
Victor Stinner8c62be82010-05-06 00:08:46 +00002951 int i;
2952 if (!PyArg_ParseTuple(args, "i:umask", &i))
2953 return NULL;
2954 i = (int)umask(i);
2955 if (i < 0)
2956 return posix_error();
2957 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002958}
2959
Brian Curtind40e6f72010-07-08 21:39:08 +00002960#ifdef MS_WINDOWS
2961
2962/* override the default DeleteFileW behavior so that directory
2963symlinks can be removed with this function, the same as with
2964Unix symlinks */
2965BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
2966{
2967 WIN32_FILE_ATTRIBUTE_DATA info;
2968 WIN32_FIND_DATAW find_data;
2969 HANDLE find_data_handle;
2970 int is_directory = 0;
2971 int is_link = 0;
2972
2973 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
2974 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
2975
2976 /* Get WIN32_FIND_DATA structure for the path to determine if
2977 it is a symlink */
2978 if(is_directory &&
2979 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
2980 find_data_handle = FindFirstFileW(lpFileName, &find_data);
2981
2982 if(find_data_handle != INVALID_HANDLE_VALUE) {
2983 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
2984 FindClose(find_data_handle);
2985 }
2986 }
2987 }
2988
2989 if (is_directory && is_link)
2990 return RemoveDirectoryW(lpFileName);
2991
2992 return DeleteFileW(lpFileName);
2993}
2994#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002995
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002996PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002997"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002998Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002999
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003000PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003001"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003002Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003003
Barry Warsaw53699e91996-12-10 23:23:01 +00003004static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003005posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003006{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003007#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00003008 return win32_1str(args, "remove", "y:remove", DeleteFileA, "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003009#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003010 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003011#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003012}
3013
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003014
Guido van Rossumb6775db1994-08-01 11:34:53 +00003015#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003016PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003017"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003018Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003019
Barry Warsaw53699e91996-12-10 23:23:01 +00003020static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003021posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003022{
Victor Stinner8c62be82010-05-06 00:08:46 +00003023 struct utsname u;
3024 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003025
Victor Stinner8c62be82010-05-06 00:08:46 +00003026 Py_BEGIN_ALLOW_THREADS
3027 res = uname(&u);
3028 Py_END_ALLOW_THREADS
3029 if (res < 0)
3030 return posix_error();
3031 return Py_BuildValue("(sssss)",
3032 u.sysname,
3033 u.nodename,
3034 u.release,
3035 u.version,
3036 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003037}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003038#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003039
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003040static int
3041extract_time(PyObject *t, long* sec, long* usec)
3042{
Victor Stinner8c62be82010-05-06 00:08:46 +00003043 long intval;
3044 if (PyFloat_Check(t)) {
3045 double tval = PyFloat_AsDouble(t);
3046 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
3047 if (!intobj)
3048 return -1;
3049 intval = PyLong_AsLong(intobj);
3050 Py_DECREF(intobj);
3051 if (intval == -1 && PyErr_Occurred())
3052 return -1;
3053 *sec = intval;
3054 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
3055 if (*usec < 0)
3056 /* If rounding gave us a negative number,
3057 truncate. */
3058 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00003059 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003060 }
3061 intval = PyLong_AsLong(t);
3062 if (intval == -1 && PyErr_Occurred())
3063 return -1;
3064 *sec = intval;
3065 *usec = 0;
3066 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003067}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003068
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003069PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00003070"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00003071utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00003072Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003073second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003074
Barry Warsaw53699e91996-12-10 23:23:01 +00003075static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003076posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003077{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003078#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003079 PyObject *arg;
3080 PyUnicodeObject *obwpath;
3081 wchar_t *wpath = NULL;
3082 PyObject *oapath;
3083 char *apath;
3084 HANDLE hFile;
3085 long atimesec, mtimesec, ausec, musec;
3086 FILETIME atime, mtime;
3087 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003088
Victor Stinner8c62be82010-05-06 00:08:46 +00003089 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
3090 wpath = PyUnicode_AS_UNICODE(obwpath);
3091 Py_BEGIN_ALLOW_THREADS
3092 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3093 NULL, OPEN_EXISTING,
3094 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3095 Py_END_ALLOW_THREADS
3096 if (hFile == INVALID_HANDLE_VALUE)
3097 return win32_error_unicode("utime", wpath);
3098 } else
3099 /* Drop the argument parsing error as narrow strings
3100 are also valid. */
3101 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003102
Victor Stinner8c62be82010-05-06 00:08:46 +00003103 if (!wpath) {
3104 if (!PyArg_ParseTuple(args, "O&O:utime",
3105 PyUnicode_FSConverter, &oapath, &arg))
3106 return NULL;
3107 apath = PyBytes_AsString(oapath);
3108 Py_BEGIN_ALLOW_THREADS
3109 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3110 NULL, OPEN_EXISTING,
3111 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3112 Py_END_ALLOW_THREADS
3113 if (hFile == INVALID_HANDLE_VALUE) {
3114 win32_error("utime", apath);
3115 Py_DECREF(oapath);
3116 return NULL;
3117 }
3118 Py_DECREF(oapath);
3119 }
3120
3121 if (arg == Py_None) {
3122 SYSTEMTIME now;
3123 GetSystemTime(&now);
3124 if (!SystemTimeToFileTime(&now, &mtime) ||
3125 !SystemTimeToFileTime(&now, &atime)) {
3126 win32_error("utime", NULL);
3127 goto done;
3128 }
3129 }
3130 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3131 PyErr_SetString(PyExc_TypeError,
3132 "utime() arg 2 must be a tuple (atime, mtime)");
3133 goto done;
3134 }
3135 else {
3136 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3137 &atimesec, &ausec) == -1)
3138 goto done;
3139 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3140 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3141 &mtimesec, &musec) == -1)
3142 goto done;
3143 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3144 }
3145 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3146 /* Avoid putting the file name into the error here,
3147 as that may confuse the user into believing that
3148 something is wrong with the file, when it also
3149 could be the time stamp that gives a problem. */
3150 win32_error("utime", NULL);
3151 }
3152 Py_INCREF(Py_None);
3153 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003154done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003155 CloseHandle(hFile);
3156 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003157#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003158
Victor Stinner8c62be82010-05-06 00:08:46 +00003159 PyObject *opath;
3160 char *path;
3161 long atime, mtime, ausec, musec;
3162 int res;
3163 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003164
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003165#if defined(HAVE_UTIMES)
Victor Stinner8c62be82010-05-06 00:08:46 +00003166 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003167#define ATIME buf[0].tv_sec
3168#define MTIME buf[1].tv_sec
3169#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003170/* XXX should define struct utimbuf instead, above */
Victor Stinner8c62be82010-05-06 00:08:46 +00003171 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003172#define ATIME buf.actime
3173#define MTIME buf.modtime
3174#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003175#else /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003176 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003177#define ATIME buf[0]
3178#define MTIME buf[1]
3179#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003180#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003181
Mark Hammond817c9292003-12-03 01:22:38 +00003182
Victor Stinner8c62be82010-05-06 00:08:46 +00003183 if (!PyArg_ParseTuple(args, "O&O:utime",
3184 PyUnicode_FSConverter, &opath, &arg))
3185 return NULL;
3186 path = PyBytes_AsString(opath);
3187 if (arg == Py_None) {
3188 /* optional time values not given */
3189 Py_BEGIN_ALLOW_THREADS
3190 res = utime(path, NULL);
3191 Py_END_ALLOW_THREADS
3192 }
3193 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3194 PyErr_SetString(PyExc_TypeError,
3195 "utime() arg 2 must be a tuple (atime, mtime)");
3196 Py_DECREF(opath);
3197 return NULL;
3198 }
3199 else {
3200 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3201 &atime, &ausec) == -1) {
3202 Py_DECREF(opath);
3203 return NULL;
3204 }
3205 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3206 &mtime, &musec) == -1) {
3207 Py_DECREF(opath);
3208 return NULL;
3209 }
3210 ATIME = atime;
3211 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003212#ifdef HAVE_UTIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00003213 buf[0].tv_usec = ausec;
3214 buf[1].tv_usec = musec;
3215 Py_BEGIN_ALLOW_THREADS
3216 res = utimes(path, buf);
3217 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003218#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003219 Py_BEGIN_ALLOW_THREADS
3220 res = utime(path, UTIME_ARG);
3221 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003222#endif /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003223 }
3224 if (res < 0) {
3225 return posix_error_with_allocated_filename(opath);
3226 }
3227 Py_DECREF(opath);
3228 Py_INCREF(Py_None);
3229 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003230#undef UTIME_ARG
3231#undef ATIME
3232#undef MTIME
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003233#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003234}
3235
Guido van Rossum85e3b011991-06-03 12:42:10 +00003236
Guido van Rossum3b066191991-06-04 19:40:25 +00003237/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003238
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003239PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003240"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003241Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003242
Barry Warsaw53699e91996-12-10 23:23:01 +00003243static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003244posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003245{
Victor Stinner8c62be82010-05-06 00:08:46 +00003246 int sts;
3247 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3248 return NULL;
3249 _exit(sts);
3250 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003251}
3252
Martin v. Löwis114619e2002-10-07 06:44:21 +00003253#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3254static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003255free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003256{
Victor Stinner8c62be82010-05-06 00:08:46 +00003257 Py_ssize_t i;
3258 for (i = 0; i < count; i++)
3259 PyMem_Free(array[i]);
3260 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003261}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003262
Antoine Pitrou69f71142009-05-24 21:25:49 +00003263static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003264int fsconvert_strdup(PyObject *o, char**out)
3265{
Victor Stinner8c62be82010-05-06 00:08:46 +00003266 PyObject *bytes;
3267 Py_ssize_t size;
3268 if (!PyUnicode_FSConverter(o, &bytes))
3269 return 0;
3270 size = PyBytes_GET_SIZE(bytes);
3271 *out = PyMem_Malloc(size+1);
3272 if (!*out)
3273 return 0;
3274 memcpy(*out, PyBytes_AsString(bytes), size+1);
3275 Py_DECREF(bytes);
3276 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003277}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003278#endif
3279
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003280
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003281#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003282PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003283"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003284Execute an executable path with arguments, replacing current process.\n\
3285\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003286 path: path of executable file\n\
3287 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003288
Barry Warsaw53699e91996-12-10 23:23:01 +00003289static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003290posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003291{
Victor Stinner8c62be82010-05-06 00:08:46 +00003292 PyObject *opath;
3293 char *path;
3294 PyObject *argv;
3295 char **argvlist;
3296 Py_ssize_t i, argc;
3297 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003298
Victor Stinner8c62be82010-05-06 00:08:46 +00003299 /* execv has two arguments: (path, argv), where
3300 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003301
Victor Stinner8c62be82010-05-06 00:08:46 +00003302 if (!PyArg_ParseTuple(args, "O&O:execv",
3303 PyUnicode_FSConverter,
3304 &opath, &argv))
3305 return NULL;
3306 path = PyBytes_AsString(opath);
3307 if (PyList_Check(argv)) {
3308 argc = PyList_Size(argv);
3309 getitem = PyList_GetItem;
3310 }
3311 else if (PyTuple_Check(argv)) {
3312 argc = PyTuple_Size(argv);
3313 getitem = PyTuple_GetItem;
3314 }
3315 else {
3316 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3317 Py_DECREF(opath);
3318 return NULL;
3319 }
3320 if (argc < 1) {
3321 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3322 Py_DECREF(opath);
3323 return NULL;
3324 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003325
Victor Stinner8c62be82010-05-06 00:08:46 +00003326 argvlist = PyMem_NEW(char *, argc+1);
3327 if (argvlist == NULL) {
3328 Py_DECREF(opath);
3329 return PyErr_NoMemory();
3330 }
3331 for (i = 0; i < argc; i++) {
3332 if (!fsconvert_strdup((*getitem)(argv, i),
3333 &argvlist[i])) {
3334 free_string_array(argvlist, i);
3335 PyErr_SetString(PyExc_TypeError,
3336 "execv() arg 2 must contain only strings");
3337 Py_DECREF(opath);
3338 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003339
Victor Stinner8c62be82010-05-06 00:08:46 +00003340 }
3341 }
3342 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003343
Victor Stinner8c62be82010-05-06 00:08:46 +00003344 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003345
Victor Stinner8c62be82010-05-06 00:08:46 +00003346 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003347
Victor Stinner8c62be82010-05-06 00:08:46 +00003348 free_string_array(argvlist, argc);
3349 Py_DECREF(opath);
3350 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003351}
3352
Victor Stinner13bb71c2010-04-23 21:41:56 +00003353static char**
3354parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3355{
Victor Stinner8c62be82010-05-06 00:08:46 +00003356 char **envlist;
3357 Py_ssize_t i, pos, envc;
3358 PyObject *keys=NULL, *vals=NULL;
3359 PyObject *key, *val, *key2, *val2;
3360 char *p, *k, *v;
3361 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003362
Victor Stinner8c62be82010-05-06 00:08:46 +00003363 i = PyMapping_Size(env);
3364 if (i < 0)
3365 return NULL;
3366 envlist = PyMem_NEW(char *, i + 1);
3367 if (envlist == NULL) {
3368 PyErr_NoMemory();
3369 return NULL;
3370 }
3371 envc = 0;
3372 keys = PyMapping_Keys(env);
3373 vals = PyMapping_Values(env);
3374 if (!keys || !vals)
3375 goto error;
3376 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3377 PyErr_Format(PyExc_TypeError,
3378 "env.keys() or env.values() is not a list");
3379 goto error;
3380 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003381
Victor Stinner8c62be82010-05-06 00:08:46 +00003382 for (pos = 0; pos < i; pos++) {
3383 key = PyList_GetItem(keys, pos);
3384 val = PyList_GetItem(vals, pos);
3385 if (!key || !val)
3386 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003387
Victor Stinner8c62be82010-05-06 00:08:46 +00003388 if (PyUnicode_FSConverter(key, &key2) == 0)
3389 goto error;
3390 if (PyUnicode_FSConverter(val, &val2) == 0) {
3391 Py_DECREF(key2);
3392 goto error;
3393 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003394
3395#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003396 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3397 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00003398#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003399 k = PyBytes_AsString(key2);
3400 v = PyBytes_AsString(val2);
3401 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003402
Victor Stinner8c62be82010-05-06 00:08:46 +00003403 p = PyMem_NEW(char, len);
3404 if (p == NULL) {
3405 PyErr_NoMemory();
3406 Py_DECREF(key2);
3407 Py_DECREF(val2);
3408 goto error;
3409 }
3410 PyOS_snprintf(p, len, "%s=%s", k, v);
3411 envlist[envc++] = p;
3412 Py_DECREF(key2);
3413 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003414#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003415 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003416#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003417 }
3418 Py_DECREF(vals);
3419 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003420
Victor Stinner8c62be82010-05-06 00:08:46 +00003421 envlist[envc] = 0;
3422 *envc_ptr = envc;
3423 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003424
3425error:
Victor Stinner8c62be82010-05-06 00:08:46 +00003426 Py_XDECREF(keys);
3427 Py_XDECREF(vals);
3428 while (--envc >= 0)
3429 PyMem_DEL(envlist[envc]);
3430 PyMem_DEL(envlist);
3431 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003432}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003433
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003434PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003435"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003436Execute a path with arguments and environment, replacing current process.\n\
3437\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003438 path: path of executable file\n\
3439 args: tuple or list of arguments\n\
3440 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003441
Barry Warsaw53699e91996-12-10 23:23:01 +00003442static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003443posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003444{
Victor Stinner8c62be82010-05-06 00:08:46 +00003445 PyObject *opath;
3446 char *path;
3447 PyObject *argv, *env;
3448 char **argvlist;
3449 char **envlist;
3450 Py_ssize_t i, argc, envc;
3451 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3452 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003453
Victor Stinner8c62be82010-05-06 00:08:46 +00003454 /* execve has three arguments: (path, argv, env), where
3455 argv is a list or tuple of strings and env is a dictionary
3456 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003457
Victor Stinner8c62be82010-05-06 00:08:46 +00003458 if (!PyArg_ParseTuple(args, "O&OO:execve",
3459 PyUnicode_FSConverter,
3460 &opath, &argv, &env))
3461 return NULL;
3462 path = PyBytes_AsString(opath);
3463 if (PyList_Check(argv)) {
3464 argc = PyList_Size(argv);
3465 getitem = PyList_GetItem;
3466 }
3467 else if (PyTuple_Check(argv)) {
3468 argc = PyTuple_Size(argv);
3469 getitem = PyTuple_GetItem;
3470 }
3471 else {
3472 PyErr_SetString(PyExc_TypeError,
3473 "execve() arg 2 must be a tuple or list");
3474 goto fail_0;
3475 }
3476 if (!PyMapping_Check(env)) {
3477 PyErr_SetString(PyExc_TypeError,
3478 "execve() arg 3 must be a mapping object");
3479 goto fail_0;
3480 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003481
Victor Stinner8c62be82010-05-06 00:08:46 +00003482 argvlist = PyMem_NEW(char *, argc+1);
3483 if (argvlist == NULL) {
3484 PyErr_NoMemory();
3485 goto fail_0;
3486 }
3487 for (i = 0; i < argc; i++) {
3488 if (!fsconvert_strdup((*getitem)(argv, i),
3489 &argvlist[i]))
3490 {
3491 lastarg = i;
3492 goto fail_1;
3493 }
3494 }
3495 lastarg = argc;
3496 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003497
Victor Stinner8c62be82010-05-06 00:08:46 +00003498 envlist = parse_envlist(env, &envc);
3499 if (envlist == NULL)
3500 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003501
Victor Stinner8c62be82010-05-06 00:08:46 +00003502 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003503
Victor Stinner8c62be82010-05-06 00:08:46 +00003504 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003505
Victor Stinner8c62be82010-05-06 00:08:46 +00003506 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003507
Victor Stinner8c62be82010-05-06 00:08:46 +00003508 while (--envc >= 0)
3509 PyMem_DEL(envlist[envc]);
3510 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003511 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003512 free_string_array(argvlist, lastarg);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003513 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003514 Py_DECREF(opath);
3515 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003516}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003517#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003518
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003519
Guido van Rossuma1065681999-01-25 23:20:23 +00003520#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003521PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003522"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003523Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003524\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003525 mode: mode of process creation\n\
3526 path: path of executable file\n\
3527 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003528
3529static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003530posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003531{
Victor Stinner8c62be82010-05-06 00:08:46 +00003532 PyObject *opath;
3533 char *path;
3534 PyObject *argv;
3535 char **argvlist;
3536 int mode, i;
3537 Py_ssize_t argc;
3538 Py_intptr_t spawnval;
3539 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003540
Victor Stinner8c62be82010-05-06 00:08:46 +00003541 /* spawnv has three arguments: (mode, path, argv), where
3542 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003543
Victor Stinner8c62be82010-05-06 00:08:46 +00003544 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3545 PyUnicode_FSConverter,
3546 &opath, &argv))
3547 return NULL;
3548 path = PyBytes_AsString(opath);
3549 if (PyList_Check(argv)) {
3550 argc = PyList_Size(argv);
3551 getitem = PyList_GetItem;
3552 }
3553 else if (PyTuple_Check(argv)) {
3554 argc = PyTuple_Size(argv);
3555 getitem = PyTuple_GetItem;
3556 }
3557 else {
3558 PyErr_SetString(PyExc_TypeError,
3559 "spawnv() arg 2 must be a tuple or list");
3560 Py_DECREF(opath);
3561 return NULL;
3562 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003563
Victor Stinner8c62be82010-05-06 00:08:46 +00003564 argvlist = PyMem_NEW(char *, argc+1);
3565 if (argvlist == NULL) {
3566 Py_DECREF(opath);
3567 return PyErr_NoMemory();
3568 }
3569 for (i = 0; i < argc; i++) {
3570 if (!fsconvert_strdup((*getitem)(argv, i),
3571 &argvlist[i])) {
3572 free_string_array(argvlist, i);
3573 PyErr_SetString(
3574 PyExc_TypeError,
3575 "spawnv() arg 2 must contain only strings");
3576 Py_DECREF(opath);
3577 return NULL;
3578 }
3579 }
3580 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003581
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003582#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003583 Py_BEGIN_ALLOW_THREADS
3584 spawnval = spawnv(mode, path, argvlist);
3585 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003586#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003587 if (mode == _OLD_P_OVERLAY)
3588 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003589
Victor Stinner8c62be82010-05-06 00:08:46 +00003590 Py_BEGIN_ALLOW_THREADS
3591 spawnval = _spawnv(mode, path, argvlist);
3592 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003593#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003594
Victor Stinner8c62be82010-05-06 00:08:46 +00003595 free_string_array(argvlist, argc);
3596 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003597
Victor Stinner8c62be82010-05-06 00:08:46 +00003598 if (spawnval == -1)
3599 return posix_error();
3600 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003601#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003602 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003603#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003604 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003605#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003606}
3607
3608
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003609PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003610"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003611Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003612\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003613 mode: mode of process creation\n\
3614 path: path of executable file\n\
3615 args: tuple or list of arguments\n\
3616 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003617
3618static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003619posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003620{
Victor Stinner8c62be82010-05-06 00:08:46 +00003621 PyObject *opath;
3622 char *path;
3623 PyObject *argv, *env;
3624 char **argvlist;
3625 char **envlist;
3626 PyObject *res = NULL;
3627 int mode, envc;
3628 Py_ssize_t argc, i;
3629 Py_intptr_t spawnval;
3630 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3631 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003632
Victor Stinner8c62be82010-05-06 00:08:46 +00003633 /* spawnve has four arguments: (mode, path, argv, env), where
3634 argv is a list or tuple of strings and env is a dictionary
3635 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003636
Victor Stinner8c62be82010-05-06 00:08:46 +00003637 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3638 PyUnicode_FSConverter,
3639 &opath, &argv, &env))
3640 return NULL;
3641 path = PyBytes_AsString(opath);
3642 if (PyList_Check(argv)) {
3643 argc = PyList_Size(argv);
3644 getitem = PyList_GetItem;
3645 }
3646 else if (PyTuple_Check(argv)) {
3647 argc = PyTuple_Size(argv);
3648 getitem = PyTuple_GetItem;
3649 }
3650 else {
3651 PyErr_SetString(PyExc_TypeError,
3652 "spawnve() arg 2 must be a tuple or list");
3653 goto fail_0;
3654 }
3655 if (!PyMapping_Check(env)) {
3656 PyErr_SetString(PyExc_TypeError,
3657 "spawnve() arg 3 must be a mapping object");
3658 goto fail_0;
3659 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003660
Victor Stinner8c62be82010-05-06 00:08:46 +00003661 argvlist = PyMem_NEW(char *, argc+1);
3662 if (argvlist == NULL) {
3663 PyErr_NoMemory();
3664 goto fail_0;
3665 }
3666 for (i = 0; i < argc; i++) {
3667 if (!fsconvert_strdup((*getitem)(argv, i),
3668 &argvlist[i]))
3669 {
3670 lastarg = i;
3671 goto fail_1;
3672 }
3673 }
3674 lastarg = argc;
3675 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003676
Victor Stinner8c62be82010-05-06 00:08:46 +00003677 envlist = parse_envlist(env, &envc);
3678 if (envlist == NULL)
3679 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003680
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003681#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003682 Py_BEGIN_ALLOW_THREADS
3683 spawnval = spawnve(mode, path, argvlist, envlist);
3684 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003685#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003686 if (mode == _OLD_P_OVERLAY)
3687 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003688
Victor Stinner8c62be82010-05-06 00:08:46 +00003689 Py_BEGIN_ALLOW_THREADS
3690 spawnval = _spawnve(mode, path, argvlist, envlist);
3691 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003692#endif
Tim Peters25059d32001-12-07 20:35:43 +00003693
Victor Stinner8c62be82010-05-06 00:08:46 +00003694 if (spawnval == -1)
3695 (void) posix_error();
3696 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003697#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003698 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003699#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003700 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003701#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003702
Victor Stinner8c62be82010-05-06 00:08:46 +00003703 while (--envc >= 0)
3704 PyMem_DEL(envlist[envc]);
3705 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003706 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003707 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003708 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003709 Py_DECREF(opath);
3710 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003711}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003712
3713/* OS/2 supports spawnvp & spawnvpe natively */
3714#if defined(PYOS_OS2)
3715PyDoc_STRVAR(posix_spawnvp__doc__,
3716"spawnvp(mode, file, args)\n\n\
3717Execute the program 'file' in a new process, using the environment\n\
3718search path to find the file.\n\
3719\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003720 mode: mode of process creation\n\
3721 file: executable file name\n\
3722 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003723
3724static PyObject *
3725posix_spawnvp(PyObject *self, PyObject *args)
3726{
Victor Stinner8c62be82010-05-06 00:08:46 +00003727 PyObject *opath;
3728 char *path;
3729 PyObject *argv;
3730 char **argvlist;
3731 int mode, i, argc;
3732 Py_intptr_t spawnval;
3733 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003734
Victor Stinner8c62be82010-05-06 00:08:46 +00003735 /* spawnvp has three arguments: (mode, path, argv), where
3736 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003737
Victor Stinner8c62be82010-05-06 00:08:46 +00003738 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3739 PyUnicode_FSConverter,
3740 &opath, &argv))
3741 return NULL;
3742 path = PyBytes_AsString(opath);
3743 if (PyList_Check(argv)) {
3744 argc = PyList_Size(argv);
3745 getitem = PyList_GetItem;
3746 }
3747 else if (PyTuple_Check(argv)) {
3748 argc = PyTuple_Size(argv);
3749 getitem = PyTuple_GetItem;
3750 }
3751 else {
3752 PyErr_SetString(PyExc_TypeError,
3753 "spawnvp() arg 2 must be a tuple or list");
3754 Py_DECREF(opath);
3755 return NULL;
3756 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003757
Victor Stinner8c62be82010-05-06 00:08:46 +00003758 argvlist = PyMem_NEW(char *, argc+1);
3759 if (argvlist == NULL) {
3760 Py_DECREF(opath);
3761 return PyErr_NoMemory();
3762 }
3763 for (i = 0; i < argc; i++) {
3764 if (!fsconvert_strdup((*getitem)(argv, i),
3765 &argvlist[i])) {
3766 free_string_array(argvlist, i);
3767 PyErr_SetString(
3768 PyExc_TypeError,
3769 "spawnvp() arg 2 must contain only strings");
3770 Py_DECREF(opath);
3771 return NULL;
3772 }
3773 }
3774 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003775
Victor Stinner8c62be82010-05-06 00:08:46 +00003776 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003777#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003778 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003779#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003780 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003781#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003782 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003783
Victor Stinner8c62be82010-05-06 00:08:46 +00003784 free_string_array(argvlist, argc);
3785 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003786
Victor Stinner8c62be82010-05-06 00:08:46 +00003787 if (spawnval == -1)
3788 return posix_error();
3789 else
3790 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003791}
3792
3793
3794PyDoc_STRVAR(posix_spawnvpe__doc__,
3795"spawnvpe(mode, file, args, env)\n\n\
3796Execute the program 'file' in a new process, using the environment\n\
3797search path to find the file.\n\
3798\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003799 mode: mode of process creation\n\
3800 file: executable file name\n\
3801 args: tuple or list of arguments\n\
3802 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003803
3804static PyObject *
3805posix_spawnvpe(PyObject *self, PyObject *args)
3806{
Victor Stinner8c62be82010-05-06 00:08:46 +00003807 PyObject *opath
3808 char *path;
3809 PyObject *argv, *env;
3810 char **argvlist;
3811 char **envlist;
3812 PyObject *res=NULL;
3813 int mode, i, argc, envc;
3814 Py_intptr_t spawnval;
3815 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3816 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003817
Victor Stinner8c62be82010-05-06 00:08:46 +00003818 /* spawnvpe has four arguments: (mode, path, argv, env), where
3819 argv is a list or tuple of strings and env is a dictionary
3820 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003821
Victor Stinner8c62be82010-05-06 00:08:46 +00003822 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3823 PyUnicode_FSConverter,
3824 &opath, &argv, &env))
3825 return NULL;
3826 path = PyBytes_AsString(opath);
3827 if (PyList_Check(argv)) {
3828 argc = PyList_Size(argv);
3829 getitem = PyList_GetItem;
3830 }
3831 else if (PyTuple_Check(argv)) {
3832 argc = PyTuple_Size(argv);
3833 getitem = PyTuple_GetItem;
3834 }
3835 else {
3836 PyErr_SetString(PyExc_TypeError,
3837 "spawnvpe() arg 2 must be a tuple or list");
3838 goto fail_0;
3839 }
3840 if (!PyMapping_Check(env)) {
3841 PyErr_SetString(PyExc_TypeError,
3842 "spawnvpe() arg 3 must be a mapping object");
3843 goto fail_0;
3844 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003845
Victor Stinner8c62be82010-05-06 00:08:46 +00003846 argvlist = PyMem_NEW(char *, argc+1);
3847 if (argvlist == NULL) {
3848 PyErr_NoMemory();
3849 goto fail_0;
3850 }
3851 for (i = 0; i < argc; i++) {
3852 if (!fsconvert_strdup((*getitem)(argv, i),
3853 &argvlist[i]))
3854 {
3855 lastarg = i;
3856 goto fail_1;
3857 }
3858 }
3859 lastarg = argc;
3860 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003861
Victor Stinner8c62be82010-05-06 00:08:46 +00003862 envlist = parse_envlist(env, &envc);
3863 if (envlist == NULL)
3864 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003865
Victor Stinner8c62be82010-05-06 00:08:46 +00003866 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003867#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003868 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003869#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003870 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003871#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003872 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003873
Victor Stinner8c62be82010-05-06 00:08:46 +00003874 if (spawnval == -1)
3875 (void) posix_error();
3876 else
3877 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003878
Victor Stinner8c62be82010-05-06 00:08:46 +00003879 while (--envc >= 0)
3880 PyMem_DEL(envlist[envc]);
3881 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003882 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003883 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003884 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003885 Py_DECREF(opath);
3886 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003887}
3888#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003889#endif /* HAVE_SPAWNV */
3890
3891
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003892#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003893PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003894"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003895Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3896\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003897Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003898
3899static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003900posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003901{
Victor Stinner8c62be82010-05-06 00:08:46 +00003902 pid_t pid;
3903 int result = 0;
3904 _PyImport_AcquireLock();
3905 pid = fork1();
3906 if (pid == 0) {
3907 /* child: this clobbers and resets the import lock. */
3908 PyOS_AfterFork();
3909 } else {
3910 /* parent: release the import lock. */
3911 result = _PyImport_ReleaseLock();
3912 }
3913 if (pid == -1)
3914 return posix_error();
3915 if (result < 0) {
3916 /* Don't clobber the OSError if the fork failed. */
3917 PyErr_SetString(PyExc_RuntimeError,
3918 "not holding the import lock");
3919 return NULL;
3920 }
3921 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003922}
3923#endif
3924
3925
Guido van Rossumad0ee831995-03-01 10:34:45 +00003926#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003927PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003928"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003929Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003930Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003931
Barry Warsaw53699e91996-12-10 23:23:01 +00003932static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003933posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003934{
Victor Stinner8c62be82010-05-06 00:08:46 +00003935 pid_t pid;
3936 int result = 0;
3937 _PyImport_AcquireLock();
3938 pid = fork();
3939 if (pid == 0) {
3940 /* child: this clobbers and resets the import lock. */
3941 PyOS_AfterFork();
3942 } else {
3943 /* parent: release the import lock. */
3944 result = _PyImport_ReleaseLock();
3945 }
3946 if (pid == -1)
3947 return posix_error();
3948 if (result < 0) {
3949 /* Don't clobber the OSError if the fork failed. */
3950 PyErr_SetString(PyExc_RuntimeError,
3951 "not holding the import lock");
3952 return NULL;
3953 }
3954 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003955}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003956#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003957
Neal Norwitzb59798b2003-03-21 01:43:31 +00003958/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003959/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3960#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003961#define DEV_PTY_FILE "/dev/ptc"
3962#define HAVE_DEV_PTMX
3963#else
3964#define DEV_PTY_FILE "/dev/ptmx"
3965#endif
3966
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003967#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003968#ifdef HAVE_PTY_H
3969#include <pty.h>
3970#else
3971#ifdef HAVE_LIBUTIL_H
3972#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00003973#else
3974#ifdef HAVE_UTIL_H
3975#include <util.h>
3976#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003977#endif /* HAVE_LIBUTIL_H */
3978#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003979#ifdef HAVE_STROPTS_H
3980#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003981#endif
3982#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003983
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003984#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003985PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003986"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003987Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003988
3989static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003990posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003991{
Victor Stinner8c62be82010-05-06 00:08:46 +00003992 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003993#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00003994 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003995#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003996#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003997 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003998#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00003999 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004000#endif
4001#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00004002
Thomas Wouters70c21a12000-07-14 14:28:33 +00004003#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004004 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
4005 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004006#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004007 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
4008 if (slave_name == NULL)
4009 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00004010
Victor Stinner8c62be82010-05-06 00:08:46 +00004011 slave_fd = open(slave_name, O_RDWR);
4012 if (slave_fd < 0)
4013 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004014#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004015 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
4016 if (master_fd < 0)
4017 return posix_error();
4018 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
4019 /* change permission of slave */
4020 if (grantpt(master_fd) < 0) {
4021 PyOS_setsig(SIGCHLD, sig_saved);
4022 return posix_error();
4023 }
4024 /* unlock slave */
4025 if (unlockpt(master_fd) < 0) {
4026 PyOS_setsig(SIGCHLD, sig_saved);
4027 return posix_error();
4028 }
4029 PyOS_setsig(SIGCHLD, sig_saved);
4030 slave_name = ptsname(master_fd); /* get name of slave */
4031 if (slave_name == NULL)
4032 return posix_error();
4033 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
4034 if (slave_fd < 0)
4035 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004036#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004037 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
4038 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00004039#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00004040 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00004041#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004042#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00004043#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00004044
Victor Stinner8c62be82010-05-06 00:08:46 +00004045 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00004046
Fred Drake8cef4cf2000-06-28 16:40:38 +00004047}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004048#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004049
4050#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004051PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004052"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00004053Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
4054Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004055To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004056
4057static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004058posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004059{
Victor Stinner8c62be82010-05-06 00:08:46 +00004060 int master_fd = -1, result = 0;
4061 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00004062
Victor Stinner8c62be82010-05-06 00:08:46 +00004063 _PyImport_AcquireLock();
4064 pid = forkpty(&master_fd, NULL, NULL, NULL);
4065 if (pid == 0) {
4066 /* child: this clobbers and resets the import lock. */
4067 PyOS_AfterFork();
4068 } else {
4069 /* parent: release the import lock. */
4070 result = _PyImport_ReleaseLock();
4071 }
4072 if (pid == -1)
4073 return posix_error();
4074 if (result < 0) {
4075 /* Don't clobber the OSError if the fork failed. */
4076 PyErr_SetString(PyExc_RuntimeError,
4077 "not holding the import lock");
4078 return NULL;
4079 }
4080 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004081}
4082#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004083
Guido van Rossumad0ee831995-03-01 10:34:45 +00004084#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004085PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004086"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004087Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004088
Barry Warsaw53699e91996-12-10 23:23:01 +00004089static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004090posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004091{
Victor Stinner8c62be82010-05-06 00:08:46 +00004092 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004093}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004094#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004095
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004096
Guido van Rossumad0ee831995-03-01 10:34:45 +00004097#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004098PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004099"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004100Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004101
Barry Warsaw53699e91996-12-10 23:23:01 +00004102static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004103posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004104{
Victor Stinner8c62be82010-05-06 00:08:46 +00004105 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004106}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004107#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004108
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004109
Guido van Rossumad0ee831995-03-01 10:34:45 +00004110#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004111PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004112"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004113Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004114
Barry Warsaw53699e91996-12-10 23:23:01 +00004115static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004116posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004117{
Victor Stinner8c62be82010-05-06 00:08:46 +00004118 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004119}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004120#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004121
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004122
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004123PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004124"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004125Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004126
Barry Warsaw53699e91996-12-10 23:23:01 +00004127static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004128posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004129{
Victor Stinner8c62be82010-05-06 00:08:46 +00004130 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004131}
4132
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004133
Fred Drakec9680921999-12-13 16:37:25 +00004134#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004135PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004136"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004137Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004138
4139static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004140posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004141{
4142 PyObject *result = NULL;
4143
Fred Drakec9680921999-12-13 16:37:25 +00004144#ifdef NGROUPS_MAX
4145#define MAX_GROUPS NGROUPS_MAX
4146#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004147 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004148#define MAX_GROUPS 64
4149#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004150 gid_t grouplist[MAX_GROUPS];
4151 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004152
Victor Stinner8c62be82010-05-06 00:08:46 +00004153 n = getgroups(MAX_GROUPS, grouplist);
4154 if (n < 0)
4155 posix_error();
4156 else {
4157 result = PyList_New(n);
4158 if (result != NULL) {
4159 int i;
4160 for (i = 0; i < n; ++i) {
4161 PyObject *o = PyLong_FromLong((long)grouplist[i]);
4162 if (o == NULL) {
4163 Py_DECREF(result);
4164 result = NULL;
4165 break;
Fred Drakec9680921999-12-13 16:37:25 +00004166 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004167 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004168 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004169 }
4170 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004171
Fred Drakec9680921999-12-13 16:37:25 +00004172 return result;
4173}
4174#endif
4175
Antoine Pitroub7572f02009-12-02 20:46:48 +00004176#ifdef HAVE_INITGROUPS
4177PyDoc_STRVAR(posix_initgroups__doc__,
4178"initgroups(username, gid) -> None\n\n\
4179Call the system initgroups() to initialize the group access list with all of\n\
4180the groups of which the specified username is a member, plus the specified\n\
4181group id.");
4182
4183static PyObject *
4184posix_initgroups(PyObject *self, PyObject *args)
4185{
Victor Stinner8c62be82010-05-06 00:08:46 +00004186 char *username;
4187 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004188
Victor Stinner8c62be82010-05-06 00:08:46 +00004189 if (!PyArg_ParseTuple(args, "sl:initgroups", &username, &gid))
4190 return NULL;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004191
Victor Stinner8c62be82010-05-06 00:08:46 +00004192 if (initgroups(username, (gid_t) gid) == -1)
4193 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004194
Victor Stinner8c62be82010-05-06 00:08:46 +00004195 Py_INCREF(Py_None);
4196 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004197}
4198#endif
4199
Martin v. Löwis606edc12002-06-13 21:09:11 +00004200#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004201PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004202"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004203Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004204
4205static PyObject *
4206posix_getpgid(PyObject *self, PyObject *args)
4207{
Victor Stinner8c62be82010-05-06 00:08:46 +00004208 pid_t pid, pgid;
4209 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
4210 return NULL;
4211 pgid = getpgid(pid);
4212 if (pgid < 0)
4213 return posix_error();
4214 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004215}
4216#endif /* HAVE_GETPGID */
4217
4218
Guido van Rossumb6775db1994-08-01 11:34:53 +00004219#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004220PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004221"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004222Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004223
Barry Warsaw53699e91996-12-10 23:23:01 +00004224static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004225posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004226{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004227#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004228 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004229#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004230 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004231#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004232}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004233#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004234
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004235
Guido van Rossumb6775db1994-08-01 11:34:53 +00004236#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004237PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004238"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00004239Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004240
Barry Warsaw53699e91996-12-10 23:23:01 +00004241static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004242posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004243{
Guido van Rossum64933891994-10-20 21:56:42 +00004244#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004245 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004246#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004247 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004248#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004249 return posix_error();
4250 Py_INCREF(Py_None);
4251 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004252}
4253
Guido van Rossumb6775db1994-08-01 11:34:53 +00004254#endif /* HAVE_SETPGRP */
4255
Guido van Rossumad0ee831995-03-01 10:34:45 +00004256#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004257PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004258"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004259Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004260
Barry Warsaw53699e91996-12-10 23:23:01 +00004261static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004262posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004263{
Victor Stinner8c62be82010-05-06 00:08:46 +00004264 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004265}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004266#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004267
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004268
Fred Drake12c6e2d1999-12-14 21:25:03 +00004269#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004270PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004271"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004272Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004273
4274static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004275posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004276{
Victor Stinner8c62be82010-05-06 00:08:46 +00004277 PyObject *result = NULL;
4278 char *name;
4279 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004280
Victor Stinner8c62be82010-05-06 00:08:46 +00004281 errno = 0;
4282 name = getlogin();
4283 if (name == NULL) {
4284 if (errno)
4285 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004286 else
Victor Stinner8c62be82010-05-06 00:08:46 +00004287 PyErr_SetString(PyExc_OSError,
4288 "unable to determine login name");
4289 }
4290 else
4291 result = PyUnicode_FromString(name);
4292 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004293
Fred Drake12c6e2d1999-12-14 21:25:03 +00004294 return result;
4295}
4296#endif
4297
Guido van Rossumad0ee831995-03-01 10:34:45 +00004298#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004299PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004300"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004301Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004302
Barry Warsaw53699e91996-12-10 23:23:01 +00004303static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004304posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004305{
Victor Stinner8c62be82010-05-06 00:08:46 +00004306 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004307}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004308#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004309
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004310
Guido van Rossumad0ee831995-03-01 10:34:45 +00004311#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004312PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004313"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004314Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004315
Barry Warsaw53699e91996-12-10 23:23:01 +00004316static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004317posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004318{
Victor Stinner8c62be82010-05-06 00:08:46 +00004319 pid_t pid;
4320 int sig;
4321 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
4322 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004323#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004324 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4325 APIRET rc;
4326 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004327 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004328
4329 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4330 APIRET rc;
4331 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004332 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004333
4334 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004335 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004336#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004337 if (kill(pid, sig) == -1)
4338 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004339#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004340 Py_INCREF(Py_None);
4341 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004342}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004343#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004344
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004345#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004346PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004347"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004348Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004349
4350static PyObject *
4351posix_killpg(PyObject *self, PyObject *args)
4352{
Victor Stinner8c62be82010-05-06 00:08:46 +00004353 int sig;
4354 pid_t pgid;
4355 /* XXX some man pages make the `pgid` parameter an int, others
4356 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4357 take the same type. Moreover, pid_t is always at least as wide as
4358 int (else compilation of this module fails), which is safe. */
4359 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
4360 return NULL;
4361 if (killpg(pgid, sig) == -1)
4362 return posix_error();
4363 Py_INCREF(Py_None);
4364 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004365}
4366#endif
4367
Brian Curtineb24d742010-04-12 17:16:38 +00004368#ifdef MS_WINDOWS
4369PyDoc_STRVAR(win32_kill__doc__,
4370"kill(pid, sig)\n\n\
4371Kill a process with a signal.");
4372
4373static PyObject *
4374win32_kill(PyObject *self, PyObject *args)
4375{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00004376 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004377 DWORD pid, sig, err;
4378 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00004379
Victor Stinner8c62be82010-05-06 00:08:46 +00004380 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4381 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00004382
Victor Stinner8c62be82010-05-06 00:08:46 +00004383 /* Console processes which share a common console can be sent CTRL+C or
4384 CTRL+BREAK events, provided they handle said events. */
4385 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4386 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4387 err = GetLastError();
4388 PyErr_SetFromWindowsErr(err);
4389 }
4390 else
4391 Py_RETURN_NONE;
4392 }
Brian Curtineb24d742010-04-12 17:16:38 +00004393
Victor Stinner8c62be82010-05-06 00:08:46 +00004394 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4395 attempt to open and terminate the process. */
4396 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4397 if (handle == NULL) {
4398 err = GetLastError();
4399 return PyErr_SetFromWindowsErr(err);
4400 }
Brian Curtineb24d742010-04-12 17:16:38 +00004401
Victor Stinner8c62be82010-05-06 00:08:46 +00004402 if (TerminateProcess(handle, sig) == 0) {
4403 err = GetLastError();
4404 result = PyErr_SetFromWindowsErr(err);
4405 } else {
4406 Py_INCREF(Py_None);
4407 result = Py_None;
4408 }
Brian Curtineb24d742010-04-12 17:16:38 +00004409
Victor Stinner8c62be82010-05-06 00:08:46 +00004410 CloseHandle(handle);
4411 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00004412}
4413#endif /* MS_WINDOWS */
4414
Guido van Rossumc0125471996-06-28 18:55:32 +00004415#ifdef HAVE_PLOCK
4416
4417#ifdef HAVE_SYS_LOCK_H
4418#include <sys/lock.h>
4419#endif
4420
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004421PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004422"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004423Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004424
Barry Warsaw53699e91996-12-10 23:23:01 +00004425static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004426posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004427{
Victor Stinner8c62be82010-05-06 00:08:46 +00004428 int op;
4429 if (!PyArg_ParseTuple(args, "i:plock", &op))
4430 return NULL;
4431 if (plock(op) == -1)
4432 return posix_error();
4433 Py_INCREF(Py_None);
4434 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004435}
4436#endif
4437
Guido van Rossumb6775db1994-08-01 11:34:53 +00004438#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004439PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004440"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004441Set the current process's user id.");
4442
Barry Warsaw53699e91996-12-10 23:23:01 +00004443static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004444posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004445{
Victor Stinner8c62be82010-05-06 00:08:46 +00004446 long uid_arg;
4447 uid_t uid;
4448 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
4449 return NULL;
4450 uid = uid_arg;
4451 if (uid != uid_arg) {
4452 PyErr_SetString(PyExc_OverflowError, "user id too big");
4453 return NULL;
4454 }
4455 if (setuid(uid) < 0)
4456 return posix_error();
4457 Py_INCREF(Py_None);
4458 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004459}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004460#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004461
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004462
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004463#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004464PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004465"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004466Set the current process's effective user id.");
4467
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004468static PyObject *
4469posix_seteuid (PyObject *self, PyObject *args)
4470{
Victor Stinner8c62be82010-05-06 00:08:46 +00004471 long euid_arg;
4472 uid_t euid;
4473 if (!PyArg_ParseTuple(args, "l", &euid_arg))
4474 return NULL;
4475 euid = euid_arg;
4476 if (euid != euid_arg) {
4477 PyErr_SetString(PyExc_OverflowError, "user id too big");
4478 return NULL;
4479 }
4480 if (seteuid(euid) < 0) {
4481 return posix_error();
4482 } else {
4483 Py_INCREF(Py_None);
4484 return Py_None;
4485 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004486}
4487#endif /* HAVE_SETEUID */
4488
4489#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004490PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004491"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004492Set the current process's effective group id.");
4493
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004494static PyObject *
4495posix_setegid (PyObject *self, PyObject *args)
4496{
Victor Stinner8c62be82010-05-06 00:08:46 +00004497 long egid_arg;
4498 gid_t egid;
4499 if (!PyArg_ParseTuple(args, "l", &egid_arg))
4500 return NULL;
4501 egid = egid_arg;
4502 if (egid != egid_arg) {
4503 PyErr_SetString(PyExc_OverflowError, "group id too big");
4504 return NULL;
4505 }
4506 if (setegid(egid) < 0) {
4507 return posix_error();
4508 } else {
4509 Py_INCREF(Py_None);
4510 return Py_None;
4511 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004512}
4513#endif /* HAVE_SETEGID */
4514
4515#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004516PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004517"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004518Set the current process's real and effective user ids.");
4519
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004520static PyObject *
4521posix_setreuid (PyObject *self, PyObject *args)
4522{
Victor Stinner8c62be82010-05-06 00:08:46 +00004523 long ruid_arg, euid_arg;
4524 uid_t ruid, euid;
4525 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
4526 return NULL;
4527 if (ruid_arg == -1)
4528 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
4529 else
4530 ruid = ruid_arg; /* otherwise, assign from our long */
4531 if (euid_arg == -1)
4532 euid = (uid_t)-1;
4533 else
4534 euid = euid_arg;
4535 if ((euid_arg != -1 && euid != euid_arg) ||
4536 (ruid_arg != -1 && ruid != ruid_arg)) {
4537 PyErr_SetString(PyExc_OverflowError, "user id too big");
4538 return NULL;
4539 }
4540 if (setreuid(ruid, euid) < 0) {
4541 return posix_error();
4542 } else {
4543 Py_INCREF(Py_None);
4544 return Py_None;
4545 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004546}
4547#endif /* HAVE_SETREUID */
4548
4549#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004550PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004551"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004552Set the current process's real and effective group ids.");
4553
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004554static PyObject *
4555posix_setregid (PyObject *self, PyObject *args)
4556{
Victor Stinner8c62be82010-05-06 00:08:46 +00004557 long rgid_arg, egid_arg;
4558 gid_t rgid, egid;
4559 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
4560 return NULL;
4561 if (rgid_arg == -1)
4562 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
4563 else
4564 rgid = rgid_arg; /* otherwise, assign from our long */
4565 if (egid_arg == -1)
4566 egid = (gid_t)-1;
4567 else
4568 egid = egid_arg;
4569 if ((egid_arg != -1 && egid != egid_arg) ||
4570 (rgid_arg != -1 && rgid != rgid_arg)) {
4571 PyErr_SetString(PyExc_OverflowError, "group id too big");
4572 return NULL;
4573 }
4574 if (setregid(rgid, egid) < 0) {
4575 return posix_error();
4576 } else {
4577 Py_INCREF(Py_None);
4578 return Py_None;
4579 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004580}
4581#endif /* HAVE_SETREGID */
4582
Guido van Rossumb6775db1994-08-01 11:34:53 +00004583#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004584PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004585"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004586Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004587
Barry Warsaw53699e91996-12-10 23:23:01 +00004588static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004589posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004590{
Victor Stinner8c62be82010-05-06 00:08:46 +00004591 long gid_arg;
4592 gid_t gid;
4593 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
4594 return NULL;
4595 gid = gid_arg;
4596 if (gid != gid_arg) {
4597 PyErr_SetString(PyExc_OverflowError, "group id too big");
4598 return NULL;
4599 }
4600 if (setgid(gid) < 0)
4601 return posix_error();
4602 Py_INCREF(Py_None);
4603 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004604}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004605#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004606
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004607#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004608PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004609"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004610Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004611
4612static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004613posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004614{
Victor Stinner8c62be82010-05-06 00:08:46 +00004615 int i, len;
4616 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004617
Victor Stinner8c62be82010-05-06 00:08:46 +00004618 if (!PySequence_Check(groups)) {
4619 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4620 return NULL;
4621 }
4622 len = PySequence_Size(groups);
4623 if (len > MAX_GROUPS) {
4624 PyErr_SetString(PyExc_ValueError, "too many groups");
4625 return NULL;
4626 }
4627 for(i = 0; i < len; i++) {
4628 PyObject *elem;
4629 elem = PySequence_GetItem(groups, i);
4630 if (!elem)
4631 return NULL;
4632 if (!PyLong_Check(elem)) {
4633 PyErr_SetString(PyExc_TypeError,
4634 "groups must be integers");
4635 Py_DECREF(elem);
4636 return NULL;
4637 } else {
4638 unsigned long x = PyLong_AsUnsignedLong(elem);
4639 if (PyErr_Occurred()) {
4640 PyErr_SetString(PyExc_TypeError,
4641 "group id too big");
4642 Py_DECREF(elem);
4643 return NULL;
4644 }
4645 grouplist[i] = x;
4646 /* read back the value to see if it fitted in gid_t */
4647 if (grouplist[i] != x) {
4648 PyErr_SetString(PyExc_TypeError,
4649 "group id too big");
4650 Py_DECREF(elem);
4651 return NULL;
4652 }
4653 }
4654 Py_DECREF(elem);
4655 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004656
Victor Stinner8c62be82010-05-06 00:08:46 +00004657 if (setgroups(len, grouplist) < 0)
4658 return posix_error();
4659 Py_INCREF(Py_None);
4660 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004661}
4662#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004663
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004664#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4665static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004666wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004667{
Victor Stinner8c62be82010-05-06 00:08:46 +00004668 PyObject *result;
4669 static PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004670
Victor Stinner8c62be82010-05-06 00:08:46 +00004671 if (pid == -1)
4672 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004673
Victor Stinner8c62be82010-05-06 00:08:46 +00004674 if (struct_rusage == NULL) {
4675 PyObject *m = PyImport_ImportModuleNoBlock("resource");
4676 if (m == NULL)
4677 return NULL;
4678 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4679 Py_DECREF(m);
4680 if (struct_rusage == NULL)
4681 return NULL;
4682 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004683
Victor Stinner8c62be82010-05-06 00:08:46 +00004684 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4685 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4686 if (!result)
4687 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004688
4689#ifndef doubletime
4690#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4691#endif
4692
Victor Stinner8c62be82010-05-06 00:08:46 +00004693 PyStructSequence_SET_ITEM(result, 0,
4694 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4695 PyStructSequence_SET_ITEM(result, 1,
4696 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004697#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00004698 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
4699 SET_INT(result, 2, ru->ru_maxrss);
4700 SET_INT(result, 3, ru->ru_ixrss);
4701 SET_INT(result, 4, ru->ru_idrss);
4702 SET_INT(result, 5, ru->ru_isrss);
4703 SET_INT(result, 6, ru->ru_minflt);
4704 SET_INT(result, 7, ru->ru_majflt);
4705 SET_INT(result, 8, ru->ru_nswap);
4706 SET_INT(result, 9, ru->ru_inblock);
4707 SET_INT(result, 10, ru->ru_oublock);
4708 SET_INT(result, 11, ru->ru_msgsnd);
4709 SET_INT(result, 12, ru->ru_msgrcv);
4710 SET_INT(result, 13, ru->ru_nsignals);
4711 SET_INT(result, 14, ru->ru_nvcsw);
4712 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004713#undef SET_INT
4714
Victor Stinner8c62be82010-05-06 00:08:46 +00004715 if (PyErr_Occurred()) {
4716 Py_DECREF(result);
4717 return NULL;
4718 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004719
Victor Stinner8c62be82010-05-06 00:08:46 +00004720 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004721}
4722#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4723
4724#ifdef HAVE_WAIT3
4725PyDoc_STRVAR(posix_wait3__doc__,
4726"wait3(options) -> (pid, status, rusage)\n\n\
4727Wait for completion of a child process.");
4728
4729static PyObject *
4730posix_wait3(PyObject *self, PyObject *args)
4731{
Victor Stinner8c62be82010-05-06 00:08:46 +00004732 pid_t pid;
4733 int options;
4734 struct rusage ru;
4735 WAIT_TYPE status;
4736 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004737
Victor Stinner8c62be82010-05-06 00:08:46 +00004738 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4739 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004740
Victor Stinner8c62be82010-05-06 00:08:46 +00004741 Py_BEGIN_ALLOW_THREADS
4742 pid = wait3(&status, options, &ru);
4743 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004744
Victor Stinner8c62be82010-05-06 00:08:46 +00004745 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004746}
4747#endif /* HAVE_WAIT3 */
4748
4749#ifdef HAVE_WAIT4
4750PyDoc_STRVAR(posix_wait4__doc__,
4751"wait4(pid, options) -> (pid, status, rusage)\n\n\
4752Wait for completion of a given child process.");
4753
4754static PyObject *
4755posix_wait4(PyObject *self, PyObject *args)
4756{
Victor Stinner8c62be82010-05-06 00:08:46 +00004757 pid_t pid;
4758 int options;
4759 struct rusage ru;
4760 WAIT_TYPE status;
4761 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004762
Victor Stinner8c62be82010-05-06 00:08:46 +00004763 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
4764 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004765
Victor Stinner8c62be82010-05-06 00:08:46 +00004766 Py_BEGIN_ALLOW_THREADS
4767 pid = wait4(pid, &status, options, &ru);
4768 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004769
Victor Stinner8c62be82010-05-06 00:08:46 +00004770 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004771}
4772#endif /* HAVE_WAIT4 */
4773
Guido van Rossumb6775db1994-08-01 11:34:53 +00004774#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004775PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004776"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004777Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004778
Barry Warsaw53699e91996-12-10 23:23:01 +00004779static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004780posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004781{
Victor Stinner8c62be82010-05-06 00:08:46 +00004782 pid_t pid;
4783 int options;
4784 WAIT_TYPE status;
4785 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004786
Victor Stinner8c62be82010-05-06 00:08:46 +00004787 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4788 return NULL;
4789 Py_BEGIN_ALLOW_THREADS
4790 pid = waitpid(pid, &status, options);
4791 Py_END_ALLOW_THREADS
4792 if (pid == -1)
4793 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004794
Victor Stinner8c62be82010-05-06 00:08:46 +00004795 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004796}
4797
Tim Petersab034fa2002-02-01 11:27:43 +00004798#elif defined(HAVE_CWAIT)
4799
4800/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004801PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004802"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004803"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004804
4805static PyObject *
4806posix_waitpid(PyObject *self, PyObject *args)
4807{
Victor Stinner8c62be82010-05-06 00:08:46 +00004808 Py_intptr_t pid;
4809 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004810
Victor Stinner8c62be82010-05-06 00:08:46 +00004811 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4812 return NULL;
4813 Py_BEGIN_ALLOW_THREADS
4814 pid = _cwait(&status, pid, options);
4815 Py_END_ALLOW_THREADS
4816 if (pid == -1)
4817 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004818
Victor Stinner8c62be82010-05-06 00:08:46 +00004819 /* shift the status left a byte so this is more like the POSIX waitpid */
4820 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004821}
4822#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004823
Guido van Rossumad0ee831995-03-01 10:34:45 +00004824#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004825PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004826"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004827Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004828
Barry Warsaw53699e91996-12-10 23:23:01 +00004829static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004830posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004831{
Victor Stinner8c62be82010-05-06 00:08:46 +00004832 pid_t pid;
4833 WAIT_TYPE status;
4834 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004835
Victor Stinner8c62be82010-05-06 00:08:46 +00004836 Py_BEGIN_ALLOW_THREADS
4837 pid = wait(&status);
4838 Py_END_ALLOW_THREADS
4839 if (pid == -1)
4840 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004841
Victor Stinner8c62be82010-05-06 00:08:46 +00004842 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00004843}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004844#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004845
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004846
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004847PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004848"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004849Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004850
Barry Warsaw53699e91996-12-10 23:23:01 +00004851static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004852posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004853{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004854#ifdef HAVE_LSTAT
Victor Stinner8c62be82010-05-06 00:08:46 +00004855 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004856#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004857#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00004858 return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat",
4859 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004860#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004861 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004862#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004863#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004864}
4865
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004866
Guido van Rossumb6775db1994-08-01 11:34:53 +00004867#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004868PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004869"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004870Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004871
Barry Warsaw53699e91996-12-10 23:23:01 +00004872static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004873posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004874{
Victor Stinner8c62be82010-05-06 00:08:46 +00004875 PyObject* v;
4876 char buf[MAXPATHLEN];
4877 PyObject *opath;
4878 char *path;
4879 int n;
4880 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004881
Victor Stinner8c62be82010-05-06 00:08:46 +00004882 if (!PyArg_ParseTuple(args, "O&:readlink",
4883 PyUnicode_FSConverter, &opath))
4884 return NULL;
4885 path = PyBytes_AsString(opath);
4886 v = PySequence_GetItem(args, 0);
4887 if (v == NULL) {
4888 Py_DECREF(opath);
4889 return NULL;
4890 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004891
Victor Stinner8c62be82010-05-06 00:08:46 +00004892 if (PyUnicode_Check(v)) {
4893 arg_is_unicode = 1;
4894 }
4895 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004896
Victor Stinner8c62be82010-05-06 00:08:46 +00004897 Py_BEGIN_ALLOW_THREADS
4898 n = readlink(path, buf, (int) sizeof buf);
4899 Py_END_ALLOW_THREADS
4900 if (n < 0)
4901 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004902
Victor Stinner8c62be82010-05-06 00:08:46 +00004903 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00004904 if (arg_is_unicode)
4905 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
4906 else
4907 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004908}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004909#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004910
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004911
Guido van Rossumb6775db1994-08-01 11:34:53 +00004912#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004913PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004914"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00004915Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004916
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004917static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004918posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004919{
Victor Stinner8c62be82010-05-06 00:08:46 +00004920 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004921}
4922#endif /* HAVE_SYMLINK */
4923
Brian Curtind40e6f72010-07-08 21:39:08 +00004924#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
4925
4926PyDoc_STRVAR(win_readlink__doc__,
4927"readlink(path) -> path\n\n\
4928Return a string representing the path to which the symbolic link points.");
4929
4930/* The following structure was copied from
4931 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
4932 include doesn't seem to be present in the Windows SDK (at least as included
4933 with Visual Studio Express). */
4934typedef struct _REPARSE_DATA_BUFFER {
4935 ULONG ReparseTag;
4936 USHORT ReparseDataLength;
4937 USHORT Reserved;
4938 union {
4939 struct {
4940 USHORT SubstituteNameOffset;
4941 USHORT SubstituteNameLength;
4942 USHORT PrintNameOffset;
4943 USHORT PrintNameLength;
4944 ULONG Flags;
4945 WCHAR PathBuffer[1];
4946 } SymbolicLinkReparseBuffer;
4947
4948 struct {
4949 USHORT SubstituteNameOffset;
4950 USHORT SubstituteNameLength;
4951 USHORT PrintNameOffset;
4952 USHORT PrintNameLength;
4953 WCHAR PathBuffer[1];
4954 } MountPointReparseBuffer;
4955
4956 struct {
4957 UCHAR DataBuffer[1];
4958 } GenericReparseBuffer;
4959 };
4960} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
4961
4962#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer)
4963
4964#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
4965
4966/* Windows readlink implementation */
4967static PyObject *
4968win_readlink(PyObject *self, PyObject *args)
4969{
4970 wchar_t *path;
4971 DWORD n_bytes_returned;
4972 DWORD io_result;
4973 PyObject *result;
4974 HANDLE reparse_point_handle;
4975
4976 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
4977 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
4978 wchar_t *print_name;
4979
4980 if (!PyArg_ParseTuple(args,
4981 "u:readlink",
4982 &path))
4983 return NULL;
4984
4985 /* First get a handle to the reparse point */
4986 Py_BEGIN_ALLOW_THREADS
4987 reparse_point_handle = CreateFileW(
4988 path,
4989 0,
4990 0,
4991 0,
4992 OPEN_EXISTING,
4993 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
4994 0);
4995 Py_END_ALLOW_THREADS
4996
4997 if (reparse_point_handle==INVALID_HANDLE_VALUE)
4998 {
4999 return win32_error_unicode("readlink", path);
5000 }
5001
5002 Py_BEGIN_ALLOW_THREADS
5003 /* New call DeviceIoControl to read the reparse point */
5004 io_result = DeviceIoControl(
5005 reparse_point_handle,
5006 FSCTL_GET_REPARSE_POINT,
5007 0, 0, /* in buffer */
5008 target_buffer, sizeof(target_buffer),
5009 &n_bytes_returned,
5010 0 /* we're not using OVERLAPPED_IO */
5011 );
5012 CloseHandle(reparse_point_handle);
5013 Py_END_ALLOW_THREADS
5014
5015 if (io_result==0)
5016 {
5017 return win32_error_unicode("readlink", path);
5018 }
5019
5020 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
5021 {
5022 PyErr_SetString(PyExc_ValueError,
5023 "not a symbolic link");
5024 return NULL;
5025 }
5026 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer + rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
5027 result = PyUnicode_FromWideChar(print_name, rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
5028 return result;
5029}
5030
5031#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
5032
5033#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
5034
5035/* Grab CreateSymbolicLinkW dynamically from kernel32 */
5036static int has_CreateSymbolicLinkW = 0;
5037static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
5038static int
5039check_CreateSymbolicLinkW()
5040{
5041 HINSTANCE hKernel32;
5042 /* only recheck */
5043 if (has_CreateSymbolicLinkW)
5044 return has_CreateSymbolicLinkW;
5045 hKernel32 = GetModuleHandle("KERNEL32");
5046 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32, "CreateSymbolicLinkW");
5047 if (Py_CreateSymbolicLinkW)
5048 has_CreateSymbolicLinkW = 1;
5049 return has_CreateSymbolicLinkW;
5050}
5051
5052PyDoc_STRVAR(win_symlink__doc__,
5053"symlink(src, dst, target_is_directory=False)\n\n\
5054Create a symbolic link pointing to src named dst.\n\
5055target_is_directory is required if the target is to be interpreted as\n\
5056a directory.\n\
5057This function requires Windows 6.0 or greater, and raises a\n\
5058NotImplementedError otherwise.");
5059
5060static PyObject *
5061win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
5062{
5063 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
5064 PyObject *src, *dest;
5065 int target_is_directory = 0;
5066 DWORD res;
5067 WIN32_FILE_ATTRIBUTE_DATA src_info;
5068
5069 if (!check_CreateSymbolicLinkW())
5070 {
5071 /* raise NotImplementedError */
5072 return PyErr_Format(PyExc_NotImplementedError,
5073 "CreateSymbolicLinkW not found");
5074 }
5075 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:symlink",
5076 kwlist, &src, &dest, &target_is_directory))
5077 return NULL;
5078 if (!convert_to_unicode(&src)) { return NULL; }
5079 if (!convert_to_unicode(&dest)) {
5080 Py_DECREF(src);
5081 return NULL;
5082 }
5083
5084 /* if src is a directory, ensure target_is_directory==1 */
5085 if(
5086 GetFileAttributesExW(
5087 PyUnicode_AsUnicode(src), GetFileExInfoStandard, &src_info
5088 ))
5089 {
5090 target_is_directory = target_is_directory ||
5091 (src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
5092 }
5093
5094 Py_BEGIN_ALLOW_THREADS
5095 res = Py_CreateSymbolicLinkW(
5096 PyUnicode_AsUnicode(dest),
5097 PyUnicode_AsUnicode(src),
5098 target_is_directory);
5099 Py_END_ALLOW_THREADS
5100 Py_DECREF(src);
5101 Py_DECREF(dest);
5102 if (!res)
5103 {
5104 return win32_error_unicode("symlink", PyUnicode_AsUnicode(src));
5105 }
5106
5107 Py_INCREF(Py_None);
5108 return Py_None;
5109}
5110#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005111
5112#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00005113#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5114static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005115system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005116{
5117 ULONG value = 0;
5118
5119 Py_BEGIN_ALLOW_THREADS
5120 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5121 Py_END_ALLOW_THREADS
5122
5123 return value;
5124}
5125
5126static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005127posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005128{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005129 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00005130 return Py_BuildValue("ddddd",
5131 (double)0 /* t.tms_utime / HZ */,
5132 (double)0 /* t.tms_stime / HZ */,
5133 (double)0 /* t.tms_cutime / HZ */,
5134 (double)0 /* t.tms_cstime / HZ */,
5135 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005136}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005137#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00005138#define NEED_TICKS_PER_SECOND
5139static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00005140static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005141posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005142{
Victor Stinner8c62be82010-05-06 00:08:46 +00005143 struct tms t;
5144 clock_t c;
5145 errno = 0;
5146 c = times(&t);
5147 if (c == (clock_t) -1)
5148 return posix_error();
5149 return Py_BuildValue("ddddd",
5150 (double)t.tms_utime / ticks_per_second,
5151 (double)t.tms_stime / ticks_per_second,
5152 (double)t.tms_cutime / ticks_per_second,
5153 (double)t.tms_cstime / ticks_per_second,
5154 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005155}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005156#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005157#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005158
5159
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005160#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005161#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005162static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005163posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005164{
Victor Stinner8c62be82010-05-06 00:08:46 +00005165 FILETIME create, exit, kernel, user;
5166 HANDLE hProc;
5167 hProc = GetCurrentProcess();
5168 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5169 /* The fields of a FILETIME structure are the hi and lo part
5170 of a 64-bit value expressed in 100 nanosecond units.
5171 1e7 is one second in such units; 1e-7 the inverse.
5172 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5173 */
5174 return Py_BuildValue(
5175 "ddddd",
5176 (double)(user.dwHighDateTime*429.4967296 +
5177 user.dwLowDateTime*1e-7),
5178 (double)(kernel.dwHighDateTime*429.4967296 +
5179 kernel.dwLowDateTime*1e-7),
5180 (double)0,
5181 (double)0,
5182 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005183}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005184#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005185
5186#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005187PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005188"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005189Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005190#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005191
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005192
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005193#ifdef HAVE_GETSID
5194PyDoc_STRVAR(posix_getsid__doc__,
5195"getsid(pid) -> sid\n\n\
5196Call the system call getsid().");
5197
5198static PyObject *
5199posix_getsid(PyObject *self, PyObject *args)
5200{
Victor Stinner8c62be82010-05-06 00:08:46 +00005201 pid_t pid;
5202 int sid;
5203 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
5204 return NULL;
5205 sid = getsid(pid);
5206 if (sid < 0)
5207 return posix_error();
5208 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005209}
5210#endif /* HAVE_GETSID */
5211
5212
Guido van Rossumb6775db1994-08-01 11:34:53 +00005213#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005214PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005215"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005216Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005217
Barry Warsaw53699e91996-12-10 23:23:01 +00005218static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005219posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005220{
Victor Stinner8c62be82010-05-06 00:08:46 +00005221 if (setsid() < 0)
5222 return posix_error();
5223 Py_INCREF(Py_None);
5224 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005225}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005226#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005227
Guido van Rossumb6775db1994-08-01 11:34:53 +00005228#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005229PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005230"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005231Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005232
Barry Warsaw53699e91996-12-10 23:23:01 +00005233static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005234posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005235{
Victor Stinner8c62be82010-05-06 00:08:46 +00005236 pid_t pid;
5237 int pgrp;
5238 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
5239 return NULL;
5240 if (setpgid(pid, pgrp) < 0)
5241 return posix_error();
5242 Py_INCREF(Py_None);
5243 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005244}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005245#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005246
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005247
Guido van Rossumb6775db1994-08-01 11:34:53 +00005248#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005249PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005250"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005251Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005252
Barry Warsaw53699e91996-12-10 23:23:01 +00005253static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005254posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005255{
Victor Stinner8c62be82010-05-06 00:08:46 +00005256 int fd;
5257 pid_t pgid;
5258 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
5259 return NULL;
5260 pgid = tcgetpgrp(fd);
5261 if (pgid < 0)
5262 return posix_error();
5263 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005264}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005265#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005266
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005267
Guido van Rossumb6775db1994-08-01 11:34:53 +00005268#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005269PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005270"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005271Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005272
Barry Warsaw53699e91996-12-10 23:23:01 +00005273static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005274posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005275{
Victor Stinner8c62be82010-05-06 00:08:46 +00005276 int fd;
5277 pid_t pgid;
5278 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
5279 return NULL;
5280 if (tcsetpgrp(fd, pgid) < 0)
5281 return posix_error();
5282 Py_INCREF(Py_None);
5283 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005284}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005285#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005286
Guido van Rossum687dd131993-05-17 08:34:16 +00005287/* Functions acting on file descriptors */
5288
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005289PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005290"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005291Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005292
Barry Warsaw53699e91996-12-10 23:23:01 +00005293static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005294posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005295{
Victor Stinner8c62be82010-05-06 00:08:46 +00005296 PyObject *ofile;
5297 char *file;
5298 int flag;
5299 int mode = 0777;
5300 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005301
5302#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005303 PyUnicodeObject *po;
5304 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5305 Py_BEGIN_ALLOW_THREADS
5306 /* PyUnicode_AS_UNICODE OK without thread
5307 lock as it is a simple dereference. */
5308 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5309 Py_END_ALLOW_THREADS
5310 if (fd < 0)
5311 return posix_error();
5312 return PyLong_FromLong((long)fd);
5313 }
5314 /* Drop the argument parsing error as narrow strings
5315 are also valid. */
5316 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005317#endif
5318
Victor Stinner8c62be82010-05-06 00:08:46 +00005319 if (!PyArg_ParseTuple(args, "O&i|i",
5320 PyUnicode_FSConverter, &ofile,
5321 &flag, &mode))
5322 return NULL;
5323 file = PyBytes_AsString(ofile);
5324 Py_BEGIN_ALLOW_THREADS
5325 fd = open(file, flag, mode);
5326 Py_END_ALLOW_THREADS
5327 if (fd < 0)
5328 return posix_error_with_allocated_filename(ofile);
5329 Py_DECREF(ofile);
5330 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005331}
5332
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005333
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005334PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005335"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005336Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005337
Barry Warsaw53699e91996-12-10 23:23:01 +00005338static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005339posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005340{
Victor Stinner8c62be82010-05-06 00:08:46 +00005341 int fd, res;
5342 if (!PyArg_ParseTuple(args, "i:close", &fd))
5343 return NULL;
5344 if (!_PyVerify_fd(fd))
5345 return posix_error();
5346 Py_BEGIN_ALLOW_THREADS
5347 res = close(fd);
5348 Py_END_ALLOW_THREADS
5349 if (res < 0)
5350 return posix_error();
5351 Py_INCREF(Py_None);
5352 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005353}
5354
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005355
Victor Stinner8c62be82010-05-06 00:08:46 +00005356PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00005357"closerange(fd_low, fd_high)\n\n\
5358Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
5359
5360static PyObject *
5361posix_closerange(PyObject *self, PyObject *args)
5362{
Victor Stinner8c62be82010-05-06 00:08:46 +00005363 int fd_from, fd_to, i;
5364 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
5365 return NULL;
5366 Py_BEGIN_ALLOW_THREADS
5367 for (i = fd_from; i < fd_to; i++)
5368 if (_PyVerify_fd(i))
5369 close(i);
5370 Py_END_ALLOW_THREADS
5371 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00005372}
5373
5374
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005375PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005376"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005377Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005378
Barry Warsaw53699e91996-12-10 23:23:01 +00005379static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005380posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005381{
Victor Stinner8c62be82010-05-06 00:08:46 +00005382 int fd;
5383 if (!PyArg_ParseTuple(args, "i:dup", &fd))
5384 return NULL;
5385 if (!_PyVerify_fd(fd))
5386 return posix_error();
5387 Py_BEGIN_ALLOW_THREADS
5388 fd = dup(fd);
5389 Py_END_ALLOW_THREADS
5390 if (fd < 0)
5391 return posix_error();
5392 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005393}
5394
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005395
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005396PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005397"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005398Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005399
Barry Warsaw53699e91996-12-10 23:23:01 +00005400static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005401posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005402{
Victor Stinner8c62be82010-05-06 00:08:46 +00005403 int fd, fd2, res;
5404 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5405 return NULL;
5406 if (!_PyVerify_fd_dup2(fd, fd2))
5407 return posix_error();
5408 Py_BEGIN_ALLOW_THREADS
5409 res = dup2(fd, fd2);
5410 Py_END_ALLOW_THREADS
5411 if (res < 0)
5412 return posix_error();
5413 Py_INCREF(Py_None);
5414 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005415}
5416
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005417
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005418PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005419"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005420Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005421
Barry Warsaw53699e91996-12-10 23:23:01 +00005422static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005423posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005424{
Victor Stinner8c62be82010-05-06 00:08:46 +00005425 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005426#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005427 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005428#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005429 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005430#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005431 PyObject *posobj;
5432 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5433 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005434#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00005435 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5436 switch (how) {
5437 case 0: how = SEEK_SET; break;
5438 case 1: how = SEEK_CUR; break;
5439 case 2: how = SEEK_END; break;
5440 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005441#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005442
5443#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005444 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005445#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005446 pos = PyLong_Check(posobj) ?
5447 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005448#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005449 if (PyErr_Occurred())
5450 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005451
Victor Stinner8c62be82010-05-06 00:08:46 +00005452 if (!_PyVerify_fd(fd))
5453 return posix_error();
5454 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005455#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005456 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005457#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005458 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005459#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005460 Py_END_ALLOW_THREADS
5461 if (res < 0)
5462 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005463
5464#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005465 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005466#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005467 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005468#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005469}
5470
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005471
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005472PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005473"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005474Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005475
Barry Warsaw53699e91996-12-10 23:23:01 +00005476static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005477posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005478{
Victor Stinner8c62be82010-05-06 00:08:46 +00005479 int fd, size;
5480 Py_ssize_t n;
5481 PyObject *buffer;
5482 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5483 return NULL;
5484 if (size < 0) {
5485 errno = EINVAL;
5486 return posix_error();
5487 }
5488 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
5489 if (buffer == NULL)
5490 return NULL;
5491 if (!_PyVerify_fd(fd))
5492 return posix_error();
5493 Py_BEGIN_ALLOW_THREADS
5494 n = read(fd, PyBytes_AS_STRING(buffer), size);
5495 Py_END_ALLOW_THREADS
5496 if (n < 0) {
5497 Py_DECREF(buffer);
5498 return posix_error();
5499 }
5500 if (n != size)
5501 _PyBytes_Resize(&buffer, n);
5502 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00005503}
5504
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005505
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005506PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005507"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005508Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005509
Barry Warsaw53699e91996-12-10 23:23:01 +00005510static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005511posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005512{
Victor Stinner8c62be82010-05-06 00:08:46 +00005513 Py_buffer pbuf;
5514 int fd;
5515 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005516
Victor Stinner8c62be82010-05-06 00:08:46 +00005517 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
5518 return NULL;
5519 if (!_PyVerify_fd(fd))
5520 return posix_error();
5521 Py_BEGIN_ALLOW_THREADS
5522 size = write(fd, pbuf.buf, (size_t)pbuf.len);
5523 Py_END_ALLOW_THREADS
5524 PyBuffer_Release(&pbuf);
5525 if (size < 0)
5526 return posix_error();
5527 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005528}
5529
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005530
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005531PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005532"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005533Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005534
Barry Warsaw53699e91996-12-10 23:23:01 +00005535static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005536posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005537{
Victor Stinner8c62be82010-05-06 00:08:46 +00005538 int fd;
5539 STRUCT_STAT st;
5540 int res;
5541 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5542 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005543#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00005544 /* on OpenVMS we must ensure that all bytes are written to the file */
5545 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005546#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005547 if (!_PyVerify_fd(fd))
5548 return posix_error();
5549 Py_BEGIN_ALLOW_THREADS
5550 res = FSTAT(fd, &st);
5551 Py_END_ALLOW_THREADS
5552 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00005553#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005554 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00005555#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005556 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005557#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005558 }
Tim Peters5aa91602002-01-30 05:46:57 +00005559
Victor Stinner8c62be82010-05-06 00:08:46 +00005560 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005561}
5562
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005563PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005564"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005565Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005566connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005567
5568static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005569posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005570{
Victor Stinner8c62be82010-05-06 00:08:46 +00005571 int fd;
5572 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5573 return NULL;
5574 if (!_PyVerify_fd(fd))
5575 return PyBool_FromLong(0);
5576 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005577}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005578
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005579#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005580PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005581"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005582Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005583
Barry Warsaw53699e91996-12-10 23:23:01 +00005584static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005585posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005586{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005587#if defined(PYOS_OS2)
5588 HFILE read, write;
5589 APIRET rc;
5590
Victor Stinner8c62be82010-05-06 00:08:46 +00005591 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005592 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinner8c62be82010-05-06 00:08:46 +00005593 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005594 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005595 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005596
5597 return Py_BuildValue("(ii)", read, write);
5598#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005599#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005600 int fds[2];
5601 int res;
5602 Py_BEGIN_ALLOW_THREADS
5603 res = pipe(fds);
5604 Py_END_ALLOW_THREADS
5605 if (res != 0)
5606 return posix_error();
5607 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005608#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00005609 HANDLE read, write;
5610 int read_fd, write_fd;
5611 BOOL ok;
5612 Py_BEGIN_ALLOW_THREADS
5613 ok = CreatePipe(&read, &write, NULL, 0);
5614 Py_END_ALLOW_THREADS
5615 if (!ok)
5616 return win32_error("CreatePipe", NULL);
5617 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5618 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5619 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005620#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005621#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005622}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005623#endif /* HAVE_PIPE */
5624
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005625
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005626#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005627PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005628"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005629Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005630
Barry Warsaw53699e91996-12-10 23:23:01 +00005631static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005632posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005633{
Victor Stinner8c62be82010-05-06 00:08:46 +00005634 char *filename;
5635 int mode = 0666;
5636 int res;
5637 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
5638 return NULL;
5639 Py_BEGIN_ALLOW_THREADS
5640 res = mkfifo(filename, mode);
5641 Py_END_ALLOW_THREADS
5642 if (res < 0)
5643 return posix_error();
5644 Py_INCREF(Py_None);
5645 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005646}
5647#endif
5648
5649
Neal Norwitz11690112002-07-30 01:08:28 +00005650#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005651PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005652"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005653Create a filesystem node (file, device special file or named pipe)\n\
5654named filename. mode specifies both the permissions to use and the\n\
5655type of node to be created, being combined (bitwise OR) with one of\n\
5656S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005657device defines the newly created device special file (probably using\n\
5658os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005659
5660
5661static PyObject *
5662posix_mknod(PyObject *self, PyObject *args)
5663{
Victor Stinner8c62be82010-05-06 00:08:46 +00005664 char *filename;
5665 int mode = 0600;
5666 int device = 0;
5667 int res;
5668 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
5669 return NULL;
5670 Py_BEGIN_ALLOW_THREADS
5671 res = mknod(filename, mode, device);
5672 Py_END_ALLOW_THREADS
5673 if (res < 0)
5674 return posix_error();
5675 Py_INCREF(Py_None);
5676 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005677}
5678#endif
5679
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005680#ifdef HAVE_DEVICE_MACROS
5681PyDoc_STRVAR(posix_major__doc__,
5682"major(device) -> major number\n\
5683Extracts a device major number from a raw device number.");
5684
5685static PyObject *
5686posix_major(PyObject *self, PyObject *args)
5687{
Victor Stinner8c62be82010-05-06 00:08:46 +00005688 int device;
5689 if (!PyArg_ParseTuple(args, "i:major", &device))
5690 return NULL;
5691 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005692}
5693
5694PyDoc_STRVAR(posix_minor__doc__,
5695"minor(device) -> minor number\n\
5696Extracts a device minor number from a raw device number.");
5697
5698static PyObject *
5699posix_minor(PyObject *self, PyObject *args)
5700{
Victor Stinner8c62be82010-05-06 00:08:46 +00005701 int device;
5702 if (!PyArg_ParseTuple(args, "i:minor", &device))
5703 return NULL;
5704 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005705}
5706
5707PyDoc_STRVAR(posix_makedev__doc__,
5708"makedev(major, minor) -> device number\n\
5709Composes a raw device number from the major and minor device numbers.");
5710
5711static PyObject *
5712posix_makedev(PyObject *self, PyObject *args)
5713{
Victor Stinner8c62be82010-05-06 00:08:46 +00005714 int major, minor;
5715 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5716 return NULL;
5717 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005718}
5719#endif /* device macros */
5720
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005721
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005722#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005723PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005724"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005725Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005726
Barry Warsaw53699e91996-12-10 23:23:01 +00005727static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005728posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005729{
Victor Stinner8c62be82010-05-06 00:08:46 +00005730 int fd;
5731 off_t length;
5732 int res;
5733 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005734
Victor Stinner8c62be82010-05-06 00:08:46 +00005735 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
5736 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005737
5738#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005739 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005740#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005741 length = PyLong_Check(lenobj) ?
5742 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005743#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005744 if (PyErr_Occurred())
5745 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005746
Victor Stinner8c62be82010-05-06 00:08:46 +00005747 Py_BEGIN_ALLOW_THREADS
5748 res = ftruncate(fd, length);
5749 Py_END_ALLOW_THREADS
5750 if (res < 0)
5751 return posix_error();
5752 Py_INCREF(Py_None);
5753 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005754}
5755#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005756
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005757#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005758PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005759"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005760Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005761
Fred Drake762e2061999-08-26 17:23:54 +00005762/* Save putenv() parameters as values here, so we can collect them when they
5763 * get re-set with another call for the same key. */
5764static PyObject *posix_putenv_garbage;
5765
Tim Peters5aa91602002-01-30 05:46:57 +00005766static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005767posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005768{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005769#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005770 wchar_t *s1, *s2;
5771 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005772#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005773 PyObject *os1, *os2;
5774 char *s1, *s2;
5775 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005776#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005777 PyObject *newstr = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005778 size_t len;
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 if (!PyArg_ParseTuple(args,
5782 "uu:putenv",
5783 &s1, &s2))
5784 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005785#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005786 if (!PyArg_ParseTuple(args,
5787 "O&O&:putenv",
5788 PyUnicode_FSConverter, &os1,
5789 PyUnicode_FSConverter, &os2))
5790 return NULL;
5791 s1 = PyBytes_AsString(os1);
5792 s2 = PyBytes_AsString(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005793#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005794
5795#if defined(PYOS_OS2)
5796 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5797 APIRET rc;
5798
Guido van Rossumd48f2521997-12-05 22:19:34 +00005799 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005800 if (rc != NO_ERROR) {
5801 os2_error(rc);
5802 goto error;
5803 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005804
5805 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5806 APIRET rc;
5807
Guido van Rossumd48f2521997-12-05 22:19:34 +00005808 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005809 if (rc != NO_ERROR) {
5810 os2_error(rc);
5811 goto error;
5812 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005813 } else {
5814#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005815 /* XXX This can leak memory -- not easy to fix :-( */
5816 /* len includes space for a trailing \0; the size arg to
5817 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005818#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005819 len = wcslen(s1) + wcslen(s2) + 2;
5820 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005821#else
Victor Stinner84ae1182010-05-06 22:05:07 +00005822 len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2;
Victor Stinner8c62be82010-05-06 00:08:46 +00005823 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005824#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005825 if (newstr == NULL) {
5826 PyErr_NoMemory();
5827 goto error;
5828 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005829#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005830 newenv = PyUnicode_AsUnicode(newstr);
5831 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5832 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005833 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00005834 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005835 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005836#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005837 newenv = PyBytes_AS_STRING(newstr);
5838 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5839 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005840 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00005841 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005842 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005843#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005844
Victor Stinner8c62be82010-05-06 00:08:46 +00005845 /* Install the first arg and newstr in posix_putenv_garbage;
5846 * this will cause previous value to be collected. This has to
5847 * happen after the real putenv() call because the old value
5848 * was still accessible until then. */
5849 if (PyDict_SetItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00005850#ifdef MS_WINDOWS
5851 PyTuple_GET_ITEM(args, 0),
5852#else
5853 os1,
5854#endif
5855 newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005856 /* really not much we can do; just leak */
5857 PyErr_Clear();
5858 }
5859 else {
5860 Py_DECREF(newstr);
5861 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005862
5863#if defined(PYOS_OS2)
5864 }
5865#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005866
Martin v. Löwis011e8422009-05-05 04:43:17 +00005867#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005868 Py_DECREF(os1);
5869 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005870#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005871 Py_RETURN_NONE;
5872
5873error:
5874#ifndef MS_WINDOWS
5875 Py_DECREF(os1);
5876 Py_DECREF(os2);
5877#endif
5878 Py_XDECREF(newstr);
5879 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005880}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005881#endif /* putenv */
5882
Guido van Rossumc524d952001-10-19 01:31:59 +00005883#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005884PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005885"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005886Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005887
5888static PyObject *
5889posix_unsetenv(PyObject *self, PyObject *args)
5890{
Victor Stinner84ae1182010-05-06 22:05:07 +00005891#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005892 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00005893
Victor Stinner8c62be82010-05-06 00:08:46 +00005894 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5895 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00005896#else
5897 PyObject *os1;
5898 char *s1;
5899
5900 if (!PyArg_ParseTuple(args, "O&:unsetenv",
5901 PyUnicode_FSConverter, &os1))
5902 return NULL;
5903 s1 = PyBytes_AsString(os1);
5904#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00005905
Victor Stinner8c62be82010-05-06 00:08:46 +00005906 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00005907
Victor Stinner8c62be82010-05-06 00:08:46 +00005908 /* Remove the key from posix_putenv_garbage;
5909 * this will cause it to be collected. This has to
5910 * happen after the real unsetenv() call because the
5911 * old value was still accessible until then.
5912 */
5913 if (PyDict_DelItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00005914#ifdef MS_WINDOWS
5915 PyTuple_GET_ITEM(args, 0)
5916#else
5917 os1
5918#endif
5919 )) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005920 /* really not much we can do; just leak */
5921 PyErr_Clear();
5922 }
Guido van Rossumc524d952001-10-19 01:31:59 +00005923
Victor Stinner84ae1182010-05-06 22:05:07 +00005924#ifndef MS_WINDOWS
5925 Py_DECREF(os1);
5926#endif
5927 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00005928}
5929#endif /* unsetenv */
5930
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005931PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005932"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005933Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005934
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005935static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005936posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005937{
Victor Stinner8c62be82010-05-06 00:08:46 +00005938 int code;
5939 char *message;
5940 if (!PyArg_ParseTuple(args, "i:strerror", &code))
5941 return NULL;
5942 message = strerror(code);
5943 if (message == NULL) {
5944 PyErr_SetString(PyExc_ValueError,
5945 "strerror() argument out of range");
5946 return NULL;
5947 }
5948 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00005949}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005950
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005951
Guido van Rossumc9641791998-08-04 15:26:23 +00005952#ifdef HAVE_SYS_WAIT_H
5953
Fred Drake106c1a02002-04-23 15:58:02 +00005954#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005955PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005956"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005957Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005958
5959static PyObject *
5960posix_WCOREDUMP(PyObject *self, PyObject *args)
5961{
Victor Stinner8c62be82010-05-06 00:08:46 +00005962 WAIT_TYPE status;
5963 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005964
Victor Stinner8c62be82010-05-06 00:08:46 +00005965 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
5966 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005967
Victor Stinner8c62be82010-05-06 00:08:46 +00005968 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005969}
5970#endif /* WCOREDUMP */
5971
5972#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005973PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005974"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005975Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005976job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005977
5978static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005979posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005980{
Victor Stinner8c62be82010-05-06 00:08:46 +00005981 WAIT_TYPE status;
5982 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005983
Victor Stinner8c62be82010-05-06 00:08:46 +00005984 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
5985 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005986
Victor Stinner8c62be82010-05-06 00:08:46 +00005987 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005988}
5989#endif /* WIFCONTINUED */
5990
Guido van Rossumc9641791998-08-04 15:26:23 +00005991#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005992PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005993"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005994Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005995
5996static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005997posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005998{
Victor Stinner8c62be82010-05-06 00:08:46 +00005999 WAIT_TYPE status;
6000 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006001
Victor Stinner8c62be82010-05-06 00:08:46 +00006002 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
6003 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006004
Victor Stinner8c62be82010-05-06 00:08:46 +00006005 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006006}
6007#endif /* WIFSTOPPED */
6008
6009#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006010PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006011"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006012Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006013
6014static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006015posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006016{
Victor Stinner8c62be82010-05-06 00:08:46 +00006017 WAIT_TYPE status;
6018 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006019
Victor Stinner8c62be82010-05-06 00:08:46 +00006020 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
6021 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006022
Victor Stinner8c62be82010-05-06 00:08:46 +00006023 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006024}
6025#endif /* WIFSIGNALED */
6026
6027#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006028PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006029"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006030Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006031system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006032
6033static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006034posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006035{
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 WAIT_TYPE status;
6037 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006038
Victor Stinner8c62be82010-05-06 00:08:46 +00006039 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
6040 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006041
Victor Stinner8c62be82010-05-06 00:08:46 +00006042 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006043}
6044#endif /* WIFEXITED */
6045
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006046#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006047PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006048"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006049Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006050
6051static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006052posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006053{
Victor Stinner8c62be82010-05-06 00:08:46 +00006054 WAIT_TYPE status;
6055 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006056
Victor Stinner8c62be82010-05-06 00:08:46 +00006057 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
6058 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006059
Victor Stinner8c62be82010-05-06 00:08:46 +00006060 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006061}
6062#endif /* WEXITSTATUS */
6063
6064#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006065PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006066"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006067Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006068value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006069
6070static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006071posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006072{
Victor Stinner8c62be82010-05-06 00:08:46 +00006073 WAIT_TYPE status;
6074 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006075
Victor Stinner8c62be82010-05-06 00:08:46 +00006076 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
6077 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006078
Victor Stinner8c62be82010-05-06 00:08:46 +00006079 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006080}
6081#endif /* WTERMSIG */
6082
6083#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006084PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006085"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006086Return the signal that stopped the process that provided\n\
6087the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006088
6089static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006090posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006091{
Victor Stinner8c62be82010-05-06 00:08:46 +00006092 WAIT_TYPE status;
6093 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006094
Victor Stinner8c62be82010-05-06 00:08:46 +00006095 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
6096 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006097
Victor Stinner8c62be82010-05-06 00:08:46 +00006098 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006099}
6100#endif /* WSTOPSIG */
6101
6102#endif /* HAVE_SYS_WAIT_H */
6103
6104
Thomas Wouters477c8d52006-05-27 19:21:47 +00006105#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006106#ifdef _SCO_DS
6107/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6108 needed definitions in sys/statvfs.h */
6109#define _SVID3
6110#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006111#include <sys/statvfs.h>
6112
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006113static PyObject*
6114_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006115 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6116 if (v == NULL)
6117 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006118
6119#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006120 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6121 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6122 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
6123 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
6124 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
6125 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
6126 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
6127 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
6128 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6129 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006130#else
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,
6134 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
6135 PyStructSequence_SET_ITEM(v, 3,
6136 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
6137 PyStructSequence_SET_ITEM(v, 4,
6138 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
6139 PyStructSequence_SET_ITEM(v, 5,
6140 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
6141 PyStructSequence_SET_ITEM(v, 6,
6142 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
6143 PyStructSequence_SET_ITEM(v, 7,
6144 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
6145 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6146 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006147#endif
6148
Victor Stinner8c62be82010-05-06 00:08:46 +00006149 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006150}
6151
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006152PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006153"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006154Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006155
6156static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006157posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006158{
Victor Stinner8c62be82010-05-06 00:08:46 +00006159 int fd, res;
6160 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006161
Victor Stinner8c62be82010-05-06 00:08:46 +00006162 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
6163 return NULL;
6164 Py_BEGIN_ALLOW_THREADS
6165 res = fstatvfs(fd, &st);
6166 Py_END_ALLOW_THREADS
6167 if (res != 0)
6168 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006169
Victor Stinner8c62be82010-05-06 00:08:46 +00006170 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006171}
Thomas Wouters477c8d52006-05-27 19:21:47 +00006172#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006173
6174
Thomas Wouters477c8d52006-05-27 19:21:47 +00006175#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006176#include <sys/statvfs.h>
6177
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006178PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006179"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006180Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006181
6182static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006183posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006184{
Victor Stinner8c62be82010-05-06 00:08:46 +00006185 char *path;
6186 int res;
6187 struct statvfs st;
6188 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
6189 return NULL;
6190 Py_BEGIN_ALLOW_THREADS
6191 res = statvfs(path, &st);
6192 Py_END_ALLOW_THREADS
6193 if (res != 0)
6194 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006195
Victor Stinner8c62be82010-05-06 00:08:46 +00006196 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006197}
6198#endif /* HAVE_STATVFS */
6199
Fred Drakec9680921999-12-13 16:37:25 +00006200/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6201 * It maps strings representing configuration variable names to
6202 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006203 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006204 * rarely-used constants. There are three separate tables that use
6205 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006206 *
6207 * This code is always included, even if none of the interfaces that
6208 * need it are included. The #if hackery needed to avoid it would be
6209 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006210 */
6211struct constdef {
6212 char *name;
6213 long value;
6214};
6215
Fred Drake12c6e2d1999-12-14 21:25:03 +00006216static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006217conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00006218 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006219{
Christian Heimes217cfd12007-12-02 14:31:20 +00006220 if (PyLong_Check(arg)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006221 *valuep = PyLong_AS_LONG(arg);
6222 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006223 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00006224 else {
Victor Stinner8c62be82010-05-06 00:08:46 +00006225 /* look up the value in the table using a binary search */
6226 size_t lo = 0;
6227 size_t mid;
6228 size_t hi = tablesize;
6229 int cmp;
6230 const char *confname;
6231 if (!PyUnicode_Check(arg)) {
6232 PyErr_SetString(PyExc_TypeError,
6233 "configuration names must be strings or integers");
Guido van Rossumbce56a62007-05-10 18:04:33 +00006234 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006235 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006236 confname = _PyUnicode_AsString(arg);
6237 if (confname == NULL)
6238 return 0;
6239 while (lo < hi) {
6240 mid = (lo + hi) / 2;
6241 cmp = strcmp(confname, table[mid].name);
6242 if (cmp < 0)
6243 hi = mid;
6244 else if (cmp > 0)
6245 lo = mid + 1;
6246 else {
6247 *valuep = table[mid].value;
6248 return 1;
6249 }
6250 }
6251 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6252 return 0;
6253 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00006254}
6255
6256
6257#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6258static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006259#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006260 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006261#endif
6262#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006263 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006264#endif
Fred Drakec9680921999-12-13 16:37:25 +00006265#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006266 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006267#endif
6268#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00006269 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00006270#endif
6271#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00006272 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00006273#endif
6274#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00006275 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00006276#endif
6277#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006278 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006279#endif
6280#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00006281 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00006282#endif
6283#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00006284 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00006285#endif
6286#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006287 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006288#endif
6289#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006290 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00006291#endif
6292#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006293 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006294#endif
6295#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006296 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00006297#endif
6298#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006299 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006300#endif
6301#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006302 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00006303#endif
6304#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006305 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006306#endif
6307#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00006308 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00006309#endif
6310};
6311
Fred Drakec9680921999-12-13 16:37:25 +00006312static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006313conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006314{
6315 return conv_confname(arg, valuep, posix_constants_pathconf,
6316 sizeof(posix_constants_pathconf)
6317 / sizeof(struct constdef));
6318}
6319#endif
6320
6321#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006322PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006323"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006324Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006325If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006326
6327static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006328posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006329{
6330 PyObject *result = NULL;
6331 int name, fd;
6332
Fred Drake12c6e2d1999-12-14 21:25:03 +00006333 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6334 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006335 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006336
Victor Stinner8c62be82010-05-06 00:08:46 +00006337 errno = 0;
6338 limit = fpathconf(fd, name);
6339 if (limit == -1 && errno != 0)
6340 posix_error();
6341 else
6342 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006343 }
6344 return result;
6345}
6346#endif
6347
6348
6349#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006350PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006351"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006352Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006353If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006354
6355static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006356posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006357{
6358 PyObject *result = NULL;
6359 int name;
6360 char *path;
6361
6362 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6363 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006364 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006365
Victor Stinner8c62be82010-05-06 00:08:46 +00006366 errno = 0;
6367 limit = pathconf(path, name);
6368 if (limit == -1 && errno != 0) {
6369 if (errno == EINVAL)
6370 /* could be a path or name problem */
6371 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00006372 else
Victor Stinner8c62be82010-05-06 00:08:46 +00006373 posix_error_with_filename(path);
6374 }
6375 else
6376 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006377 }
6378 return result;
6379}
6380#endif
6381
6382#ifdef HAVE_CONFSTR
6383static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006384#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00006385 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00006386#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00006387#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006388 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006389#endif
6390#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006391 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006392#endif
Fred Draked86ed291999-12-15 15:34:33 +00006393#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006394 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006395#endif
6396#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006397 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006398#endif
6399#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006400 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006401#endif
6402#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006403 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006404#endif
Fred Drakec9680921999-12-13 16:37:25 +00006405#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006406 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006407#endif
6408#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006409 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006410#endif
6411#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006412 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006413#endif
6414#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006415 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006416#endif
6417#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006418 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006419#endif
6420#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006421 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006422#endif
6423#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006424 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006425#endif
6426#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006427 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006428#endif
Fred Draked86ed291999-12-15 15:34:33 +00006429#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00006430 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00006431#endif
Fred Drakec9680921999-12-13 16:37:25 +00006432#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00006433 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00006434#endif
Fred Draked86ed291999-12-15 15:34:33 +00006435#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006436 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00006437#endif
6438#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006439 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00006440#endif
6441#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006442 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006443#endif
6444#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006445 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00006446#endif
Fred Drakec9680921999-12-13 16:37:25 +00006447#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006448 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006449#endif
6450#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006451 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006452#endif
6453#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006454 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006455#endif
6456#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006457 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006458#endif
6459#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006460 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006461#endif
6462#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006463 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006464#endif
6465#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006466 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006467#endif
6468#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006469 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006470#endif
6471#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006472 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006473#endif
6474#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006475 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006476#endif
6477#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006478 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006479#endif
6480#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006481 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006482#endif
6483#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006484 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006485#endif
6486#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006487 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006488#endif
6489#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006490 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006491#endif
6492#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006493 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006494#endif
Fred Draked86ed291999-12-15 15:34:33 +00006495#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006496 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006497#endif
6498#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006499 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00006500#endif
6501#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00006502 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00006503#endif
6504#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006505 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006506#endif
6507#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006508 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006509#endif
6510#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00006511 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00006512#endif
6513#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006514 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00006515#endif
6516#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00006517 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00006518#endif
6519#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006520 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006521#endif
6522#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006523 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006524#endif
6525#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006526 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006527#endif
6528#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006529 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006530#endif
6531#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00006532 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00006533#endif
Fred Drakec9680921999-12-13 16:37:25 +00006534};
6535
6536static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006537conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006538{
6539 return conv_confname(arg, valuep, posix_constants_confstr,
6540 sizeof(posix_constants_confstr)
6541 / sizeof(struct constdef));
6542}
6543
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006544PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006545"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006546Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006547
6548static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006549posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006550{
6551 PyObject *result = NULL;
6552 int name;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006553 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00006554
6555 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006556 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006557
Fred Drakec9680921999-12-13 16:37:25 +00006558 errno = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006559 len = confstr(name, buffer, sizeof(buffer));
6560 if (len == 0) {
6561 if (errno) {
6562 posix_error();
6563 }
6564 else {
6565 result = Py_None;
6566 Py_INCREF(Py_None);
6567 }
Fred Drakec9680921999-12-13 16:37:25 +00006568 }
6569 else {
Victor Stinner8c62be82010-05-06 00:08:46 +00006570 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz93c56822007-08-26 07:10:06 +00006571 result = PyUnicode_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006572 if (result != NULL)
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00006573 confstr(name, _PyUnicode_AsString(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00006574 }
6575 else
Neal Norwitz93c56822007-08-26 07:10:06 +00006576 result = PyUnicode_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006577 }
6578 }
6579 return result;
6580}
6581#endif
6582
6583
6584#ifdef HAVE_SYSCONF
6585static struct constdef posix_constants_sysconf[] = {
6586#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00006587 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00006588#endif
6589#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00006590 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00006591#endif
6592#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006593 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006594#endif
6595#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006596 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006597#endif
6598#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006599 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006600#endif
6601#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00006602 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00006603#endif
6604#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00006605 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00006606#endif
6607#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006608 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006609#endif
6610#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00006611 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00006612#endif
6613#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006614 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006615#endif
Fred Draked86ed291999-12-15 15:34:33 +00006616#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006617 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006618#endif
6619#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00006620 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00006621#endif
Fred Drakec9680921999-12-13 16:37:25 +00006622#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006623 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006624#endif
Fred Drakec9680921999-12-13 16:37:25 +00006625#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006626 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006627#endif
6628#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006629 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006630#endif
6631#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006632 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006633#endif
6634#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006635 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006636#endif
6637#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006638 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006639#endif
Fred Draked86ed291999-12-15 15:34:33 +00006640#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006641 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00006642#endif
Fred Drakec9680921999-12-13 16:37:25 +00006643#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00006644 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006645#endif
6646#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006647 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006648#endif
6649#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006650 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006651#endif
6652#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006653 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006654#endif
6655#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006656 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006657#endif
Fred Draked86ed291999-12-15 15:34:33 +00006658#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00006659 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00006660#endif
Fred Drakec9680921999-12-13 16:37:25 +00006661#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006662 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006663#endif
6664#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006665 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006666#endif
6667#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006668 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006669#endif
6670#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006671 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006672#endif
6673#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006674 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006675#endif
6676#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006677 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00006678#endif
6679#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006680 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006681#endif
6682#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006683 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006684#endif
6685#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006686 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006687#endif
6688#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006689 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006690#endif
6691#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006692 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006693#endif
6694#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006695 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006696#endif
6697#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006698 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006699#endif
6700#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006701 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006702#endif
6703#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006704 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006705#endif
6706#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006707 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006708#endif
6709#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006710 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00006711#endif
6712#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006713 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006714#endif
6715#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006716 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006717#endif
6718#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006719 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006720#endif
6721#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006722 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006723#endif
6724#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006725 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006726#endif
6727#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006728 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006729#endif
Fred Draked86ed291999-12-15 15:34:33 +00006730#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00006731 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00006732#endif
Fred Drakec9680921999-12-13 16:37:25 +00006733#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006734 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006735#endif
6736#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006737 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006738#endif
6739#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006740 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006741#endif
Fred Draked86ed291999-12-15 15:34:33 +00006742#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006743 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00006744#endif
Fred Drakec9680921999-12-13 16:37:25 +00006745#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00006746 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00006747#endif
Fred Draked86ed291999-12-15 15:34:33 +00006748#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00006749 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00006750#endif
6751#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00006752 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00006753#endif
Fred Drakec9680921999-12-13 16:37:25 +00006754#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006755 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006756#endif
6757#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006758 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006759#endif
6760#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006761 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006762#endif
6763#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006764 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006765#endif
Fred Draked86ed291999-12-15 15:34:33 +00006766#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00006767 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00006768#endif
Fred Drakec9680921999-12-13 16:37:25 +00006769#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00006770 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00006771#endif
6772#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00006773 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00006774#endif
6775#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006776 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006777#endif
6778#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006779 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00006780#endif
6781#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00006782 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00006783#endif
6784#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00006785 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00006786#endif
6787#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00006788 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00006789#endif
Fred Draked86ed291999-12-15 15:34:33 +00006790#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00006791 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00006792#endif
Fred Drakec9680921999-12-13 16:37:25 +00006793#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006794 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006795#endif
6796#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006797 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006798#endif
Fred Draked86ed291999-12-15 15:34:33 +00006799#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006801#endif
Fred Drakec9680921999-12-13 16:37:25 +00006802#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006803 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006804#endif
6805#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006806 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006807#endif
6808#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006809 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006810#endif
6811#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006812 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006813#endif
6814#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006815 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006816#endif
6817#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006818 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006819#endif
6820#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006821 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006822#endif
6823#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00006824 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00006825#endif
6826#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00006827 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00006828#endif
Fred Draked86ed291999-12-15 15:34:33 +00006829#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00006830 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00006831#endif
6832#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00006833 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00006834#endif
Fred Drakec9680921999-12-13 16:37:25 +00006835#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00006836 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00006837#endif
6838#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006839 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006840#endif
6841#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00006842 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006843#endif
6844#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00006845 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006846#endif
6847#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006848 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006849#endif
6850#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00006851 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006852#endif
6853#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00006854 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00006855#endif
6856#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00006857 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00006858#endif
6859#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00006860 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00006861#endif
6862#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00006863 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00006864#endif
6865#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00006866 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00006867#endif
6868#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006869 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00006870#endif
6871#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006872 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00006873#endif
6874#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00006875 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00006876#endif
6877#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00006878 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00006879#endif
6880#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00006881 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00006882#endif
6883#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00006884 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00006885#endif
6886#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006887 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006888#endif
6889#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00006890 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00006891#endif
6892#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00006893 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00006894#endif
6895#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006896 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006897#endif
6898#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006899 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006900#endif
6901#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00006902 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00006903#endif
6904#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006905 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006906#endif
6907#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006908 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006909#endif
6910#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00006911 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00006912#endif
6913#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00006914 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00006915#endif
6916#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006917 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006918#endif
6919#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006920 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006921#endif
6922#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006923 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00006924#endif
6925#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006926 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006927#endif
6928#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006929 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006930#endif
6931#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006932 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006933#endif
6934#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006935 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006936#endif
6937#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006938 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006939#endif
Fred Draked86ed291999-12-15 15:34:33 +00006940#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00006941 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00006942#endif
Fred Drakec9680921999-12-13 16:37:25 +00006943#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00006944 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00006945#endif
6946#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006947 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006948#endif
6949#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00006950 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00006951#endif
6952#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006953 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006954#endif
6955#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006956 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006957#endif
6958#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00006959 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00006960#endif
6961#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00006962 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00006963#endif
6964#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00006965 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006966#endif
6967#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00006968 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00006969#endif
6970#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006971 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006972#endif
6973#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00006974 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00006975#endif
6976#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006977 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00006978#endif
6979#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00006980 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00006981#endif
6982#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00006983 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00006984#endif
6985#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00006986 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00006987#endif
6988#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006989 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006990#endif
6991#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006992 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006993#endif
6994#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00006995 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00006996#endif
6997#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006998 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006999#endif
7000#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007001 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007002#endif
7003#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007004 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007005#endif
7006#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007007 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007008#endif
7009#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007010 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007011#endif
7012#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007013 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007014#endif
7015#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00007016 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00007017#endif
7018#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007019 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007020#endif
7021#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007022 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007023#endif
7024#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007025 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007026#endif
7027#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007028 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007029#endif
7030#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00007031 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00007032#endif
7033#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007034 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007035#endif
7036#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00007037 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00007038#endif
7039#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007040 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007041#endif
7042#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00007043 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00007044#endif
7045#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00007046 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00007047#endif
7048#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00007049 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00007050#endif
7051#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00007052 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00007053#endif
7054#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007055 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007056#endif
7057#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00007058 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00007059#endif
7060#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00007061 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00007062#endif
7063#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007064 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007065#endif
7066#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007067 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007068#endif
7069#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00007070 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00007071#endif
7072#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00007073 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00007074#endif
7075#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00007076 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00007077#endif
7078};
7079
7080static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007081conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007082{
7083 return conv_confname(arg, valuep, posix_constants_sysconf,
7084 sizeof(posix_constants_sysconf)
7085 / sizeof(struct constdef));
7086}
7087
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007088PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007089"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007090Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007091
7092static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007093posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007094{
7095 PyObject *result = NULL;
7096 int name;
7097
7098 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7099 int value;
7100
7101 errno = 0;
7102 value = sysconf(name);
7103 if (value == -1 && errno != 0)
7104 posix_error();
7105 else
Christian Heimes217cfd12007-12-02 14:31:20 +00007106 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00007107 }
7108 return result;
7109}
7110#endif
7111
7112
Fred Drakebec628d1999-12-15 18:31:10 +00007113/* This code is used to ensure that the tables of configuration value names
7114 * are in sorted order as required by conv_confname(), and also to build the
7115 * the exported dictionaries that are used to publish information about the
7116 * names available on the host platform.
7117 *
7118 * Sorting the table at runtime ensures that the table is properly ordered
7119 * when used, even for platforms we're not able to test on. It also makes
7120 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007121 */
Fred Drakebec628d1999-12-15 18:31:10 +00007122
7123static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007124cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007125{
7126 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007127 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00007128 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007129 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00007130
7131 return strcmp(c1->name, c2->name);
7132}
7133
7134static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007135setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00007136 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007137{
Fred Drakebec628d1999-12-15 18:31:10 +00007138 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007139 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007140
7141 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7142 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007143 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00007144 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007145
Barry Warsaw3155db32000-04-13 15:20:40 +00007146 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007147 PyObject *o = PyLong_FromLong(table[i].value);
7148 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7149 Py_XDECREF(o);
7150 Py_DECREF(d);
7151 return -1;
7152 }
7153 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007154 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007155 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007156}
7157
Fred Drakebec628d1999-12-15 18:31:10 +00007158/* Return -1 on failure, 0 on success. */
7159static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007160setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007161{
7162#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007163 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007164 sizeof(posix_constants_pathconf)
7165 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007166 "pathconf_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007167 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007168#endif
7169#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007170 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007171 sizeof(posix_constants_confstr)
7172 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007173 "confstr_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007174 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007175#endif
7176#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007177 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007178 sizeof(posix_constants_sysconf)
7179 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007180 "sysconf_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007181 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007182#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007183 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007184}
Fred Draked86ed291999-12-15 15:34:33 +00007185
7186
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007187PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007188"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007189Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007190in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007191
7192static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007193posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007194{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007195 abort();
7196 /*NOTREACHED*/
7197 Py_FatalError("abort() called from Python code didn't abort!");
7198 return NULL;
7199}
Fred Drakebec628d1999-12-15 18:31:10 +00007200
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007201#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007202PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007203"startfile(filepath [, operation]) - Start a file with its associated\n\
7204application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007205\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007206When \"operation\" is not specified or \"open\", this acts like\n\
7207double-clicking the file in Explorer, or giving the file name as an\n\
7208argument to the DOS \"start\" command: the file is opened with whatever\n\
7209application (if any) its extension is associated.\n\
7210When another \"operation\" is given, it specifies what should be done with\n\
7211the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007212\n\
7213startfile returns as soon as the associated application is launched.\n\
7214There is no option to wait for the application to close, and no way\n\
7215to retrieve the application's exit status.\n\
7216\n\
7217The filepath is relative to the current directory. If you want to use\n\
7218an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007219the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007220
7221static PyObject *
7222win32_startfile(PyObject *self, PyObject *args)
7223{
Victor Stinner8c62be82010-05-06 00:08:46 +00007224 PyObject *ofilepath;
7225 char *filepath;
7226 char *operation = NULL;
7227 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00007228
Victor Stinner8c62be82010-05-06 00:08:46 +00007229 PyObject *unipath, *woperation = NULL;
7230 if (!PyArg_ParseTuple(args, "U|s:startfile",
7231 &unipath, &operation)) {
7232 PyErr_Clear();
7233 goto normal;
7234 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007235
Victor Stinner8c62be82010-05-06 00:08:46 +00007236 if (operation) {
7237 woperation = PyUnicode_DecodeASCII(operation,
7238 strlen(operation), NULL);
7239 if (!woperation) {
7240 PyErr_Clear();
7241 operation = NULL;
7242 goto normal;
7243 }
7244 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007245
Victor Stinner8c62be82010-05-06 00:08:46 +00007246 Py_BEGIN_ALLOW_THREADS
7247 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
7248 PyUnicode_AS_UNICODE(unipath),
7249 NULL, NULL, SW_SHOWNORMAL);
7250 Py_END_ALLOW_THREADS
7251
7252 Py_XDECREF(woperation);
7253 if (rc <= (HINSTANCE)32) {
7254 PyObject *errval = win32_error_unicode("startfile",
7255 PyUnicode_AS_UNICODE(unipath));
7256 return errval;
7257 }
7258 Py_INCREF(Py_None);
7259 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007260
7261normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00007262 if (!PyArg_ParseTuple(args, "O&|s:startfile",
7263 PyUnicode_FSConverter, &ofilepath,
7264 &operation))
7265 return NULL;
7266 filepath = PyBytes_AsString(ofilepath);
7267 Py_BEGIN_ALLOW_THREADS
7268 rc = ShellExecute((HWND)0, operation, filepath,
7269 NULL, NULL, SW_SHOWNORMAL);
7270 Py_END_ALLOW_THREADS
7271 if (rc <= (HINSTANCE)32) {
7272 PyObject *errval = win32_error("startfile", filepath);
7273 Py_DECREF(ofilepath);
7274 return errval;
7275 }
7276 Py_DECREF(ofilepath);
7277 Py_INCREF(Py_None);
7278 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007279}
7280#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007281
Martin v. Löwis438b5342002-12-27 10:16:42 +00007282#ifdef HAVE_GETLOADAVG
7283PyDoc_STRVAR(posix_getloadavg__doc__,
7284"getloadavg() -> (float, float, float)\n\n\
7285Return the number of processes in the system run queue averaged over\n\
7286the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7287was unobtainable");
7288
7289static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007290posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007291{
7292 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007293 if (getloadavg(loadavg, 3)!=3) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007294 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7295 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00007296 } else
Victor Stinner8c62be82010-05-06 00:08:46 +00007297 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00007298}
7299#endif
7300
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007301#ifdef MS_WINDOWS
7302
7303PyDoc_STRVAR(win32_urandom__doc__,
7304"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007305Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007306
7307typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7308 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7309 DWORD dwFlags );
7310typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7311 BYTE *pbBuffer );
7312
7313static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00007314/* This handle is never explicitly released. Instead, the operating
7315 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007316static HCRYPTPROV hCryptProv = 0;
7317
Tim Peters4ad82172004-08-30 17:02:04 +00007318static PyObject*
7319win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007320{
Victor Stinner8c62be82010-05-06 00:08:46 +00007321 int howMany;
7322 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007323
Victor Stinner8c62be82010-05-06 00:08:46 +00007324 /* Read arguments */
7325 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7326 return NULL;
7327 if (howMany < 0)
7328 return PyErr_Format(PyExc_ValueError,
7329 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007330
Victor Stinner8c62be82010-05-06 00:08:46 +00007331 if (hCryptProv == 0) {
7332 HINSTANCE hAdvAPI32 = NULL;
7333 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007334
Victor Stinner8c62be82010-05-06 00:08:46 +00007335 /* Obtain handle to the DLL containing CryptoAPI
7336 This should not fail */
7337 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7338 if(hAdvAPI32 == NULL)
7339 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007340
Victor Stinner8c62be82010-05-06 00:08:46 +00007341 /* Obtain pointers to the CryptoAPI functions
7342 This will fail on some early versions of Win95 */
7343 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7344 hAdvAPI32,
7345 "CryptAcquireContextA");
7346 if (pCryptAcquireContext == NULL)
7347 return PyErr_Format(PyExc_NotImplementedError,
7348 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007349
Victor Stinner8c62be82010-05-06 00:08:46 +00007350 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7351 hAdvAPI32, "CryptGenRandom");
7352 if (pCryptGenRandom == NULL)
7353 return PyErr_Format(PyExc_NotImplementedError,
7354 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007355
Victor Stinner8c62be82010-05-06 00:08:46 +00007356 /* Acquire context */
7357 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7358 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7359 return win32_error("CryptAcquireContext", NULL);
7360 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007361
Victor Stinner8c62be82010-05-06 00:08:46 +00007362 /* Allocate bytes */
7363 result = PyBytes_FromStringAndSize(NULL, howMany);
7364 if (result != NULL) {
7365 /* Get random data */
7366 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
7367 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7368 PyBytes_AS_STRING(result))) {
7369 Py_DECREF(result);
7370 return win32_error("CryptGenRandom", NULL);
7371 }
7372 }
7373 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007374}
7375#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007376
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007377PyDoc_STRVAR(device_encoding__doc__,
7378"device_encoding(fd) -> str\n\n\
7379Return a string describing the encoding of the device\n\
7380if the output is a terminal; else return None.");
7381
7382static PyObject *
7383device_encoding(PyObject *self, PyObject *args)
7384{
Victor Stinner8c62be82010-05-06 00:08:46 +00007385 int fd;
7386 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
7387 return NULL;
7388 if (!_PyVerify_fd(fd) || !isatty(fd)) {
7389 Py_INCREF(Py_None);
7390 return Py_None;
7391 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007392#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner8c62be82010-05-06 00:08:46 +00007393 if (fd == 0) {
7394 char buf[100];
7395 sprintf(buf, "cp%d", GetConsoleCP());
7396 return PyUnicode_FromString(buf);
7397 }
7398 if (fd == 1 || fd == 2) {
7399 char buf[100];
7400 sprintf(buf, "cp%d", GetConsoleOutputCP());
7401 return PyUnicode_FromString(buf);
7402 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007403#elif defined(CODESET)
Victor Stinner8c62be82010-05-06 00:08:46 +00007404 {
7405 char *codeset = nl_langinfo(CODESET);
7406 if (codeset != NULL && codeset[0] != 0)
7407 return PyUnicode_FromString(codeset);
7408 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007409#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007410 Py_INCREF(Py_None);
7411 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007412}
7413
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007414#ifdef __VMS
7415/* Use openssl random routine */
7416#include <openssl/rand.h>
7417PyDoc_STRVAR(vms_urandom__doc__,
7418"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007419Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007420
7421static PyObject*
7422vms_urandom(PyObject *self, PyObject *args)
7423{
Victor Stinner8c62be82010-05-06 00:08:46 +00007424 int howMany;
7425 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007426
Victor Stinner8c62be82010-05-06 00:08:46 +00007427 /* Read arguments */
7428 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7429 return NULL;
7430 if (howMany < 0)
7431 return PyErr_Format(PyExc_ValueError,
7432 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007433
Victor Stinner8c62be82010-05-06 00:08:46 +00007434 /* Allocate bytes */
7435 result = PyBytes_FromStringAndSize(NULL, howMany);
7436 if (result != NULL) {
7437 /* Get random data */
7438 if (RAND_pseudo_bytes((unsigned char*)
7439 PyBytes_AS_STRING(result),
7440 howMany) < 0) {
7441 Py_DECREF(result);
7442 return PyErr_Format(PyExc_ValueError,
7443 "RAND_pseudo_bytes");
7444 }
7445 }
7446 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007447}
7448#endif
7449
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007450#ifdef HAVE_SETRESUID
7451PyDoc_STRVAR(posix_setresuid__doc__,
7452"setresuid(ruid, euid, suid)\n\n\
7453Set the current process's real, effective, and saved user ids.");
7454
7455static PyObject*
7456posix_setresuid (PyObject *self, PyObject *args)
7457{
Victor Stinner8c62be82010-05-06 00:08:46 +00007458 /* We assume uid_t is no larger than a long. */
7459 long ruid, euid, suid;
7460 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
7461 return NULL;
7462 if (setresuid(ruid, euid, suid) < 0)
7463 return posix_error();
7464 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007465}
7466#endif
7467
7468#ifdef HAVE_SETRESGID
7469PyDoc_STRVAR(posix_setresgid__doc__,
7470"setresgid(rgid, egid, sgid)\n\n\
7471Set the current process's real, effective, and saved group ids.");
7472
7473static PyObject*
7474posix_setresgid (PyObject *self, PyObject *args)
7475{
Victor Stinner8c62be82010-05-06 00:08:46 +00007476 /* We assume uid_t is no larger than a long. */
7477 long rgid, egid, sgid;
7478 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
7479 return NULL;
7480 if (setresgid(rgid, egid, sgid) < 0)
7481 return posix_error();
7482 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007483}
7484#endif
7485
7486#ifdef HAVE_GETRESUID
7487PyDoc_STRVAR(posix_getresuid__doc__,
7488"getresuid() -> (ruid, euid, suid)\n\n\
7489Get tuple of the current process's real, effective, and saved user ids.");
7490
7491static PyObject*
7492posix_getresuid (PyObject *self, PyObject *noargs)
7493{
Victor Stinner8c62be82010-05-06 00:08:46 +00007494 uid_t ruid, euid, suid;
7495 long l_ruid, l_euid, l_suid;
7496 if (getresuid(&ruid, &euid, &suid) < 0)
7497 return posix_error();
7498 /* Force the values into long's as we don't know the size of uid_t. */
7499 l_ruid = ruid;
7500 l_euid = euid;
7501 l_suid = suid;
7502 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007503}
7504#endif
7505
7506#ifdef HAVE_GETRESGID
7507PyDoc_STRVAR(posix_getresgid__doc__,
7508"getresgid() -> (rgid, egid, sgid)\n\n\
7509Get tuple of the current process's real, effective, and saved user ids.");
7510
7511static PyObject*
7512posix_getresgid (PyObject *self, PyObject *noargs)
7513{
Victor Stinner8c62be82010-05-06 00:08:46 +00007514 uid_t rgid, egid, sgid;
7515 long l_rgid, l_egid, l_sgid;
7516 if (getresgid(&rgid, &egid, &sgid) < 0)
7517 return posix_error();
7518 /* Force the values into long's as we don't know the size of uid_t. */
7519 l_rgid = rgid;
7520 l_egid = egid;
7521 l_sgid = sgid;
7522 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007523}
7524#endif
7525
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007526static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00007527 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007528#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007529 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007530#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007531 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007532#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007533 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007534#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007535 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007536#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007537 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007538#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007539#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007540 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007541#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00007542#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007543 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007544#endif /* HAVE_LCHMOD */
7545#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007546 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007547#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00007548#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007549 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007550#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007551#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007552 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007553#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007554#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +00007555 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00007556#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007557#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +00007558 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007559#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007560#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +00007561 {"getcwd", (PyCFunction)posix_getcwd_unicode,
7562 METH_NOARGS, posix_getcwd__doc__},
7563 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
7564 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007565#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007566#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007567 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007568#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +00007569 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7570 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7571 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007572#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +00007573 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007574#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007575#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007576 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007577#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007578#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7579 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
7580#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7581 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7582 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7583 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +00007584 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007585#ifdef HAVE_SYMLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007586 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007587#endif /* HAVE_SYMLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007588#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
7589 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS, win_symlink__doc__},
7590#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007591#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +00007592 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007593#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007594 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007595#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007596 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007597#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +00007598 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7599 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7600 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007601#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00007602 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007603#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00007604 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007605#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +00007606 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7607 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007608#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007609#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +00007610 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7611 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007612#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00007613 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7614 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007615#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007616#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007617#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +00007618 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007619#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007620#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +00007621 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007622#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007623#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +00007624 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007625#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007626#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007627 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007628#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007629#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007630 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007631#endif /* HAVE_GETEGID */
7632#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007633 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007634#endif /* HAVE_GETEUID */
7635#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007636 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007637#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007638#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007639 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007640#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007641 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007642#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007643 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007644#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007645#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +00007646 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007647#endif /* HAVE_GETPPID */
7648#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007649 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007650#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007651#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007652 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007653#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007654#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +00007655 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007656#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007657#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +00007658 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007659#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007660#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007661 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007662#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007663#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007664 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7665 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +00007666#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007667#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007668 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007669#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007670#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007671 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007672#endif /* HAVE_SETEUID */
7673#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007674 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007675#endif /* HAVE_SETEGID */
7676#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007677 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007678#endif /* HAVE_SETREUID */
7679#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007680 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007681#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007682#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007683 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007684#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007685#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007686 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007687#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +00007688#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007689 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +00007690#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007691#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007692 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00007693#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007694#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007695 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007696#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007697#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007698 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007699#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007700#ifdef HAVE_WAIT3
Victor Stinner8c62be82010-05-06 00:08:46 +00007701 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007702#endif /* HAVE_WAIT3 */
7703#ifdef HAVE_WAIT4
Victor Stinner8c62be82010-05-06 00:08:46 +00007704 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007705#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007706#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007707 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007708#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007709#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007710 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007711#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007712#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007713 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007714#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007715#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007716 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007717#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007718#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007719 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007720#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007721#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007722 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007723#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +00007724 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7725 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7726 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
7727 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
7728 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7729 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7730 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7731 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7732 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7733 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7734 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007735#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +00007736 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007737#endif
7738#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +00007739 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007740#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007741#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +00007742 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007743#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007744#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +00007745 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7746 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7747 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007748#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007749#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +00007750 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007751#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007752#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007753 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007754#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007755#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007756 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00007757#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007758 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007759#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +00007760 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007761#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007762#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007763 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007764#endif
7765#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007766 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007767#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007768#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007769#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +00007770 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00007771#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007772#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00007773 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007774#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007775#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +00007776 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007777#endif /* WIFSTOPPED */
7778#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +00007779 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007780#endif /* WIFSIGNALED */
7781#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +00007782 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007783#endif /* WIFEXITED */
7784#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +00007785 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007786#endif /* WEXITSTATUS */
7787#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007788 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007789#endif /* WTERMSIG */
7790#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007791 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007792#endif /* WSTOPSIG */
7793#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007794#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007795 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007796#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007797#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007798 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007799#endif
Fred Drakec9680921999-12-13 16:37:25 +00007800#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +00007801 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007802#endif
7803#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007804 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007805#endif
7806#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007807 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007808#endif
7809#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007810 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007811#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007812 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007813#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007814 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +00007815 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Mark Hammondef8b6542001-05-13 08:04:26 +00007816#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007817#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +00007818 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007819#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007820 #ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007821 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007822 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007823 #ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007824 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007825 #endif
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007826#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007827 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007828#endif
7829#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007830 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007831#endif
7832#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007833 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007834#endif
7835#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007836 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007837#endif
7838
Victor Stinner8c62be82010-05-06 00:08:46 +00007839 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007840};
7841
7842
Barry Warsaw4a342091996-12-19 23:50:02 +00007843static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007844ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007845{
Victor Stinner8c62be82010-05-06 00:08:46 +00007846 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007847}
7848
Guido van Rossumd48f2521997-12-05 22:19:34 +00007849#if defined(PYOS_OS2)
7850/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007851static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007852{
7853 APIRET rc;
7854 ULONG values[QSV_MAX+1];
7855 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007856 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007857
7858 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007859 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007860 Py_END_ALLOW_THREADS
7861
7862 if (rc != NO_ERROR) {
7863 os2_error(rc);
7864 return -1;
7865 }
7866
Fred Drake4d1e64b2002-04-15 19:40:07 +00007867 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7868 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7869 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7870 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7871 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7872 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7873 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007874
7875 switch (values[QSV_VERSION_MINOR]) {
7876 case 0: ver = "2.00"; break;
7877 case 10: ver = "2.10"; break;
7878 case 11: ver = "2.11"; break;
7879 case 30: ver = "3.00"; break;
7880 case 40: ver = "4.00"; break;
7881 case 50: ver = "5.00"; break;
7882 default:
Tim Peters885d4572001-11-28 20:27:42 +00007883 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +00007884 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00007885 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007886 ver = &tmp[0];
7887 }
7888
7889 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007890 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007891 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007892
7893 /* Add Indicator of Which Drive was Used to Boot the System */
7894 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7895 tmp[1] = ':';
7896 tmp[2] = '\0';
7897
Fred Drake4d1e64b2002-04-15 19:40:07 +00007898 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007899}
7900#endif
7901
Barry Warsaw4a342091996-12-19 23:50:02 +00007902static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007903all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007904{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007905#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00007906 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007907#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007908#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00007909 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007910#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007911#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00007912 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007913#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007914#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00007915 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007916#endif
Fred Drakec9680921999-12-13 16:37:25 +00007917#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007918 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00007919#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007920#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007921 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007922#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007923#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00007924 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00007925#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007926#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +00007927 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007928#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007929#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +00007930 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00007931#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007932#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00007933 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007934#endif
7935#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00007936 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007937#endif
7938#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +00007939 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007940#endif
7941#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +00007942 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007943#endif
7944#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007945 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007946#endif
7947#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +00007948 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007949#endif
7950#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007951 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007952#endif
7953#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007954 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007955#endif
7956#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007957 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007958#endif
7959#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007960 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007961#endif
7962#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00007963 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007964#endif
7965#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +00007966 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007967#endif
7968#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007969 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007970#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007971#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +00007972 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00007973#endif
7974#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +00007975 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00007976#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007977#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00007978 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007979#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007980#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007981 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00007982#endif
7983#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007984 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00007985#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007986
Tim Peters5aa91602002-01-30 05:46:57 +00007987/* MS Windows */
7988#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007989 /* Don't inherit in child processes. */
7990 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007991#endif
7992#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +00007993 /* Optimize for short life (keep in memory). */
7994 /* MS forgot to define this one with a non-underscore form too. */
7995 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007996#endif
7997#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +00007998 /* Automatically delete when last handle is closed. */
7999 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008000#endif
8001#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +00008002 /* Optimize for random access. */
8003 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008004#endif
8005#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008006 /* Optimize for sequential access. */
8007 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008008#endif
8009
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008010/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008011#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008012 /* Send a SIGIO signal whenever input or output
8013 becomes available on file descriptor */
8014 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008015#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008016#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008017 /* Direct disk access. */
8018 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008019#endif
8020#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +00008021 /* Must be a directory. */
8022 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008023#endif
8024#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +00008025 /* Do not follow links. */
8026 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008027#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008028#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +00008029 /* Do not update the access time. */
8030 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008031#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008032
Victor Stinner8c62be82010-05-06 00:08:46 +00008033 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008034#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008035 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008036#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008037#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008038 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008039#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008040#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008041 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008042#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008043#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008044 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008045#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008046#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +00008047 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008048#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008049#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +00008050 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008051#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008052#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008053 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008054#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008055#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +00008056 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008057#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008058#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008059 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008060#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008061#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008062 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008063#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008064#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008065 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008066#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008067#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008068 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008069#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008070#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +00008071 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008072#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008073#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +00008074 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008075#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008076#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008077 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008078#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008079#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008080 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008081#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008082#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +00008083 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008084#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008085
Guido van Rossum246bc171999-02-01 23:54:31 +00008086#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008087#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00008088 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8089 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8090 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8091 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8092 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8093 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8094 if (ins(d, "P_PM", (long)P_PM)) return -1;
8095 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8096 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8097 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8098 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8099 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8100 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8101 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8102 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8103 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8104 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8105 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8106 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8107 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008108#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008109 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8110 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8111 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8112 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8113 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008114#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008115#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008116
Guido van Rossumd48f2521997-12-05 22:19:34 +00008117#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00008118 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008119#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008120 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00008121}
8122
8123
Tim Peters5aa91602002-01-30 05:46:57 +00008124#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008125#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008126#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008127
8128#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008129#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008130#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008131
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008132#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00008133#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008134#define MODNAME "posix"
8135#endif
8136
Martin v. Löwis1a214512008-06-11 05:26:20 +00008137static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +00008138 PyModuleDef_HEAD_INIT,
8139 MODNAME,
8140 posix__doc__,
8141 -1,
8142 posix_methods,
8143 NULL,
8144 NULL,
8145 NULL,
8146 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00008147};
8148
8149
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008150PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008151INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008152{
Victor Stinner8c62be82010-05-06 00:08:46 +00008153 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008154
Victor Stinner8c62be82010-05-06 00:08:46 +00008155 m = PyModule_Create(&posixmodule);
8156 if (m == NULL)
8157 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008158
Victor Stinner8c62be82010-05-06 00:08:46 +00008159 /* Initialize environ dictionary */
8160 v = convertenviron();
8161 Py_XINCREF(v);
8162 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
8163 return NULL;
8164 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008165
Victor Stinner8c62be82010-05-06 00:08:46 +00008166 if (all_ins(m))
8167 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00008168
Victor Stinner8c62be82010-05-06 00:08:46 +00008169 if (setup_confname_tables(m))
8170 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00008171
Victor Stinner8c62be82010-05-06 00:08:46 +00008172 Py_INCREF(PyExc_OSError);
8173 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008174
Guido van Rossumb3d39562000-01-31 18:41:26 +00008175#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00008176 if (posix_putenv_garbage == NULL)
8177 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008178#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008179
Victor Stinner8c62be82010-05-06 00:08:46 +00008180 if (!initialized) {
8181 stat_result_desc.name = MODNAME ".stat_result";
8182 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8183 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8184 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8185 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8186 structseq_new = StatResultType.tp_new;
8187 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008188
Victor Stinner8c62be82010-05-06 00:08:46 +00008189 statvfs_result_desc.name = MODNAME ".statvfs_result";
8190 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008191#ifdef NEED_TICKS_PER_SECOND
8192# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +00008193 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008194# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +00008195 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008196# else
Victor Stinner8c62be82010-05-06 00:08:46 +00008197 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008198# endif
8199#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008200 }
8201 Py_INCREF((PyObject*) &StatResultType);
8202 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
8203 Py_INCREF((PyObject*) &StatVFSResultType);
8204 PyModule_AddObject(m, "statvfs_result",
8205 (PyObject*) &StatVFSResultType);
8206 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008207
8208#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +00008209 /*
8210 * Step 2 of weak-linking support on Mac OS X.
8211 *
8212 * The code below removes functions that are not available on the
8213 * currently active platform.
8214 *
8215 * This block allow one to use a python binary that was build on
8216 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8217 * OSX 10.4.
8218 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008219#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008220 if (fstatvfs == NULL) {
8221 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8222 return NULL;
8223 }
8224 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008225#endif /* HAVE_FSTATVFS */
8226
8227#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008228 if (statvfs == NULL) {
8229 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8230 return NULL;
8231 }
8232 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008233#endif /* HAVE_STATVFS */
8234
8235# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00008236 if (lchown == NULL) {
8237 if (PyObject_DelAttrString(m, "lchown") == -1) {
8238 return NULL;
8239 }
8240 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008241#endif /* HAVE_LCHOWN */
8242
8243
8244#endif /* __APPLE__ */
Victor Stinner8c62be82010-05-06 00:08:46 +00008245 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008246
Guido van Rossumb6775db1994-08-01 11:34:53 +00008247}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008248
8249#ifdef __cplusplus
8250}
8251#endif