blob: 702fec0cdf54ede3d0070ac495de5b80c34a34b4 [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
Thomas Wouters477c8d52006-05-27 19:21:47 +000014#ifdef __APPLE__
15 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000016 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000017 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
18 * at the end of this file for more information.
19 */
20# pragma weak lchown
21# pragma weak statvfs
22# pragma weak fstatvfs
23
24#endif /* __APPLE__ */
25
Thomas Wouters68bc4f92006-03-01 01:05:10 +000026#define PY_SSIZE_T_CLEAN
27
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000028#include "Python.h"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000029
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000030#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000031# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000032#endif /* defined(__VMS) */
33
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000034#ifdef __cplusplus
35extern "C" {
36#endif
37
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000038PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000039"This module provides access to operating system functionality that is\n\
40standardized by the C Standard and the POSIX standard (a thinly\n\
41disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000042corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000043
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000044
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000045#if defined(PYOS_OS2)
46#define INCL_DOS
47#define INCL_DOSERRORS
48#define INCL_DOSPROCESS
49#define INCL_NOPMAPI
50#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000051#if defined(PYCC_GCC)
52#include <ctype.h>
53#include <io.h>
54#include <stdio.h>
55#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000056#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000057#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000058#endif
59
Thomas Wouters0e3f5912006-08-11 14:57:12 +000060#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000061#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000062#endif /* HAVE_SYS_TYPES_H */
63
64#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000065#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000066#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000067
Guido van Rossum36bc6801995-06-14 22:54:23 +000068#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000069#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000070#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000071
Thomas Wouters0e3f5912006-08-11 14:57:12 +000072#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000073#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000074#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000075
Guido van Rossumb6775db1994-08-01 11:34:53 +000076#ifdef HAVE_FCNTL_H
77#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000078#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000079
Guido van Rossuma6535fd2001-10-18 19:44:10 +000080#ifdef HAVE_GRP_H
81#include <grp.h>
82#endif
83
Barry Warsaw5676bd12003-01-07 20:57:09 +000084#ifdef HAVE_SYSEXITS_H
85#include <sysexits.h>
86#endif /* HAVE_SYSEXITS_H */
87
Anthony Baxter8a560de2004-10-13 15:30:56 +000088#ifdef HAVE_SYS_LOADAVG_H
89#include <sys/loadavg.h>
90#endif
91
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000092#ifdef HAVE_LANGINFO_H
93#include <langinfo.h>
94#endif
95
Guido van Rossuma4916fa1996-05-23 22:58:55 +000096/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000097/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000098#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000099#include <process.h>
100#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000101#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000102#define HAVE_GETCWD 1
103#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000104#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000105#if defined(__OS2__)
106#define HAVE_EXECV 1
107#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000108#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000109#include <process.h>
110#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000111#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000112#define HAVE_EXECV 1
113#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000114#define HAVE_OPENDIR 1
115#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000116#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000117#define HAVE_WAIT 1
118#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000119#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000120#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000121#define HAVE_GETPPID 1
Victor Stinner26de69d2011-06-17 15:15:38 +0200122#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000123#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000124#define HAVE_EXECV 1
125#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000126#define HAVE_SYSTEM 1
127#define HAVE_CWAIT 1
128#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000129#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000130#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000131#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
132/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000133#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000134/* Unix functions that the configure script doesn't check for */
135#define HAVE_EXECV 1
136#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000137#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000138#define HAVE_FORK1 1
139#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000140#define HAVE_GETCWD 1
141#define HAVE_GETEGID 1
142#define HAVE_GETEUID 1
143#define HAVE_GETGID 1
144#define HAVE_GETPPID 1
145#define HAVE_GETUID 1
146#define HAVE_KILL 1
147#define HAVE_OPENDIR 1
148#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000149#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000150#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000151#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000152#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#endif /* _MSC_VER */
154#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000155#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000156#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000157
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000158#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000159
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000160#if defined(__sgi)&&_COMPILER_VERSION>=700
161/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
162 (default) */
163extern char *ctermid_r(char *);
164#endif
165
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000166#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000167#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000168extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000169#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000170#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000171extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000173extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000174#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000175#endif
176#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000177extern int chdir(char *);
178extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000179#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000180extern int chdir(const char *);
181extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000182#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000183#ifdef __BORLANDC__
184extern int chmod(const char *, int);
185#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000186extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000187#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000188/*#ifdef HAVE_FCHMOD
189extern int fchmod(int, mode_t);
190#endif*/
191/*#ifdef HAVE_LCHMOD
192extern int lchmod(const char *, mode_t);
193#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000194extern int chown(const char *, uid_t, gid_t);
195extern char *getcwd(char *, int);
196extern char *strerror(int);
197extern int link(const char *, const char *);
198extern int rename(const char *, const char *);
199extern int stat(const char *, struct stat *);
200extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000201#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000202extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000203#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000204#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000205extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000206#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000207#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000208
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000210
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#ifdef HAVE_UTIME_H
212#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000213#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000215#ifdef HAVE_SYS_UTIME_H
216#include <sys/utime.h>
217#define HAVE_UTIME_H /* pretend we do for the rest of this file */
218#endif /* HAVE_SYS_UTIME_H */
219
Guido van Rossumb6775db1994-08-01 11:34:53 +0000220#ifdef HAVE_SYS_TIMES_H
221#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000222#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000223
224#ifdef HAVE_SYS_PARAM_H
225#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000226#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000227
228#ifdef HAVE_SYS_UTSNAME_H
229#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000230#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000231
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000232#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000233#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000234#define NAMLEN(dirent) strlen((dirent)->d_name)
235#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000236#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000237#include <direct.h>
238#define NAMLEN(dirent) strlen((dirent)->d_name)
239#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000240#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000241#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000242#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000243#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000245#endif
246#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000248#endif
249#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000250#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000251#endif
252#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000253
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000254#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000255#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000257#endif
258#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000259#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000260#endif
261#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000263#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000264#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000265#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000266#endif
267#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000268#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000269#endif
270#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000271#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000272#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000273#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000274#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000275#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000276#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000277#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000278#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
279#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000280static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000281#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000282#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000283
Guido van Rossumd48f2521997-12-05 22:19:34 +0000284#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000285#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000286#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000287
Tim Petersbc2e10e2002-03-03 23:17:02 +0000288#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000289#if defined(PATH_MAX) && PATH_MAX > 1024
290#define MAXPATHLEN PATH_MAX
291#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000292#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000293#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000294#endif /* MAXPATHLEN */
295
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000296#ifdef UNION_WAIT
297/* Emulate some macros on systems that have a union instead of macros */
298
299#ifndef WIFEXITED
300#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
301#endif
302
303#ifndef WEXITSTATUS
304#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
305#endif
306
307#ifndef WTERMSIG
308#define WTERMSIG(u_wait) ((u_wait).w_termsig)
309#endif
310
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000311#define WAIT_TYPE union wait
312#define WAIT_STATUS_INT(s) (s.w_status)
313
314#else /* !UNION_WAIT */
315#define WAIT_TYPE int
316#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000317#endif /* UNION_WAIT */
318
Greg Wardb48bc172000-03-01 21:51:56 +0000319/* Don't use the "_r" form if we don't need it (also, won't have a
320 prototype for it, at least on Solaris -- maybe others as well?). */
321#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
322#define USE_CTERMID_R
323#endif
324
Fred Drake699f3522000-06-29 21:12:41 +0000325/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000326#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000327#undef FSTAT
328#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000329#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000330# define STAT win32_stat
331# define FSTAT win32_fstat
332# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000333#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000334# define STAT stat
335# define FSTAT fstat
336# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000337#endif
338
Tim Peters11b23062003-04-23 02:39:17 +0000339#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000340#include <sys/mkdev.h>
341#else
342#if defined(MAJOR_IN_SYSMACROS)
343#include <sys/sysmacros.h>
344#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000345#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
346#include <sys/mkdev.h>
347#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000348#endif
Fred Drake699f3522000-06-29 21:12:41 +0000349
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000350#if defined _MSC_VER && _MSC_VER >= 1400
351/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
352 * valid and throw an assertion if it isn't.
353 * Normally, an invalid fd is likely to be a C program error and therefore
354 * an assertion can be useful, but it does contradict the POSIX standard
355 * which for write(2) states:
356 * "Otherwise, -1 shall be returned and errno set to indicate the error."
357 * "[EBADF] The fildes argument is not a valid file descriptor open for
358 * writing."
359 * Furthermore, python allows the user to enter any old integer
360 * as a fd and should merely raise a python exception on error.
361 * The Microsoft CRT doesn't provide an official way to check for the
362 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000363 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000364 * internal structures involved.
365 * The structures below must be updated for each version of visual studio
366 * according to the file internal.h in the CRT source, until MS comes
367 * up with a less hacky way to do this.
368 * (all of this is to avoid globally modifying the CRT behaviour using
369 * _set_invalid_parameter_handler() and _CrtSetReportMode())
370 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000371/* The actual size of the structure is determined at runtime.
372 * Only the first items must be present.
373 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000374typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000375 intptr_t osfhnd;
376 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000377} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000378
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000379extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000380#define IOINFO_L2E 5
381#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
382#define IOINFO_ARRAYS 64
383#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
384#define FOPEN 0x01
385#define _NO_CONSOLE_FILENO (intptr_t)-2
386
387/* This function emulates what the windows CRT does to validate file handles */
388int
389_PyVerify_fd(int fd)
390{
Victor Stinner8c62be82010-05-06 00:08:46 +0000391 const int i1 = fd >> IOINFO_L2E;
392 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000393
Antoine Pitrou22e41552010-08-15 18:07:50 +0000394 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000395
Victor Stinner8c62be82010-05-06 00:08:46 +0000396 /* Determine the actual size of the ioinfo structure,
397 * as used by the CRT loaded in memory
398 */
399 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
400 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
401 }
402 if (sizeof_ioinfo == 0) {
403 /* This should not happen... */
404 goto fail;
405 }
406
407 /* See that it isn't a special CLEAR fileno */
408 if (fd != _NO_CONSOLE_FILENO) {
409 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
410 * we check pointer validity and other info
411 */
412 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
413 /* finally, check that the file is open */
414 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
415 if (info->osfile & FOPEN) {
416 return 1;
417 }
418 }
419 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000420 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000421 errno = EBADF;
422 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000423}
424
425/* the special case of checking dup2. The target fd must be in a sensible range */
426static int
427_PyVerify_fd_dup2(int fd1, int fd2)
428{
Victor Stinner8c62be82010-05-06 00:08:46 +0000429 if (!_PyVerify_fd(fd1))
430 return 0;
431 if (fd2 == _NO_CONSOLE_FILENO)
432 return 0;
433 if ((unsigned)fd2 < _NHANDLE_)
434 return 1;
435 else
436 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000437}
438#else
439/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
440#define _PyVerify_fd_dup2(A, B) (1)
441#endif
442
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000443#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000444/* The following structure was copied from
445 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
446 include doesn't seem to be present in the Windows SDK (at least as included
447 with Visual Studio Express). */
448typedef struct _REPARSE_DATA_BUFFER {
449 ULONG ReparseTag;
450 USHORT ReparseDataLength;
451 USHORT Reserved;
452 union {
453 struct {
454 USHORT SubstituteNameOffset;
455 USHORT SubstituteNameLength;
456 USHORT PrintNameOffset;
457 USHORT PrintNameLength;
458 ULONG Flags;
459 WCHAR PathBuffer[1];
460 } SymbolicLinkReparseBuffer;
461
462 struct {
463 USHORT SubstituteNameOffset;
464 USHORT SubstituteNameLength;
465 USHORT PrintNameOffset;
466 USHORT PrintNameLength;
467 WCHAR PathBuffer[1];
468 } MountPointReparseBuffer;
469
470 struct {
471 UCHAR DataBuffer[1];
472 } GenericReparseBuffer;
473 };
474} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
475
476#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
477 GenericReparseBuffer)
478#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
479
480static int
Brian Curtind25aef52011-06-13 15:16:04 -0500481win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +0000482{
483 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
484 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
485 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000486
487 if (0 == DeviceIoControl(
488 reparse_point_handle,
489 FSCTL_GET_REPARSE_POINT,
490 NULL, 0, /* in buffer */
491 target_buffer, sizeof(target_buffer),
492 &n_bytes_returned,
493 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -0500494 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000495
496 if (reparse_tag)
497 *reparse_tag = rdb->ReparseTag;
498
Brian Curtind25aef52011-06-13 15:16:04 -0500499 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000500}
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000501#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000502
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000503/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000504#ifdef WITH_NEXT_FRAMEWORK
505/* On Darwin/MacOSX a shared library or framework has no access to
506** environ directly, we must obtain it with _NSGetEnviron().
507*/
508#include <crt_externs.h>
509static char **environ;
510#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000511extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000512#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000513
Barry Warsaw53699e91996-12-10 23:23:01 +0000514static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000515convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000516{
Victor Stinner8c62be82010-05-06 00:08:46 +0000517 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000518#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000519 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000520#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000521 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000522#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000523#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000524 APIRET rc;
525 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
526#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000527
Victor Stinner8c62be82010-05-06 00:08:46 +0000528 d = PyDict_New();
529 if (d == NULL)
530 return NULL;
531#ifdef WITH_NEXT_FRAMEWORK
532 if (environ == NULL)
533 environ = *_NSGetEnviron();
534#endif
535#ifdef MS_WINDOWS
536 /* _wenviron must be initialized in this way if the program is started
537 through main() instead of wmain(). */
538 _wgetenv(L"");
539 if (_wenviron == NULL)
540 return d;
541 /* This part ignores errors */
542 for (e = _wenviron; *e != NULL; e++) {
543 PyObject *k;
544 PyObject *v;
545 wchar_t *p = wcschr(*e, L'=');
546 if (p == NULL)
547 continue;
548 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
549 if (k == NULL) {
550 PyErr_Clear();
551 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000552 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000553 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
554 if (v == NULL) {
555 PyErr_Clear();
556 Py_DECREF(k);
557 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000558 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000559 if (PyDict_GetItem(d, k) == NULL) {
560 if (PyDict_SetItem(d, k, v) != 0)
561 PyErr_Clear();
562 }
563 Py_DECREF(k);
564 Py_DECREF(v);
565 }
566#else
567 if (environ == NULL)
568 return d;
569 /* This part ignores errors */
570 for (e = environ; *e != NULL; e++) {
571 PyObject *k;
572 PyObject *v;
573 char *p = strchr(*e, '=');
574 if (p == NULL)
575 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000576 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000577 if (k == NULL) {
578 PyErr_Clear();
579 continue;
580 }
Victor Stinner84ae1182010-05-06 22:05:07 +0000581 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +0000582 if (v == NULL) {
583 PyErr_Clear();
584 Py_DECREF(k);
585 continue;
586 }
587 if (PyDict_GetItem(d, k) == NULL) {
588 if (PyDict_SetItem(d, k, v) != 0)
589 PyErr_Clear();
590 }
591 Py_DECREF(k);
592 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000593 }
594#endif
Victor Stinner8c62be82010-05-06 00:08:46 +0000595#if defined(PYOS_OS2)
596 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
597 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
598 PyObject *v = PyBytes_FromString(buffer);
599 PyDict_SetItemString(d, "BEGINLIBPATH", v);
600 Py_DECREF(v);
601 }
602 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
603 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
604 PyObject *v = PyBytes_FromString(buffer);
605 PyDict_SetItemString(d, "ENDLIBPATH", v);
606 Py_DECREF(v);
607 }
608#endif
609 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000610}
611
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000612/* Set a POSIX-specific error from errno, and return NULL */
613
Barry Warsawd58d7641998-07-23 16:14:40 +0000614static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000615posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000616{
Victor Stinner8c62be82010-05-06 00:08:46 +0000617 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000618}
Barry Warsawd58d7641998-07-23 16:14:40 +0000619static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000620posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000621{
Victor Stinner8c62be82010-05-06 00:08:46 +0000622 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000623}
624
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000625
Mark Hammondef8b6542001-05-13 08:04:26 +0000626static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000627posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000628{
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000629 PyObject *name_str, *rc;
630 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
631 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +0000632 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000633 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
634 name_str);
635 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +0000636 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000637}
638
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000639#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000640static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +0000641win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000642{
Victor Stinner8c62be82010-05-06 00:08:46 +0000643 /* XXX We should pass the function name along in the future.
644 (winreg.c also wants to pass the function name.)
645 This would however require an additional param to the
646 Windows error object, which is non-trivial.
647 */
648 errno = GetLastError();
649 if (filename)
650 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
651 else
652 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000653}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000654
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000655static PyObject *
656win32_error_unicode(char* function, Py_UNICODE* filename)
657{
Victor Stinner8c62be82010-05-06 00:08:46 +0000658 /* XXX - see win32_error for comments on 'function' */
659 errno = GetLastError();
660 if (filename)
661 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
662 else
663 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000664}
665
Thomas Wouters477c8d52006-05-27 19:21:47 +0000666static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000667convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000668{
Victor Stinner8c62be82010-05-06 00:08:46 +0000669 if (PyUnicode_CheckExact(*param))
670 Py_INCREF(*param);
671 else if (PyUnicode_Check(*param))
672 /* For a Unicode subtype that's not a Unicode object,
673 return a true Unicode object with the same data. */
674 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
675 PyUnicode_GET_SIZE(*param));
676 else
677 *param = PyUnicode_FromEncodedObject(*param,
678 Py_FileSystemDefaultEncoding,
679 "strict");
680 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000681}
682
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000683#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000684
Guido van Rossumd48f2521997-12-05 22:19:34 +0000685#if defined(PYOS_OS2)
686/**********************************************************************
687 * Helper Function to Trim and Format OS/2 Messages
688 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000689static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000690os2_formatmsg(char *msgbuf, int msglen, char *reason)
691{
692 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
693
694 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
695 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
696
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000697 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000698 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
699 }
700
701 /* Add Optional Reason Text */
702 if (reason) {
703 strcat(msgbuf, " : ");
704 strcat(msgbuf, reason);
705 }
706}
707
708/**********************************************************************
709 * Decode an OS/2 Operating System Error Code
710 *
711 * A convenience function to lookup an OS/2 error code and return a
712 * text message we can use to raise a Python exception.
713 *
714 * Notes:
715 * The messages for errors returned from the OS/2 kernel reside in
716 * the file OSO001.MSG in the \OS2 directory hierarchy.
717 *
718 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000719static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000720os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
721{
722 APIRET rc;
723 ULONG msglen;
724
725 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
726 Py_BEGIN_ALLOW_THREADS
727 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
728 errorcode, "oso001.msg", &msglen);
729 Py_END_ALLOW_THREADS
730
731 if (rc == NO_ERROR)
732 os2_formatmsg(msgbuf, msglen, reason);
733 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000734 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +0000735 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000736
737 return msgbuf;
738}
739
740/* Set an OS/2-specific error and return NULL. OS/2 kernel
741 errors are not in a global variable e.g. 'errno' nor are
742 they congruent with posix error numbers. */
743
Victor Stinner8c62be82010-05-06 00:08:46 +0000744static PyObject *
745os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000746{
747 char text[1024];
748 PyObject *v;
749
750 os2_strerror(text, sizeof(text), code, "");
751
752 v = Py_BuildValue("(is)", code, text);
753 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000754 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000755 Py_DECREF(v);
756 }
757 return NULL; /* Signal to Python that an Exception is Pending */
758}
759
760#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000761
762/* POSIX generic methods */
763
Barry Warsaw53699e91996-12-10 23:23:01 +0000764static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000765posix_fildes(PyObject *fdobj, int (*func)(int))
766{
Victor Stinner8c62be82010-05-06 00:08:46 +0000767 int fd;
768 int res;
769 fd = PyObject_AsFileDescriptor(fdobj);
770 if (fd < 0)
771 return NULL;
772 if (!_PyVerify_fd(fd))
773 return posix_error();
774 Py_BEGIN_ALLOW_THREADS
775 res = (*func)(fd);
776 Py_END_ALLOW_THREADS
777 if (res < 0)
778 return posix_error();
779 Py_INCREF(Py_None);
780 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000781}
Guido van Rossum21142a01999-01-08 21:05:37 +0000782
783static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000784posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000785{
Victor Stinner8c62be82010-05-06 00:08:46 +0000786 PyObject *opath1 = NULL;
787 char *path1;
788 int res;
789 if (!PyArg_ParseTuple(args, format,
790 PyUnicode_FSConverter, &opath1))
791 return NULL;
792 path1 = PyBytes_AsString(opath1);
793 Py_BEGIN_ALLOW_THREADS
794 res = (*func)(path1);
795 Py_END_ALLOW_THREADS
796 if (res < 0)
797 return posix_error_with_allocated_filename(opath1);
798 Py_DECREF(opath1);
799 Py_INCREF(Py_None);
800 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000801}
802
Barry Warsaw53699e91996-12-10 23:23:01 +0000803static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000804posix_2str(PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +0000805 char *format,
806 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000807{
Victor Stinner8c62be82010-05-06 00:08:46 +0000808 PyObject *opath1 = NULL, *opath2 = NULL;
809 char *path1, *path2;
810 int res;
811 if (!PyArg_ParseTuple(args, format,
812 PyUnicode_FSConverter, &opath1,
813 PyUnicode_FSConverter, &opath2)) {
814 return NULL;
815 }
816 path1 = PyBytes_AsString(opath1);
817 path2 = PyBytes_AsString(opath2);
818 Py_BEGIN_ALLOW_THREADS
819 res = (*func)(path1, path2);
820 Py_END_ALLOW_THREADS
821 Py_DECREF(opath1);
822 Py_DECREF(opath2);
823 if (res != 0)
824 /* XXX how to report both path1 and path2??? */
825 return posix_error();
826 Py_INCREF(Py_None);
827 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000828}
829
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000830#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000831static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +0000832win32_1str(PyObject* args, char* func,
833 char* format, BOOL (__stdcall *funcA)(LPCSTR),
834 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000835{
Victor Stinner8c62be82010-05-06 00:08:46 +0000836 PyObject *uni;
837 char *ansi;
838 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +0000839
Victor Stinner8c62be82010-05-06 00:08:46 +0000840 if (!PyArg_ParseTuple(args, wformat, &uni))
841 PyErr_Clear();
842 else {
843 Py_BEGIN_ALLOW_THREADS
844 result = funcW(PyUnicode_AsUnicode(uni));
845 Py_END_ALLOW_THREADS
846 if (!result)
847 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
848 Py_INCREF(Py_None);
849 return Py_None;
850 }
851 if (!PyArg_ParseTuple(args, format, &ansi))
852 return NULL;
853 Py_BEGIN_ALLOW_THREADS
854 result = funcA(ansi);
855 Py_END_ALLOW_THREADS
856 if (!result)
857 return win32_error(func, ansi);
858 Py_INCREF(Py_None);
859 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000860
861}
862
863/* This is a reimplementation of the C library's chdir function,
864 but one that produces Win32 errors instead of DOS error codes.
865 chdir is essentially a wrapper around SetCurrentDirectory; however,
866 it also needs to set "magic" environment variables indicating
867 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000868static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000869win32_chdir(LPCSTR path)
870{
Victor Stinner8c62be82010-05-06 00:08:46 +0000871 char new_path[MAX_PATH+1];
872 int result;
873 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000874
Victor Stinner8c62be82010-05-06 00:08:46 +0000875 if(!SetCurrentDirectoryA(path))
876 return FALSE;
877 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
878 if (!result)
879 return FALSE;
880 /* In the ANSI API, there should not be any paths longer
881 than MAX_PATH. */
882 assert(result <= MAX_PATH+1);
883 if (strncmp(new_path, "\\\\", 2) == 0 ||
884 strncmp(new_path, "//", 2) == 0)
885 /* UNC path, nothing to do. */
886 return TRUE;
887 env[1] = new_path[0];
888 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000889}
890
891/* The Unicode version differs from the ANSI version
892 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000893static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000894win32_wchdir(LPCWSTR path)
895{
Victor Stinner8c62be82010-05-06 00:08:46 +0000896 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
897 int result;
898 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000899
Victor Stinner8c62be82010-05-06 00:08:46 +0000900 if(!SetCurrentDirectoryW(path))
901 return FALSE;
902 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
903 if (!result)
904 return FALSE;
905 if (result > MAX_PATH+1) {
906 new_path = malloc(result * sizeof(wchar_t));
907 if (!new_path) {
908 SetLastError(ERROR_OUTOFMEMORY);
909 return FALSE;
910 }
911 result = GetCurrentDirectoryW(result, new_path);
912 if (!result) {
913 free(new_path);
914 return FALSE;
915 }
916 }
917 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
918 wcsncmp(new_path, L"//", 2) == 0)
919 /* UNC path, nothing to do. */
920 return TRUE;
921 env[1] = new_path[0];
922 result = SetEnvironmentVariableW(env, new_path);
923 if (new_path != _new_path)
924 free(new_path);
925 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000926}
927#endif
928
Martin v. Löwis14694662006-02-03 12:54:16 +0000929#ifdef MS_WINDOWS
930/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
931 - time stamps are restricted to second resolution
932 - file modification times suffer from forth-and-back conversions between
933 UTC and local time
934 Therefore, we implement our own stat, based on the Win32 API directly.
935*/
Victor Stinner8c62be82010-05-06 00:08:46 +0000936#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +0000937
938struct win32_stat{
939 int st_dev;
940 __int64 st_ino;
941 unsigned short st_mode;
942 int st_nlink;
943 int st_uid;
944 int st_gid;
945 int st_rdev;
946 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +0000947 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000948 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +0000949 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000950 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +0000951 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000952 int st_ctime_nsec;
953};
954
955static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
956
957static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +0000958FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +0000959{
Victor Stinner8c62be82010-05-06 00:08:46 +0000960 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
961 /* Cannot simply cast and dereference in_ptr,
962 since it might not be aligned properly */
963 __int64 in;
964 memcpy(&in, in_ptr, sizeof(in));
965 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +0000966 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +0000967}
968
Thomas Wouters477c8d52006-05-27 19:21:47 +0000969static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +0000970time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000971{
Victor Stinner8c62be82010-05-06 00:08:46 +0000972 /* XXX endianness */
973 __int64 out;
974 out = time_in + secs_between_epochs;
975 out = out * 10000000 + nsec_in / 100;
976 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000977}
978
Martin v. Löwis14694662006-02-03 12:54:16 +0000979/* Below, we *know* that ugo+r is 0444 */
980#if _S_IREAD != 0400
981#error Unsupported C library
982#endif
983static int
984attributes_to_mode(DWORD attr)
985{
Victor Stinner8c62be82010-05-06 00:08:46 +0000986 int m = 0;
987 if (attr & FILE_ATTRIBUTE_DIRECTORY)
988 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
989 else
990 m |= _S_IFREG;
991 if (attr & FILE_ATTRIBUTE_READONLY)
992 m |= 0444;
993 else
994 m |= 0666;
995 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +0000996}
997
998static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +0000999attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001000{
Victor Stinner8c62be82010-05-06 00:08:46 +00001001 memset(result, 0, sizeof(*result));
1002 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1003 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1004 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1005 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1006 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001007 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001008 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001009 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1010 /* first clear the S_IFMT bits */
1011 result->st_mode ^= (result->st_mode & 0170000);
1012 /* now set the bits that make this a symlink */
1013 result->st_mode |= 0120000;
1014 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001015
Victor Stinner8c62be82010-05-06 00:08:46 +00001016 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001017}
1018
Guido van Rossumd8faa362007-04-27 19:54:29 +00001019static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001020attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001021{
Victor Stinner8c62be82010-05-06 00:08:46 +00001022 HANDLE hFindFile;
1023 WIN32_FIND_DATAA FileData;
1024 hFindFile = FindFirstFileA(pszFile, &FileData);
1025 if (hFindFile == INVALID_HANDLE_VALUE)
1026 return FALSE;
1027 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001028 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001029 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001030 info->dwFileAttributes = FileData.dwFileAttributes;
1031 info->ftCreationTime = FileData.ftCreationTime;
1032 info->ftLastAccessTime = FileData.ftLastAccessTime;
1033 info->ftLastWriteTime = FileData.ftLastWriteTime;
1034 info->nFileSizeHigh = FileData.nFileSizeHigh;
1035 info->nFileSizeLow = FileData.nFileSizeLow;
1036/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001037 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1038 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001039 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001040}
1041
1042static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001043attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001044{
Victor Stinner8c62be82010-05-06 00:08:46 +00001045 HANDLE hFindFile;
1046 WIN32_FIND_DATAW FileData;
1047 hFindFile = FindFirstFileW(pszFile, &FileData);
1048 if (hFindFile == INVALID_HANDLE_VALUE)
1049 return FALSE;
1050 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001051 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001052 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001053 info->dwFileAttributes = FileData.dwFileAttributes;
1054 info->ftCreationTime = FileData.ftCreationTime;
1055 info->ftLastAccessTime = FileData.ftLastAccessTime;
1056 info->ftLastWriteTime = FileData.ftLastWriteTime;
1057 info->nFileSizeHigh = FileData.nFileSizeHigh;
1058 info->nFileSizeLow = FileData.nFileSizeLow;
1059/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001060 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1061 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001062 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001063}
1064
Brian Curtind25aef52011-06-13 15:16:04 -05001065/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1066static int has_GetFinalPathNameByHandle = 0;
1067static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1068 DWORD);
1069static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1070 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001071static int
Brian Curtind25aef52011-06-13 15:16:04 -05001072check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001073{
Brian Curtind25aef52011-06-13 15:16:04 -05001074 HINSTANCE hKernel32;
1075 /* only recheck */
1076 if (!has_GetFinalPathNameByHandle)
1077 {
1078 hKernel32 = GetModuleHandle("KERNEL32");
1079 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1080 "GetFinalPathNameByHandleA");
1081 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1082 "GetFinalPathNameByHandleW");
1083 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1084 Py_GetFinalPathNameByHandleW;
1085 }
1086 return has_GetFinalPathNameByHandle;
1087}
1088
1089static BOOL
1090get_target_path(HANDLE hdl, wchar_t **target_path)
1091{
1092 int buf_size, result_length;
1093 wchar_t *buf;
1094
1095 /* We have a good handle to the target, use it to determine
1096 the target path name (then we'll call lstat on it). */
1097 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1098 VOLUME_NAME_DOS);
1099 if(!buf_size)
1100 return FALSE;
1101
1102 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001103 if (!buf) {
1104 SetLastError(ERROR_OUTOFMEMORY);
1105 return FALSE;
1106 }
1107
Brian Curtind25aef52011-06-13 15:16:04 -05001108 result_length = Py_GetFinalPathNameByHandleW(hdl,
1109 buf, buf_size, VOLUME_NAME_DOS);
1110
1111 if(!result_length) {
1112 free(buf);
1113 return FALSE;
1114 }
1115
1116 if(!CloseHandle(hdl)) {
1117 free(buf);
1118 return FALSE;
1119 }
1120
1121 buf[result_length] = 0;
1122
1123 *target_path = buf;
1124 return TRUE;
1125}
1126
1127static int
1128win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1129 BOOL traverse);
1130static int
1131win32_xstat_impl(const char *path, struct win32_stat *result,
1132 BOOL traverse)
1133{
Victor Stinner26de69d2011-06-17 15:15:38 +02001134 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001135 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001136 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001137 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001138 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001139 const char *dot;
1140
Brian Curtind25aef52011-06-13 15:16:04 -05001141 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001142 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1143 traverse reparse point. */
1144 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001145 }
1146
Brian Curtinf5e76d02010-11-24 13:14:05 +00001147 hFile = CreateFileA(
1148 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001149 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001150 0, /* share mode */
1151 NULL, /* security attributes */
1152 OPEN_EXISTING,
1153 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001154 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1155 Because of this, calls like GetFinalPathNameByHandle will return
1156 the symlink path agin and not the actual final path. */
1157 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1158 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001159 NULL);
1160
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001161 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001162 /* Either the target doesn't exist, or we don't have access to
1163 get a handle to it. If the former, we need to return an error.
1164 If the latter, we can use attributes_from_dir. */
1165 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001166 return -1;
1167 /* Could not get attributes on open file. Fall back to
1168 reading the directory. */
1169 if (!attributes_from_dir(path, &info, &reparse_tag))
1170 /* Very strange. This should not fail now */
1171 return -1;
1172 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1173 if (traverse) {
1174 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001175 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001176 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001177 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001178 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001179 } else {
1180 if (!GetFileInformationByHandle(hFile, &info)) {
1181 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001182 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001183 }
1184 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001185 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1186 return -1;
1187
1188 /* Close the outer open file handle now that we're about to
1189 reopen it with different flags. */
1190 if (!CloseHandle(hFile))
1191 return -1;
1192
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001193 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001194 /* In order to call GetFinalPathNameByHandle we need to open
1195 the file without the reparse handling flag set. */
1196 hFile2 = CreateFileA(
1197 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1198 NULL, OPEN_EXISTING,
1199 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1200 NULL);
1201 if (hFile2 == INVALID_HANDLE_VALUE)
1202 return -1;
1203
1204 if (!get_target_path(hFile2, &target_path))
1205 return -1;
1206
1207 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001208 free(target_path);
1209 return code;
1210 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001211 } else
1212 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001213 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001214 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001215
1216 /* Set S_IEXEC if it is an .exe, .bat, ... */
1217 dot = strrchr(path, '.');
1218 if (dot) {
1219 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1220 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1221 result->st_mode |= 0111;
1222 }
1223 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001224}
1225
1226static int
Brian Curtind25aef52011-06-13 15:16:04 -05001227win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1228 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001229{
1230 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001231 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001232 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001233 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001234 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001235 const wchar_t *dot;
1236
Brian Curtind25aef52011-06-13 15:16:04 -05001237 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001238 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1239 traverse reparse point. */
1240 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001241 }
1242
Brian Curtinf5e76d02010-11-24 13:14:05 +00001243 hFile = CreateFileW(
1244 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001245 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001246 0, /* share mode */
1247 NULL, /* security attributes */
1248 OPEN_EXISTING,
1249 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001250 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1251 Because of this, calls like GetFinalPathNameByHandle will return
1252 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001253 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001254 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001255 NULL);
1256
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001257 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001258 /* Either the target doesn't exist, or we don't have access to
1259 get a handle to it. If the former, we need to return an error.
1260 If the latter, we can use attributes_from_dir. */
1261 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001262 return -1;
1263 /* Could not get attributes on open file. Fall back to
1264 reading the directory. */
1265 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1266 /* Very strange. This should not fail now */
1267 return -1;
1268 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1269 if (traverse) {
1270 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001271 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001272 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001273 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001274 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001275 } else {
1276 if (!GetFileInformationByHandle(hFile, &info)) {
1277 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001278 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001279 }
1280 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001281 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1282 return -1;
1283
1284 /* Close the outer open file handle now that we're about to
1285 reopen it with different flags. */
1286 if (!CloseHandle(hFile))
1287 return -1;
1288
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001289 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001290 /* In order to call GetFinalPathNameByHandle we need to open
1291 the file without the reparse handling flag set. */
1292 hFile2 = CreateFileW(
1293 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1294 NULL, OPEN_EXISTING,
1295 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1296 NULL);
1297 if (hFile2 == INVALID_HANDLE_VALUE)
1298 return -1;
1299
1300 if (!get_target_path(hFile2, &target_path))
1301 return -1;
1302
1303 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001304 free(target_path);
1305 return code;
1306 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001307 } else
1308 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001309 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001310 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001311
1312 /* Set S_IEXEC if it is an .exe, .bat, ... */
1313 dot = wcsrchr(path, '.');
1314 if (dot) {
1315 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1316 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1317 result->st_mode |= 0111;
1318 }
1319 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001320}
1321
1322static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001323win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001324{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001325 /* Protocol violation: we explicitly clear errno, instead of
1326 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001327 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001328 errno = 0;
1329 return code;
1330}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001331
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001332static int
1333win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1334{
1335 /* Protocol violation: we explicitly clear errno, instead of
1336 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001337 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001338 errno = 0;
1339 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001340}
Brian Curtind25aef52011-06-13 15:16:04 -05001341/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001342
1343 In Posix, stat automatically traverses symlinks and returns the stat
1344 structure for the target. In Windows, the equivalent GetFileAttributes by
1345 default does not traverse symlinks and instead returns attributes for
1346 the symlink.
1347
1348 Therefore, win32_lstat will get the attributes traditionally, and
1349 win32_stat will first explicitly resolve the symlink target and then will
1350 call win32_lstat on that result.
1351
Ezio Melotti4969f702011-03-15 05:59:46 +02001352 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001353
Brian Curtind25aef52011-06-13 15:16:04 -05001354static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001355win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001356{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001357 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001358}
1359
Victor Stinner8c62be82010-05-06 00:08:46 +00001360static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001361win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001362{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001363 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001364}
1365
1366static int
1367win32_stat(const char* path, struct win32_stat *result)
1368{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001369 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001370}
1371
Victor Stinner26de69d2011-06-17 15:15:38 +02001372static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001373win32_stat_w(const wchar_t* path, struct win32_stat *result)
1374{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001375 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001376}
1377
1378static int
1379win32_fstat(int file_number, struct win32_stat *result)
1380{
Victor Stinner8c62be82010-05-06 00:08:46 +00001381 BY_HANDLE_FILE_INFORMATION info;
1382 HANDLE h;
1383 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001384
Victor Stinner8c62be82010-05-06 00:08:46 +00001385 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001386
Victor Stinner8c62be82010-05-06 00:08:46 +00001387 /* Protocol violation: we explicitly clear errno, instead of
1388 setting it to a POSIX error. Callers should use GetLastError. */
1389 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001390
Victor Stinner8c62be82010-05-06 00:08:46 +00001391 if (h == INVALID_HANDLE_VALUE) {
1392 /* This is really a C library error (invalid file handle).
1393 We set the Win32 error to the closes one matching. */
1394 SetLastError(ERROR_INVALID_HANDLE);
1395 return -1;
1396 }
1397 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001398
Victor Stinner8c62be82010-05-06 00:08:46 +00001399 type = GetFileType(h);
1400 if (type == FILE_TYPE_UNKNOWN) {
1401 DWORD error = GetLastError();
1402 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001403 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001404 }
1405 /* else: valid but unknown file */
1406 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001407
Victor Stinner8c62be82010-05-06 00:08:46 +00001408 if (type != FILE_TYPE_DISK) {
1409 if (type == FILE_TYPE_CHAR)
1410 result->st_mode = _S_IFCHR;
1411 else if (type == FILE_TYPE_PIPE)
1412 result->st_mode = _S_IFIFO;
1413 return 0;
1414 }
1415
1416 if (!GetFileInformationByHandle(h, &info)) {
1417 return -1;
1418 }
1419
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001420 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001421 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001422 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1423 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001424}
1425
1426#endif /* MS_WINDOWS */
1427
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001428PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001429"stat_result: Result from stat or lstat.\n\n\
1430This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001431 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001432or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1433\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001434Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1435or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001436\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001437See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001438
1439static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001440 {"st_mode", "protection bits"},
1441 {"st_ino", "inode"},
1442 {"st_dev", "device"},
1443 {"st_nlink", "number of hard links"},
1444 {"st_uid", "user ID of owner"},
1445 {"st_gid", "group ID of owner"},
1446 {"st_size", "total size, in bytes"},
1447 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1448 {NULL, "integer time of last access"},
1449 {NULL, "integer time of last modification"},
1450 {NULL, "integer time of last change"},
1451 {"st_atime", "time of last access"},
1452 {"st_mtime", "time of last modification"},
1453 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001454#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001455 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001456#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001457#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001458 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001459#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001460#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001461 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001462#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001463#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001464 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001465#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001466#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001467 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001468#endif
1469#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001470 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001471#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001472 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001473};
1474
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001475#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001476#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001477#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001478#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001479#endif
1480
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001481#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001482#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1483#else
1484#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1485#endif
1486
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001487#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001488#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1489#else
1490#define ST_RDEV_IDX ST_BLOCKS_IDX
1491#endif
1492
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001493#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1494#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1495#else
1496#define ST_FLAGS_IDX ST_RDEV_IDX
1497#endif
1498
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001499#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001500#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001501#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001502#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001503#endif
1504
1505#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1506#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1507#else
1508#define ST_BIRTHTIME_IDX ST_GEN_IDX
1509#endif
1510
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001511static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001512 "stat_result", /* name */
1513 stat_result__doc__, /* doc */
1514 stat_result_fields,
1515 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001516};
1517
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001518PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001519"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1520This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001521 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001522or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001523\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001524See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001525
1526static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001527 {"f_bsize", },
1528 {"f_frsize", },
1529 {"f_blocks", },
1530 {"f_bfree", },
1531 {"f_bavail", },
1532 {"f_files", },
1533 {"f_ffree", },
1534 {"f_favail", },
1535 {"f_flag", },
1536 {"f_namemax",},
1537 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001538};
1539
1540static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001541 "statvfs_result", /* name */
1542 statvfs_result__doc__, /* doc */
1543 statvfs_result_fields,
1544 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001545};
1546
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001547static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001548static PyTypeObject StatResultType;
1549static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001550static newfunc structseq_new;
1551
1552static PyObject *
1553statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1554{
Victor Stinner8c62be82010-05-06 00:08:46 +00001555 PyStructSequence *result;
1556 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001557
Victor Stinner8c62be82010-05-06 00:08:46 +00001558 result = (PyStructSequence*)structseq_new(type, args, kwds);
1559 if (!result)
1560 return NULL;
1561 /* If we have been initialized from a tuple,
1562 st_?time might be set to None. Initialize it
1563 from the int slots. */
1564 for (i = 7; i <= 9; i++) {
1565 if (result->ob_item[i+3] == Py_None) {
1566 Py_DECREF(Py_None);
1567 Py_INCREF(result->ob_item[i]);
1568 result->ob_item[i+3] = result->ob_item[i];
1569 }
1570 }
1571 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001572}
1573
1574
1575
1576/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001577static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001578
1579PyDoc_STRVAR(stat_float_times__doc__,
1580"stat_float_times([newval]) -> oldval\n\n\
1581Determine whether os.[lf]stat represents time stamps as float objects.\n\
1582If newval is True, future calls to stat() return floats, if it is False,\n\
1583future calls return ints. \n\
1584If newval is omitted, return the current setting.\n");
1585
1586static PyObject*
1587stat_float_times(PyObject* self, PyObject *args)
1588{
Victor Stinner8c62be82010-05-06 00:08:46 +00001589 int newval = -1;
1590 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1591 return NULL;
1592 if (newval == -1)
1593 /* Return old value */
1594 return PyBool_FromLong(_stat_float_times);
1595 _stat_float_times = newval;
1596 Py_INCREF(Py_None);
1597 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001598}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001599
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001600static void
1601fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1602{
Victor Stinner8c62be82010-05-06 00:08:46 +00001603 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001604#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner8c62be82010-05-06 00:08:46 +00001605 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001606#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001607 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001608#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001609 if (!ival)
1610 return;
1611 if (_stat_float_times) {
1612 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1613 } else {
1614 fval = ival;
1615 Py_INCREF(fval);
1616 }
1617 PyStructSequence_SET_ITEM(v, index, ival);
1618 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001619}
1620
Tim Peters5aa91602002-01-30 05:46:57 +00001621/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001622 (used by posix_stat() and posix_fstat()) */
1623static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001624_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001625{
Victor Stinner8c62be82010-05-06 00:08:46 +00001626 unsigned long ansec, mnsec, cnsec;
1627 PyObject *v = PyStructSequence_New(&StatResultType);
1628 if (v == NULL)
1629 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001630
Victor Stinner8c62be82010-05-06 00:08:46 +00001631 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001632#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001633 PyStructSequence_SET_ITEM(v, 1,
1634 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001635#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001636 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001637#endif
1638#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001639 PyStructSequence_SET_ITEM(v, 2,
1640 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001641#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001642 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001643#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001644 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1645 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1646 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001647#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001648 PyStructSequence_SET_ITEM(v, 6,
1649 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001650#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001651 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001652#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001653
Martin v. Löwis14694662006-02-03 12:54:16 +00001654#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001655 ansec = st->st_atim.tv_nsec;
1656 mnsec = st->st_mtim.tv_nsec;
1657 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001658#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001659 ansec = st->st_atimespec.tv_nsec;
1660 mnsec = st->st_mtimespec.tv_nsec;
1661 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001662#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001663 ansec = st->st_atime_nsec;
1664 mnsec = st->st_mtime_nsec;
1665 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001666#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001667 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001668#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001669 fill_time(v, 7, st->st_atime, ansec);
1670 fill_time(v, 8, st->st_mtime, mnsec);
1671 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001672
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001673#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001674 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1675 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001676#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001677#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001678 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1679 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001680#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001681#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001682 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1683 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001684#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001685#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001686 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1687 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001688#endif
1689#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001690 {
1691 PyObject *val;
1692 unsigned long bsec,bnsec;
1693 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001694#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner8c62be82010-05-06 00:08:46 +00001695 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001696#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001697 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001698#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001699 if (_stat_float_times) {
1700 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1701 } else {
1702 val = PyLong_FromLong((long)bsec);
1703 }
1704 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1705 val);
1706 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001707#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001708#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001709 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1710 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001711#endif
Fred Drake699f3522000-06-29 21:12:41 +00001712
Victor Stinner8c62be82010-05-06 00:08:46 +00001713 if (PyErr_Occurred()) {
1714 Py_DECREF(v);
1715 return NULL;
1716 }
Fred Drake699f3522000-06-29 21:12:41 +00001717
Victor Stinner8c62be82010-05-06 00:08:46 +00001718 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001719}
1720
Barry Warsaw53699e91996-12-10 23:23:01 +00001721static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001722posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +00001723 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001724#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00001725 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001726#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001727 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001728#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001729 char *wformat,
1730 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001731{
Victor Stinner8c62be82010-05-06 00:08:46 +00001732 STRUCT_STAT st;
1733 PyObject *opath;
1734 char *path;
1735 int res;
1736 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001737
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001738#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001739 PyUnicodeObject *po;
1740 if (PyArg_ParseTuple(args, wformat, &po)) {
1741 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001742
Victor Stinner8c62be82010-05-06 00:08:46 +00001743 Py_BEGIN_ALLOW_THREADS
1744 /* PyUnicode_AS_UNICODE result OK without
1745 thread lock as it is a simple dereference. */
1746 res = wstatfunc(wpath, &st);
1747 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001748
Victor Stinner8c62be82010-05-06 00:08:46 +00001749 if (res != 0)
1750 return win32_error_unicode("stat", wpath);
1751 return _pystat_fromstructstat(&st);
1752 }
1753 /* Drop the argument parsing error as narrow strings
1754 are also valid. */
1755 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001756#endif
1757
Victor Stinner8c62be82010-05-06 00:08:46 +00001758 if (!PyArg_ParseTuple(args, format,
1759 PyUnicode_FSConverter, &opath))
1760 return NULL;
1761 path = PyBytes_AsString(opath);
1762 Py_BEGIN_ALLOW_THREADS
1763 res = (*statfunc)(path, &st);
1764 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001765
Victor Stinner8c62be82010-05-06 00:08:46 +00001766 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001767#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001768 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001769#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001770 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001771#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001772 }
1773 else
1774 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001775
Victor Stinner8c62be82010-05-06 00:08:46 +00001776 Py_DECREF(opath);
1777 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001778}
1779
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001780/* POSIX methods */
1781
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001782PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001783"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001784Use the real uid/gid to test for access to a path. Note that most\n\
1785operations will use the effective uid/gid, therefore this routine can\n\
1786be used in a suid/sgid environment to test if the invoking user has the\n\
1787specified access to the path. The mode argument can be F_OK to test\n\
1788existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001789
1790static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001791posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001792{
Victor Stinner8c62be82010-05-06 00:08:46 +00001793 PyObject *opath;
1794 char *path;
1795 int mode;
1796
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001797#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001798 DWORD attr;
1799 PyUnicodeObject *po;
1800 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1801 Py_BEGIN_ALLOW_THREADS
1802 /* PyUnicode_AS_UNICODE OK without thread lock as
1803 it is a simple dereference. */
1804 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1805 Py_END_ALLOW_THREADS
1806 goto finish;
1807 }
1808 /* Drop the argument parsing error as narrow strings
1809 are also valid. */
1810 PyErr_Clear();
1811 if (!PyArg_ParseTuple(args, "O&i:access",
1812 PyUnicode_FSConverter, &opath, &mode))
1813 return NULL;
1814 path = PyBytes_AsString(opath);
1815 Py_BEGIN_ALLOW_THREADS
1816 attr = GetFileAttributesA(path);
1817 Py_END_ALLOW_THREADS
1818 Py_DECREF(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001819finish:
Victor Stinner8c62be82010-05-06 00:08:46 +00001820 if (attr == 0xFFFFFFFF)
1821 /* File does not exist, or cannot read attributes */
1822 return PyBool_FromLong(0);
1823 /* Access is possible if either write access wasn't requested, or
1824 the file isn't read-only, or if it's a directory, as there are
1825 no read-only directories on Windows. */
1826 return PyBool_FromLong(!(mode & 2)
1827 || !(attr & FILE_ATTRIBUTE_READONLY)
1828 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001829#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001830 int res;
1831 if (!PyArg_ParseTuple(args, "O&i:access",
1832 PyUnicode_FSConverter, &opath, &mode))
1833 return NULL;
1834 path = PyBytes_AsString(opath);
1835 Py_BEGIN_ALLOW_THREADS
1836 res = access(path, mode);
1837 Py_END_ALLOW_THREADS
1838 Py_DECREF(opath);
1839 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001840#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001841}
1842
Guido van Rossumd371ff11999-01-25 16:12:23 +00001843#ifndef F_OK
1844#define F_OK 0
1845#endif
1846#ifndef R_OK
1847#define R_OK 4
1848#endif
1849#ifndef W_OK
1850#define W_OK 2
1851#endif
1852#ifndef X_OK
1853#define X_OK 1
1854#endif
1855
1856#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001857PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001858"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001859Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001860
1861static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001862posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001863{
Victor Stinner8c62be82010-05-06 00:08:46 +00001864 int id;
1865 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001866
Victor Stinner8c62be82010-05-06 00:08:46 +00001867 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1868 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001869
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001870#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001871 /* file descriptor 0 only, the default input device (stdin) */
1872 if (id == 0) {
1873 ret = ttyname();
1874 }
1875 else {
1876 ret = NULL;
1877 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001878#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001879 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001880#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001881 if (ret == NULL)
1882 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001883 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001884}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001885#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001886
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001887#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001888PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001889"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001890Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001891
1892static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001893posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001894{
Victor Stinner8c62be82010-05-06 00:08:46 +00001895 char *ret;
1896 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001897
Greg Wardb48bc172000-03-01 21:51:56 +00001898#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00001899 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001900#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001901 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001902#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001903 if (ret == NULL)
1904 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001905 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001906}
1907#endif
1908
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001909PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001910"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001911Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001912
Barry Warsaw53699e91996-12-10 23:23:01 +00001913static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001914posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001915{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001916#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001917 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001918#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001919 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001920#elif defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001921 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001922#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001923 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001924#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001925}
1926
Fred Drake4d1e64b2002-04-15 19:40:07 +00001927#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001928PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001929"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001930Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001931opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001932
1933static PyObject *
1934posix_fchdir(PyObject *self, PyObject *fdobj)
1935{
Victor Stinner8c62be82010-05-06 00:08:46 +00001936 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001937}
1938#endif /* HAVE_FCHDIR */
1939
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001940
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001941PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001942"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001943Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001944
Barry Warsaw53699e91996-12-10 23:23:01 +00001945static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001946posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001947{
Victor Stinner8c62be82010-05-06 00:08:46 +00001948 PyObject *opath = NULL;
1949 char *path = NULL;
1950 int i;
1951 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001952#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001953 DWORD attr;
1954 PyUnicodeObject *po;
1955 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1956 Py_BEGIN_ALLOW_THREADS
1957 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1958 if (attr != 0xFFFFFFFF) {
1959 if (i & _S_IWRITE)
1960 attr &= ~FILE_ATTRIBUTE_READONLY;
1961 else
1962 attr |= FILE_ATTRIBUTE_READONLY;
1963 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1964 }
1965 else
1966 res = 0;
1967 Py_END_ALLOW_THREADS
1968 if (!res)
1969 return win32_error_unicode("chmod",
1970 PyUnicode_AS_UNICODE(po));
1971 Py_INCREF(Py_None);
1972 return Py_None;
1973 }
1974 /* Drop the argument parsing error as narrow strings
1975 are also valid. */
1976 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001977
Victor Stinner8c62be82010-05-06 00:08:46 +00001978 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1979 &opath, &i))
1980 return NULL;
1981 path = PyBytes_AsString(opath);
1982 Py_BEGIN_ALLOW_THREADS
1983 attr = GetFileAttributesA(path);
1984 if (attr != 0xFFFFFFFF) {
1985 if (i & _S_IWRITE)
1986 attr &= ~FILE_ATTRIBUTE_READONLY;
1987 else
1988 attr |= FILE_ATTRIBUTE_READONLY;
1989 res = SetFileAttributesA(path, attr);
1990 }
1991 else
1992 res = 0;
1993 Py_END_ALLOW_THREADS
1994 if (!res) {
1995 win32_error("chmod", path);
1996 Py_DECREF(opath);
1997 return NULL;
1998 }
1999 Py_DECREF(opath);
2000 Py_INCREF(Py_None);
2001 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002002#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00002003 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
2004 &opath, &i))
2005 return NULL;
2006 path = PyBytes_AsString(opath);
2007 Py_BEGIN_ALLOW_THREADS
2008 res = chmod(path, i);
2009 Py_END_ALLOW_THREADS
2010 if (res < 0)
2011 return posix_error_with_allocated_filename(opath);
2012 Py_DECREF(opath);
2013 Py_INCREF(Py_None);
2014 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002015#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002016}
2017
Christian Heimes4e30a842007-11-30 22:12:06 +00002018#ifdef HAVE_FCHMOD
2019PyDoc_STRVAR(posix_fchmod__doc__,
2020"fchmod(fd, mode)\n\n\
2021Change the access permissions of the file given by file\n\
2022descriptor fd.");
2023
2024static PyObject *
2025posix_fchmod(PyObject *self, PyObject *args)
2026{
Victor Stinner8c62be82010-05-06 00:08:46 +00002027 int fd, mode, res;
2028 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2029 return NULL;
2030 Py_BEGIN_ALLOW_THREADS
2031 res = fchmod(fd, mode);
2032 Py_END_ALLOW_THREADS
2033 if (res < 0)
2034 return posix_error();
2035 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002036}
2037#endif /* HAVE_FCHMOD */
2038
2039#ifdef HAVE_LCHMOD
2040PyDoc_STRVAR(posix_lchmod__doc__,
2041"lchmod(path, mode)\n\n\
2042Change the access permissions of a file. If path is a symlink, this\n\
2043affects the link itself rather than the target.");
2044
2045static PyObject *
2046posix_lchmod(PyObject *self, PyObject *args)
2047{
Victor Stinner8c62be82010-05-06 00:08:46 +00002048 PyObject *opath;
2049 char *path;
2050 int i;
2051 int res;
2052 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2053 &opath, &i))
2054 return NULL;
2055 path = PyBytes_AsString(opath);
2056 Py_BEGIN_ALLOW_THREADS
2057 res = lchmod(path, i);
2058 Py_END_ALLOW_THREADS
2059 if (res < 0)
2060 return posix_error_with_allocated_filename(opath);
2061 Py_DECREF(opath);
2062 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002063}
2064#endif /* HAVE_LCHMOD */
2065
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002066
Thomas Wouterscf297e42007-02-23 15:07:44 +00002067#ifdef HAVE_CHFLAGS
2068PyDoc_STRVAR(posix_chflags__doc__,
2069"chflags(path, flags)\n\n\
2070Set file flags.");
2071
2072static PyObject *
2073posix_chflags(PyObject *self, PyObject *args)
2074{
Victor Stinner8c62be82010-05-06 00:08:46 +00002075 PyObject *opath;
2076 char *path;
2077 unsigned long flags;
2078 int res;
2079 if (!PyArg_ParseTuple(args, "O&k:chflags",
2080 PyUnicode_FSConverter, &opath, &flags))
2081 return NULL;
2082 path = PyBytes_AsString(opath);
2083 Py_BEGIN_ALLOW_THREADS
2084 res = chflags(path, flags);
2085 Py_END_ALLOW_THREADS
2086 if (res < 0)
2087 return posix_error_with_allocated_filename(opath);
2088 Py_DECREF(opath);
2089 Py_INCREF(Py_None);
2090 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002091}
2092#endif /* HAVE_CHFLAGS */
2093
2094#ifdef HAVE_LCHFLAGS
2095PyDoc_STRVAR(posix_lchflags__doc__,
2096"lchflags(path, flags)\n\n\
2097Set file flags.\n\
2098This function will not follow symbolic links.");
2099
2100static PyObject *
2101posix_lchflags(PyObject *self, PyObject *args)
2102{
Victor Stinner8c62be82010-05-06 00:08:46 +00002103 PyObject *opath;
2104 char *path;
2105 unsigned long flags;
2106 int res;
2107 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2108 PyUnicode_FSConverter, &opath, &flags))
2109 return NULL;
2110 path = PyBytes_AsString(opath);
2111 Py_BEGIN_ALLOW_THREADS
2112 res = lchflags(path, flags);
2113 Py_END_ALLOW_THREADS
2114 if (res < 0)
2115 return posix_error_with_allocated_filename(opath);
2116 Py_DECREF(opath);
2117 Py_INCREF(Py_None);
2118 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002119}
2120#endif /* HAVE_LCHFLAGS */
2121
Martin v. Löwis244edc82001-10-04 22:44:26 +00002122#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002123PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002124"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002125Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002126
2127static PyObject *
2128posix_chroot(PyObject *self, PyObject *args)
2129{
Victor Stinner8c62be82010-05-06 00:08:46 +00002130 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002131}
2132#endif
2133
Guido van Rossum21142a01999-01-08 21:05:37 +00002134#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002135PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002136"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002137force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002138
2139static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002140posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002141{
Stefan Krah0e803b32010-11-26 16:16:47 +00002142 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002143}
2144#endif /* HAVE_FSYNC */
2145
2146#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002147
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002148#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002149extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2150#endif
2151
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002152PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002153"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002154force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002155 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002156
2157static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002158posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002159{
Stefan Krah0e803b32010-11-26 16:16:47 +00002160 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002161}
2162#endif /* HAVE_FDATASYNC */
2163
2164
Fredrik Lundh10723342000-07-10 16:38:09 +00002165#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002166PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002167"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002168Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002169
Barry Warsaw53699e91996-12-10 23:23:01 +00002170static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002171posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002172{
Victor Stinner8c62be82010-05-06 00:08:46 +00002173 PyObject *opath;
2174 char *path;
2175 long uid, gid;
2176 int res;
2177 if (!PyArg_ParseTuple(args, "O&ll:chown",
2178 PyUnicode_FSConverter, &opath,
2179 &uid, &gid))
2180 return NULL;
2181 path = PyBytes_AsString(opath);
2182 Py_BEGIN_ALLOW_THREADS
2183 res = chown(path, (uid_t) uid, (gid_t) gid);
2184 Py_END_ALLOW_THREADS
2185 if (res < 0)
2186 return posix_error_with_allocated_filename(opath);
2187 Py_DECREF(opath);
2188 Py_INCREF(Py_None);
2189 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002190}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002191#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002192
Christian Heimes4e30a842007-11-30 22:12:06 +00002193#ifdef HAVE_FCHOWN
2194PyDoc_STRVAR(posix_fchown__doc__,
2195"fchown(fd, uid, gid)\n\n\
2196Change the owner and group id of the file given by file descriptor\n\
2197fd to the numeric uid and gid.");
2198
2199static PyObject *
2200posix_fchown(PyObject *self, PyObject *args)
2201{
Victor Stinner8c62be82010-05-06 00:08:46 +00002202 int fd;
2203 long uid, gid;
2204 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02002205 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00002206 return NULL;
2207 Py_BEGIN_ALLOW_THREADS
2208 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2209 Py_END_ALLOW_THREADS
2210 if (res < 0)
2211 return posix_error();
2212 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002213}
2214#endif /* HAVE_FCHOWN */
2215
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002216#ifdef HAVE_LCHOWN
2217PyDoc_STRVAR(posix_lchown__doc__,
2218"lchown(path, uid, gid)\n\n\
2219Change the owner and group id of path to the numeric uid and gid.\n\
2220This function will not follow symbolic links.");
2221
2222static PyObject *
2223posix_lchown(PyObject *self, PyObject *args)
2224{
Victor Stinner8c62be82010-05-06 00:08:46 +00002225 PyObject *opath;
2226 char *path;
2227 long uid, gid;
2228 int res;
2229 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2230 PyUnicode_FSConverter, &opath,
2231 &uid, &gid))
2232 return NULL;
2233 path = PyBytes_AsString(opath);
2234 Py_BEGIN_ALLOW_THREADS
2235 res = lchown(path, (uid_t) uid, (gid_t) gid);
2236 Py_END_ALLOW_THREADS
2237 if (res < 0)
2238 return posix_error_with_allocated_filename(opath);
2239 Py_DECREF(opath);
2240 Py_INCREF(Py_None);
2241 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002242}
2243#endif /* HAVE_LCHOWN */
2244
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002245
Guido van Rossum36bc6801995-06-14 22:54:23 +00002246#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002247static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002248posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002249{
Victor Stinner8c62be82010-05-06 00:08:46 +00002250 char buf[1026];
2251 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002252
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002253#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002254 if (!use_bytes) {
2255 wchar_t wbuf[1026];
2256 wchar_t *wbuf2 = wbuf;
2257 PyObject *resobj;
2258 DWORD len;
2259 Py_BEGIN_ALLOW_THREADS
2260 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2261 /* If the buffer is large enough, len does not include the
2262 terminating \0. If the buffer is too small, len includes
2263 the space needed for the terminator. */
2264 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2265 wbuf2 = malloc(len * sizeof(wchar_t));
2266 if (wbuf2)
2267 len = GetCurrentDirectoryW(len, wbuf2);
2268 }
2269 Py_END_ALLOW_THREADS
2270 if (!wbuf2) {
2271 PyErr_NoMemory();
2272 return NULL;
2273 }
2274 if (!len) {
2275 if (wbuf2 != wbuf) free(wbuf2);
2276 return win32_error("getcwdu", NULL);
2277 }
2278 resobj = PyUnicode_FromWideChar(wbuf2, len);
2279 if (wbuf2 != wbuf) free(wbuf2);
2280 return resobj;
2281 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002282#endif
2283
Victor Stinner8c62be82010-05-06 00:08:46 +00002284 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002285#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002286 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002287#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002288 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002289#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002290 Py_END_ALLOW_THREADS
2291 if (res == NULL)
2292 return posix_error();
2293 if (use_bytes)
2294 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002295 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002296}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002297
2298PyDoc_STRVAR(posix_getcwd__doc__,
2299"getcwd() -> path\n\n\
2300Return a unicode string representing the current working directory.");
2301
2302static PyObject *
2303posix_getcwd_unicode(PyObject *self)
2304{
2305 return posix_getcwd(0);
2306}
2307
2308PyDoc_STRVAR(posix_getcwdb__doc__,
2309"getcwdb() -> path\n\n\
2310Return a bytes string representing the current working directory.");
2311
2312static PyObject *
2313posix_getcwd_bytes(PyObject *self)
2314{
2315 return posix_getcwd(1);
2316}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002317#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002318
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002319
Guido van Rossumb6775db1994-08-01 11:34:53 +00002320#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002321PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002322"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002323Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002324
Barry Warsaw53699e91996-12-10 23:23:01 +00002325static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002326posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002327{
Victor Stinner8c62be82010-05-06 00:08:46 +00002328 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002329}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002330#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002331
Brian Curtin1b9df392010-11-24 20:24:31 +00002332#ifdef MS_WINDOWS
2333PyDoc_STRVAR(win32_link__doc__,
2334"link(src, dst)\n\n\
2335Create a hard link to a file.");
2336
2337static PyObject *
2338win32_link(PyObject *self, PyObject *args)
2339{
2340 PyObject *osrc, *odst;
2341 char *src, *dst;
2342 BOOL rslt;
2343
Brian Curtinfc889c42010-11-28 23:59:46 +00002344 PyUnicodeObject *usrc, *udst;
2345 if (PyArg_ParseTuple(args, "UU:link", &usrc, &udst)) {
2346 Py_BEGIN_ALLOW_THREADS
2347 rslt = CreateHardLinkW(PyUnicode_AS_UNICODE(udst),
2348 PyUnicode_AS_UNICODE(usrc), NULL);
2349 Py_END_ALLOW_THREADS
2350
2351 if (rslt == 0)
2352 return win32_error("link", NULL);
2353
2354 Py_RETURN_NONE;
2355 }
2356
2357 /* Narrow strings also valid. */
2358 PyErr_Clear();
2359
Brian Curtin1b9df392010-11-24 20:24:31 +00002360 if (!PyArg_ParseTuple(args, "O&O&:link", PyUnicode_FSConverter, &osrc,
2361 PyUnicode_FSConverter, &odst))
2362 return NULL;
2363
2364 src = PyBytes_AsString(osrc);
2365 dst = PyBytes_AsString(odst);
2366
2367 Py_BEGIN_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00002368 rslt = CreateHardLinkA(dst, src, NULL);
Brian Curtin1b9df392010-11-24 20:24:31 +00002369 Py_END_ALLOW_THREADS
2370
Stefan Krah30b341f2010-11-27 11:44:18 +00002371 Py_DECREF(osrc);
2372 Py_DECREF(odst);
Brian Curtin1b9df392010-11-24 20:24:31 +00002373 if (rslt == 0)
Brian Curtinfc889c42010-11-28 23:59:46 +00002374 return win32_error("link", NULL);
Brian Curtin1b9df392010-11-24 20:24:31 +00002375
2376 Py_RETURN_NONE;
2377}
2378#endif /* MS_WINDOWS */
2379
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002380
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002381PyDoc_STRVAR(posix_listdir__doc__,
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002382"listdir([path]) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002383Return a list containing the names of the entries in the directory.\n\
2384\n\
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002385 path: path of directory to list (default: '.')\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002386\n\
2387The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002388entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002389
Barry Warsaw53699e91996-12-10 23:23:01 +00002390static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002391posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002392{
Victor Stinner8c62be82010-05-06 00:08:46 +00002393 /* XXX Should redo this putting the (now four) versions of opendir
2394 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002395#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002396
Victor Stinner8c62be82010-05-06 00:08:46 +00002397 PyObject *d, *v;
2398 HANDLE hFindFile;
2399 BOOL result;
2400 WIN32_FIND_DATA FileData;
2401 PyObject *opath;
2402 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2403 char *bufptr = namebuf;
2404 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002405
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002406 PyObject *po = NULL;
2407 if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002408 WIN32_FIND_DATAW wFileData;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002409 Py_UNICODE *wnamebuf, *po_wchars;
Victor Stinner26de69d2011-06-17 15:15:38 +02002410
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002411 if (po == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002412 po_wchars = L".";
2413 len = 1;
2414 } else {
2415 po_wchars = PyUnicode_AS_UNICODE(po);
2416 len = PyUnicode_GET_SIZE(po);
2417 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002418 /* Overallocate for \\*.*\0 */
Victor Stinner8c62be82010-05-06 00:08:46 +00002419 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2420 if (!wnamebuf) {
2421 PyErr_NoMemory();
2422 return NULL;
2423 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002424 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00002425 if (len > 0) {
2426 Py_UNICODE wch = wnamebuf[len-1];
2427 if (wch != L'/' && wch != L'\\' && wch != L':')
2428 wnamebuf[len++] = L'\\';
2429 wcscpy(wnamebuf + len, L"*.*");
2430 }
2431 if ((d = PyList_New(0)) == NULL) {
2432 free(wnamebuf);
2433 return NULL;
2434 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00002435 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002436 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002437 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002438 if (hFindFile == INVALID_HANDLE_VALUE) {
2439 int error = GetLastError();
2440 if (error == ERROR_FILE_NOT_FOUND) {
2441 free(wnamebuf);
2442 return d;
2443 }
2444 Py_DECREF(d);
2445 win32_error_unicode("FindFirstFileW", wnamebuf);
2446 free(wnamebuf);
2447 return NULL;
2448 }
2449 do {
2450 /* Skip over . and .. */
2451 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2452 wcscmp(wFileData.cFileName, L"..") != 0) {
2453 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2454 if (v == NULL) {
2455 Py_DECREF(d);
2456 d = NULL;
2457 break;
2458 }
2459 if (PyList_Append(d, v) != 0) {
2460 Py_DECREF(v);
2461 Py_DECREF(d);
2462 d = NULL;
2463 break;
2464 }
2465 Py_DECREF(v);
2466 }
2467 Py_BEGIN_ALLOW_THREADS
2468 result = FindNextFileW(hFindFile, &wFileData);
2469 Py_END_ALLOW_THREADS
2470 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2471 it got to the end of the directory. */
2472 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2473 Py_DECREF(d);
2474 win32_error_unicode("FindNextFileW", wnamebuf);
2475 FindClose(hFindFile);
2476 free(wnamebuf);
2477 return NULL;
2478 }
2479 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002480
Victor Stinner8c62be82010-05-06 00:08:46 +00002481 if (FindClose(hFindFile) == FALSE) {
2482 Py_DECREF(d);
2483 win32_error_unicode("FindClose", wnamebuf);
2484 free(wnamebuf);
2485 return NULL;
2486 }
2487 free(wnamebuf);
2488 return d;
2489 }
2490 /* Drop the argument parsing error as narrow strings
2491 are also valid. */
2492 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002493
Victor Stinner8c62be82010-05-06 00:08:46 +00002494 if (!PyArg_ParseTuple(args, "O&:listdir",
2495 PyUnicode_FSConverter, &opath))
2496 return NULL;
2497 if (PyBytes_GET_SIZE(opath)+1 > MAX_PATH) {
2498 PyErr_SetString(PyExc_ValueError, "path too long");
2499 Py_DECREF(opath);
2500 return NULL;
2501 }
2502 strcpy(namebuf, PyBytes_AsString(opath));
2503 len = PyObject_Size(opath);
Stefan Krah2a7feee2010-11-27 22:06:49 +00002504 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00002505 if (len > 0) {
2506 char ch = namebuf[len-1];
2507 if (ch != SEP && ch != ALTSEP && ch != ':')
2508 namebuf[len++] = '/';
2509 strcpy(namebuf + len, "*.*");
2510 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002511
Victor Stinner8c62be82010-05-06 00:08:46 +00002512 if ((d = PyList_New(0)) == NULL)
2513 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002514
Antoine Pitroub73caab2010-08-09 23:39:31 +00002515 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002516 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002517 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002518 if (hFindFile == INVALID_HANDLE_VALUE) {
2519 int error = GetLastError();
2520 if (error == ERROR_FILE_NOT_FOUND)
2521 return d;
2522 Py_DECREF(d);
2523 return win32_error("FindFirstFile", namebuf);
2524 }
2525 do {
2526 /* Skip over . and .. */
2527 if (strcmp(FileData.cFileName, ".") != 0 &&
2528 strcmp(FileData.cFileName, "..") != 0) {
2529 v = PyBytes_FromString(FileData.cFileName);
2530 if (v == NULL) {
2531 Py_DECREF(d);
2532 d = NULL;
2533 break;
2534 }
2535 if (PyList_Append(d, v) != 0) {
2536 Py_DECREF(v);
2537 Py_DECREF(d);
2538 d = NULL;
2539 break;
2540 }
2541 Py_DECREF(v);
2542 }
2543 Py_BEGIN_ALLOW_THREADS
2544 result = FindNextFile(hFindFile, &FileData);
2545 Py_END_ALLOW_THREADS
2546 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2547 it got to the end of the directory. */
2548 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2549 Py_DECREF(d);
2550 win32_error("FindNextFile", namebuf);
2551 FindClose(hFindFile);
2552 return NULL;
2553 }
2554 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002555
Victor Stinner8c62be82010-05-06 00:08:46 +00002556 if (FindClose(hFindFile) == FALSE) {
2557 Py_DECREF(d);
2558 return win32_error("FindClose", namebuf);
2559 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002560
Victor Stinner8c62be82010-05-06 00:08:46 +00002561 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002562
Tim Peters0bb44a42000-09-15 07:44:49 +00002563#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002564
2565#ifndef MAX_PATH
2566#define MAX_PATH CCHMAXPATH
2567#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002568 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002569 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002570 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002571 PyObject *d, *v;
2572 char namebuf[MAX_PATH+5];
2573 HDIR hdir = 1;
2574 ULONG srchcnt = 1;
2575 FILEFINDBUF3 ep;
2576 APIRET rc;
2577
Victor Stinner8c62be82010-05-06 00:08:46 +00002578 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002579 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002580 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002581 name = PyBytes_AsString(oname);
2582 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002583 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002584 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002585 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002586 return NULL;
2587 }
2588 strcpy(namebuf, name);
2589 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002590 if (*pt == ALTSEP)
2591 *pt = SEP;
2592 if (namebuf[len-1] != SEP)
2593 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002594 strcpy(namebuf + len, "*.*");
2595
Neal Norwitz6c913782007-10-14 03:23:09 +00002596 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002597 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002598 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002599 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002600
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002601 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2602 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002603 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002604 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2605 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2606 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002607
2608 if (rc != NO_ERROR) {
2609 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002610 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002611 }
2612
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002613 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002614 do {
2615 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002616 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002617 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002618
2619 strcpy(namebuf, ep.achName);
2620
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002621 /* Leave Case of Name Alone -- In Native Form */
2622 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002623
Christian Heimes72b710a2008-05-26 13:28:38 +00002624 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002625 if (v == NULL) {
2626 Py_DECREF(d);
2627 d = NULL;
2628 break;
2629 }
2630 if (PyList_Append(d, v) != 0) {
2631 Py_DECREF(v);
2632 Py_DECREF(d);
2633 d = NULL;
2634 break;
2635 }
2636 Py_DECREF(v);
2637 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2638 }
2639
Victor Stinnerdcb24032010-04-22 12:08:36 +00002640 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002641 return d;
2642#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002643 PyObject *oname;
2644 char *name;
2645 PyObject *d, *v;
2646 DIR *dirp;
2647 struct dirent *ep;
2648 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002649
Victor Stinner8c62be82010-05-06 00:08:46 +00002650 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002651 /* v is never read, so it does not need to be initialized yet. */
2652 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002653 arg_is_unicode = 0;
2654 PyErr_Clear();
2655 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002656 oname = NULL;
2657 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
Victor Stinner8c62be82010-05-06 00:08:46 +00002658 return NULL;
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002659 if (oname == NULL) { /* Default arg: "." */
Stefan Krah0e803b32010-11-26 16:16:47 +00002660 oname = PyBytes_FromString(".");
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002661 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002662 name = PyBytes_AsString(oname);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002663 Py_BEGIN_ALLOW_THREADS
2664 dirp = opendir(name);
2665 Py_END_ALLOW_THREADS
2666 if (dirp == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002667 return posix_error_with_allocated_filename(oname);
2668 }
2669 if ((d = PyList_New(0)) == NULL) {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002670 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002671 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002672 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002673 Py_DECREF(oname);
2674 return NULL;
2675 }
2676 for (;;) {
2677 errno = 0;
2678 Py_BEGIN_ALLOW_THREADS
2679 ep = readdir(dirp);
2680 Py_END_ALLOW_THREADS
2681 if (ep == NULL) {
2682 if (errno == 0) {
2683 break;
2684 } else {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002685 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002686 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002687 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002688 Py_DECREF(d);
2689 return posix_error_with_allocated_filename(oname);
2690 }
2691 }
2692 if (ep->d_name[0] == '.' &&
2693 (NAMLEN(ep) == 1 ||
2694 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2695 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002696 if (arg_is_unicode)
2697 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2698 else
2699 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002700 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002701 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002702 break;
2703 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002704 if (PyList_Append(d, v) != 0) {
2705 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002706 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002707 break;
2708 }
2709 Py_DECREF(v);
2710 }
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002711 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002712 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002713 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002714 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002715
Victor Stinner8c62be82010-05-06 00:08:46 +00002716 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002717
Tim Peters0bb44a42000-09-15 07:44:49 +00002718#endif /* which OS */
2719} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002720
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002721#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002722/* A helper function for abspath on win32 */
2723static PyObject *
2724posix__getfullpathname(PyObject *self, PyObject *args)
2725{
Victor Stinner8c62be82010-05-06 00:08:46 +00002726 PyObject *opath;
2727 char *path;
2728 char outbuf[MAX_PATH*2];
2729 char *temp;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002730#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002731 PyUnicodeObject *po;
2732 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2733 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2734 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2735 Py_UNICODE *wtemp;
2736 DWORD result;
2737 PyObject *v;
2738 result = GetFullPathNameW(wpath,
2739 sizeof(woutbuf)/sizeof(woutbuf[0]),
2740 woutbuf, &wtemp);
2741 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2742 woutbufp = malloc(result * sizeof(Py_UNICODE));
2743 if (!woutbufp)
2744 return PyErr_NoMemory();
2745 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2746 }
2747 if (result)
2748 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2749 else
2750 v = win32_error_unicode("GetFullPathNameW", wpath);
2751 if (woutbufp != woutbuf)
2752 free(woutbufp);
2753 return v;
2754 }
2755 /* Drop the argument parsing error as narrow strings
2756 are also valid. */
2757 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002758
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002759#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002760 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2761 PyUnicode_FSConverter, &opath))
2762 return NULL;
2763 path = PyBytes_AsString(opath);
2764 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2765 outbuf, &temp)) {
2766 win32_error("GetFullPathName", path);
2767 Py_DECREF(opath);
2768 return NULL;
2769 }
2770 Py_DECREF(opath);
2771 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2772 return PyUnicode_Decode(outbuf, strlen(outbuf),
2773 Py_FileSystemDefaultEncoding, NULL);
2774 }
2775 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002776} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00002777
Brian Curtind25aef52011-06-13 15:16:04 -05002778
Brian Curtinf5e76d02010-11-24 13:14:05 +00002779
Brian Curtind40e6f72010-07-08 21:39:08 +00002780/* A helper function for samepath on windows */
2781static PyObject *
2782posix__getfinalpathname(PyObject *self, PyObject *args)
2783{
2784 HANDLE hFile;
2785 int buf_size;
2786 wchar_t *target_path;
2787 int result_length;
2788 PyObject *result;
2789 wchar_t *path;
Victor Stinner26de69d2011-06-17 15:15:38 +02002790
Brian Curtin94622b02010-09-24 00:03:39 +00002791 if (!PyArg_ParseTuple(args, "u|:_getfinalpathname", &path)) {
Brian Curtind40e6f72010-07-08 21:39:08 +00002792 return NULL;
2793 }
2794
2795 if(!check_GetFinalPathNameByHandle()) {
2796 /* If the OS doesn't have GetFinalPathNameByHandle, return a
2797 NotImplementedError. */
2798 return PyErr_Format(PyExc_NotImplementedError,
2799 "GetFinalPathNameByHandle not available on this platform");
2800 }
2801
2802 hFile = CreateFileW(
2803 path,
2804 0, /* desired access */
2805 0, /* share mode */
2806 NULL, /* security attributes */
2807 OPEN_EXISTING,
2808 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
2809 FILE_FLAG_BACKUP_SEMANTICS,
2810 NULL);
Victor Stinner26de69d2011-06-17 15:15:38 +02002811
Brian Curtind40e6f72010-07-08 21:39:08 +00002812 if(hFile == INVALID_HANDLE_VALUE) {
2813 return win32_error_unicode("GetFinalPathNamyByHandle", path);
Brian Curtin74e45612010-07-09 15:58:59 +00002814 return PyErr_Format(PyExc_RuntimeError,
2815 "Could not get a handle to file.");
Brian Curtind40e6f72010-07-08 21:39:08 +00002816 }
2817
2818 /* We have a good handle to the target, use it to determine the
2819 target path name. */
2820 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
2821
2822 if(!buf_size)
2823 return win32_error_unicode("GetFinalPathNameByHandle", path);
2824
2825 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
2826 if(!target_path)
2827 return PyErr_NoMemory();
2828
2829 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
2830 buf_size, VOLUME_NAME_DOS);
2831 if(!result_length)
2832 return win32_error_unicode("GetFinalPathNamyByHandle", path);
2833
2834 if(!CloseHandle(hFile))
2835 return win32_error_unicode("GetFinalPathNameByHandle", path);
2836
2837 target_path[result_length] = 0;
2838 result = PyUnicode_FromUnicode(target_path, result_length);
2839 free(target_path);
2840 return result;
2841
2842} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00002843
2844static PyObject *
2845posix__getfileinformation(PyObject *self, PyObject *args)
2846{
2847 HANDLE hFile;
2848 BY_HANDLE_FILE_INFORMATION info;
2849 int fd;
2850
2851 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
2852 return NULL;
2853
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00002854 if (!_PyVerify_fd(fd))
2855 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00002856
2857 hFile = (HANDLE)_get_osfhandle(fd);
2858 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00002859 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00002860
2861 if (!GetFileInformationByHandle(hFile, &info))
2862 return win32_error("_getfileinformation", NULL);
2863
2864 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
2865 info.nFileIndexHigh,
2866 info.nFileIndexLow);
2867}
Brian Curtin9c669cc2011-06-08 18:17:18 -05002868
Brian Curtin95d028f2011-06-09 09:10:38 -05002869PyDoc_STRVAR(posix__isdir__doc__,
2870"Return true if the pathname refers to an existing directory.");
2871
Brian Curtin9c669cc2011-06-08 18:17:18 -05002872static PyObject *
2873posix__isdir(PyObject *self, PyObject *args)
2874{
2875 PyObject *opath;
2876 char *path;
2877 PyUnicodeObject *po;
2878 DWORD attributes;
2879
2880 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
2881 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2882
2883 attributes = GetFileAttributesW(wpath);
2884 if (attributes == INVALID_FILE_ATTRIBUTES)
2885 Py_RETURN_FALSE;
2886 goto check;
2887 }
2888 /* Drop the argument parsing error as narrow strings
2889 are also valid. */
2890 PyErr_Clear();
2891
2892 if (!PyArg_ParseTuple(args, "O&:_isdir",
2893 PyUnicode_FSConverter, &opath))
2894 return NULL;
2895
2896 path = PyBytes_AsString(opath);
2897 attributes = GetFileAttributesA(path);
2898 if (attributes == INVALID_FILE_ATTRIBUTES)
2899 Py_RETURN_FALSE;
2900
2901check:
2902 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
2903 Py_RETURN_TRUE;
2904 else
2905 Py_RETURN_FALSE;
2906}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002907#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002908
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002909PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002910"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002911Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002912
Barry Warsaw53699e91996-12-10 23:23:01 +00002913static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002914posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002915{
Victor Stinner8c62be82010-05-06 00:08:46 +00002916 int res;
2917 PyObject *opath;
2918 char *path;
2919 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002920
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002921#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002922 PyUnicodeObject *po;
2923 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2924 Py_BEGIN_ALLOW_THREADS
2925 /* PyUnicode_AS_UNICODE OK without thread lock as
2926 it is a simple dereference. */
2927 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2928 Py_END_ALLOW_THREADS
2929 if (!res)
2930 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2931 Py_INCREF(Py_None);
2932 return Py_None;
2933 }
2934 /* Drop the argument parsing error as narrow strings
2935 are also valid. */
2936 PyErr_Clear();
2937 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2938 PyUnicode_FSConverter, &opath, &mode))
2939 return NULL;
2940 path = PyBytes_AsString(opath);
2941 Py_BEGIN_ALLOW_THREADS
2942 /* PyUnicode_AS_UNICODE OK without thread lock as
2943 it is a simple dereference. */
2944 res = CreateDirectoryA(path, NULL);
2945 Py_END_ALLOW_THREADS
2946 if (!res) {
2947 win32_error("mkdir", path);
2948 Py_DECREF(opath);
2949 return NULL;
2950 }
2951 Py_DECREF(opath);
2952 Py_INCREF(Py_None);
2953 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002954#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002955
Victor Stinner8c62be82010-05-06 00:08:46 +00002956 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2957 PyUnicode_FSConverter, &opath, &mode))
2958 return NULL;
2959 path = PyBytes_AsString(opath);
2960 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002961#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00002962 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002963#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002964 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002965#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002966 Py_END_ALLOW_THREADS
2967 if (res < 0)
2968 return posix_error_with_allocated_filename(opath);
2969 Py_DECREF(opath);
2970 Py_INCREF(Py_None);
2971 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002972#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002973}
2974
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002975
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002976/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2977#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002978#include <sys/resource.h>
2979#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002980
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002981
2982#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002983PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002984"nice(inc) -> new_priority\n\n\
2985Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002986
Barry Warsaw53699e91996-12-10 23:23:01 +00002987static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002988posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002989{
Victor Stinner8c62be82010-05-06 00:08:46 +00002990 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002991
Victor Stinner8c62be82010-05-06 00:08:46 +00002992 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2993 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002994
Victor Stinner8c62be82010-05-06 00:08:46 +00002995 /* There are two flavours of 'nice': one that returns the new
2996 priority (as required by almost all standards out there) and the
2997 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2998 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002999
Victor Stinner8c62be82010-05-06 00:08:46 +00003000 If we are of the nice family that returns the new priority, we
3001 need to clear errno before the call, and check if errno is filled
3002 before calling posix_error() on a returnvalue of -1, because the
3003 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003004
Victor Stinner8c62be82010-05-06 00:08:46 +00003005 errno = 0;
3006 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003007#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003008 if (value == 0)
3009 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003010#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003011 if (value == -1 && errno != 0)
3012 /* either nice() or getpriority() returned an error */
3013 return posix_error();
3014 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003015}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003016#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003017
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003018PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003019"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003020Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003021
Barry Warsaw53699e91996-12-10 23:23:01 +00003022static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003023posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003024{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003025#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003026 PyObject *o1, *o2;
3027 char *p1, *p2;
3028 BOOL result;
3029 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
3030 goto error;
3031 if (!convert_to_unicode(&o1))
3032 goto error;
3033 if (!convert_to_unicode(&o2)) {
3034 Py_DECREF(o1);
3035 goto error;
3036 }
3037 Py_BEGIN_ALLOW_THREADS
3038 result = MoveFileW(PyUnicode_AsUnicode(o1),
3039 PyUnicode_AsUnicode(o2));
3040 Py_END_ALLOW_THREADS
3041 Py_DECREF(o1);
3042 Py_DECREF(o2);
3043 if (!result)
3044 return win32_error("rename", NULL);
3045 Py_INCREF(Py_None);
3046 return Py_None;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003047error:
Victor Stinner8c62be82010-05-06 00:08:46 +00003048 PyErr_Clear();
3049 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
3050 return NULL;
3051 Py_BEGIN_ALLOW_THREADS
3052 result = MoveFileA(p1, p2);
3053 Py_END_ALLOW_THREADS
3054 if (!result)
3055 return win32_error("rename", NULL);
3056 Py_INCREF(Py_None);
3057 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003058#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003059 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003060#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003061}
3062
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003063
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003064PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003065"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003066Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003067
Barry Warsaw53699e91996-12-10 23:23:01 +00003068static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003069posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003070{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003071#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003072 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003073#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003074 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003075#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003076}
3077
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003078
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003079PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003080"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003081Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003082
Barry Warsaw53699e91996-12-10 23:23:01 +00003083static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003084posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003085{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003086#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00003087 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003088#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003089 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003090#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003091}
3092
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003093
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003094#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003095PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003096"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003097Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003098
Barry Warsaw53699e91996-12-10 23:23:01 +00003099static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003100posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003101{
Victor Stinner8c62be82010-05-06 00:08:46 +00003102 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00003103#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003104 wchar_t *command;
3105 if (!PyArg_ParseTuple(args, "u:system", &command))
3106 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003107
Victor Stinner8c62be82010-05-06 00:08:46 +00003108 Py_BEGIN_ALLOW_THREADS
3109 sts = _wsystem(command);
3110 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00003111#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003112 PyObject *command_obj;
3113 char *command;
3114 if (!PyArg_ParseTuple(args, "O&:system",
3115 PyUnicode_FSConverter, &command_obj))
3116 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003117
Victor Stinner8c62be82010-05-06 00:08:46 +00003118 command = PyBytes_AsString(command_obj);
3119 Py_BEGIN_ALLOW_THREADS
3120 sts = system(command);
3121 Py_END_ALLOW_THREADS
3122 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00003123#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003124 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003125}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003126#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003127
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003128
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003129PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003130"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003131Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003132
Barry Warsaw53699e91996-12-10 23:23:01 +00003133static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003134posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003135{
Victor Stinner8c62be82010-05-06 00:08:46 +00003136 int i;
3137 if (!PyArg_ParseTuple(args, "i:umask", &i))
3138 return NULL;
3139 i = (int)umask(i);
3140 if (i < 0)
3141 return posix_error();
3142 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003143}
3144
Brian Curtind40e6f72010-07-08 21:39:08 +00003145#ifdef MS_WINDOWS
3146
3147/* override the default DeleteFileW behavior so that directory
3148symlinks can be removed with this function, the same as with
3149Unix symlinks */
3150BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
3151{
3152 WIN32_FILE_ATTRIBUTE_DATA info;
3153 WIN32_FIND_DATAW find_data;
3154 HANDLE find_data_handle;
3155 int is_directory = 0;
3156 int is_link = 0;
3157
3158 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3159 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Victor Stinner26de69d2011-06-17 15:15:38 +02003160
Brian Curtind40e6f72010-07-08 21:39:08 +00003161 /* Get WIN32_FIND_DATA structure for the path to determine if
3162 it is a symlink */
3163 if(is_directory &&
3164 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3165 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3166
3167 if(find_data_handle != INVALID_HANDLE_VALUE) {
3168 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3169 FindClose(find_data_handle);
3170 }
3171 }
3172 }
3173
3174 if (is_directory && is_link)
3175 return RemoveDirectoryW(lpFileName);
3176
3177 return DeleteFileW(lpFileName);
3178}
3179#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003180
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003181PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003182"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003183Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003184
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003185PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003186"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003187Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003188
Barry Warsaw53699e91996-12-10 23:23:01 +00003189static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003190posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003191{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003192#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003193 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3194 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003195#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003196 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003197#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003198}
3199
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003200
Guido van Rossumb6775db1994-08-01 11:34:53 +00003201#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003202PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003203"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003204Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003205
Barry Warsaw53699e91996-12-10 23:23:01 +00003206static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003207posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003208{
Victor Stinner8c62be82010-05-06 00:08:46 +00003209 struct utsname u;
3210 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003211
Victor Stinner8c62be82010-05-06 00:08:46 +00003212 Py_BEGIN_ALLOW_THREADS
3213 res = uname(&u);
3214 Py_END_ALLOW_THREADS
3215 if (res < 0)
3216 return posix_error();
3217 return Py_BuildValue("(sssss)",
3218 u.sysname,
3219 u.nodename,
3220 u.release,
3221 u.version,
3222 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003223}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003224#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003225
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003226static int
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003227extract_time(PyObject *t, time_t* sec, long* usec)
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003228{
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003229 time_t intval;
Victor Stinner8c62be82010-05-06 00:08:46 +00003230 if (PyFloat_Check(t)) {
3231 double tval = PyFloat_AsDouble(t);
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003232 PyObject *intobj = PyNumber_Long(t);
Victor Stinner8c62be82010-05-06 00:08:46 +00003233 if (!intobj)
3234 return -1;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003235#if SIZEOF_TIME_T > SIZEOF_LONG
3236 intval = PyLong_AsUnsignedLongLongMask(intobj);
3237#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003238 intval = PyLong_AsLong(intobj);
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003239#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003240 Py_DECREF(intobj);
3241 if (intval == -1 && PyErr_Occurred())
3242 return -1;
3243 *sec = intval;
3244 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
3245 if (*usec < 0)
3246 /* If rounding gave us a negative number,
3247 truncate. */
3248 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00003249 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003250 }
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003251#if SIZEOF_TIME_T > SIZEOF_LONG
3252 intval = PyLong_AsUnsignedLongLongMask(t);
3253#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003254 intval = PyLong_AsLong(t);
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003255#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003256 if (intval == -1 && PyErr_Occurred())
3257 return -1;
3258 *sec = intval;
3259 *usec = 0;
3260 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003261}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003262
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003263PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00003264"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00003265utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00003266Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003267second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003268
Barry Warsaw53699e91996-12-10 23:23:01 +00003269static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003270posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003271{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003272#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003273 PyObject *arg;
3274 PyUnicodeObject *obwpath;
3275 wchar_t *wpath = NULL;
3276 PyObject *oapath;
3277 char *apath;
3278 HANDLE hFile;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003279 time_t atimesec, mtimesec;
3280 long ausec, musec;
Victor Stinner8c62be82010-05-06 00:08:46 +00003281 FILETIME atime, mtime;
3282 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003283
Victor Stinner8c62be82010-05-06 00:08:46 +00003284 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
3285 wpath = PyUnicode_AS_UNICODE(obwpath);
3286 Py_BEGIN_ALLOW_THREADS
3287 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3288 NULL, OPEN_EXISTING,
3289 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3290 Py_END_ALLOW_THREADS
3291 if (hFile == INVALID_HANDLE_VALUE)
3292 return win32_error_unicode("utime", wpath);
3293 } else
3294 /* Drop the argument parsing error as narrow strings
3295 are also valid. */
3296 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003297
Victor Stinner8c62be82010-05-06 00:08:46 +00003298 if (!wpath) {
3299 if (!PyArg_ParseTuple(args, "O&O:utime",
3300 PyUnicode_FSConverter, &oapath, &arg))
3301 return NULL;
3302 apath = PyBytes_AsString(oapath);
3303 Py_BEGIN_ALLOW_THREADS
3304 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3305 NULL, OPEN_EXISTING,
3306 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3307 Py_END_ALLOW_THREADS
3308 if (hFile == INVALID_HANDLE_VALUE) {
3309 win32_error("utime", apath);
3310 Py_DECREF(oapath);
3311 return NULL;
3312 }
3313 Py_DECREF(oapath);
3314 }
3315
3316 if (arg == Py_None) {
3317 SYSTEMTIME now;
3318 GetSystemTime(&now);
3319 if (!SystemTimeToFileTime(&now, &mtime) ||
3320 !SystemTimeToFileTime(&now, &atime)) {
3321 win32_error("utime", NULL);
3322 goto done;
Stefan Krah0e803b32010-11-26 16:16:47 +00003323 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003324 }
3325 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3326 PyErr_SetString(PyExc_TypeError,
3327 "utime() arg 2 must be a tuple (atime, mtime)");
3328 goto done;
3329 }
3330 else {
3331 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3332 &atimesec, &ausec) == -1)
3333 goto done;
3334 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3335 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3336 &mtimesec, &musec) == -1)
3337 goto done;
3338 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3339 }
3340 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3341 /* Avoid putting the file name into the error here,
3342 as that may confuse the user into believing that
3343 something is wrong with the file, when it also
3344 could be the time stamp that gives a problem. */
3345 win32_error("utime", NULL);
Antoine Pitroue85da7a2011-01-06 18:25:55 +00003346 goto done;
Victor Stinner8c62be82010-05-06 00:08:46 +00003347 }
3348 Py_INCREF(Py_None);
3349 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003350done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003351 CloseHandle(hFile);
3352 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003353#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003354
Victor Stinner8c62be82010-05-06 00:08:46 +00003355 PyObject *opath;
3356 char *path;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003357 time_t atime, mtime;
3358 long ausec, musec;
Victor Stinner8c62be82010-05-06 00:08:46 +00003359 int res;
3360 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003361
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003362#if defined(HAVE_UTIMES)
Victor Stinner8c62be82010-05-06 00:08:46 +00003363 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003364#define ATIME buf[0].tv_sec
3365#define MTIME buf[1].tv_sec
3366#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003367/* XXX should define struct utimbuf instead, above */
Victor Stinner8c62be82010-05-06 00:08:46 +00003368 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003369#define ATIME buf.actime
3370#define MTIME buf.modtime
3371#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003372#else /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003373 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003374#define ATIME buf[0]
3375#define MTIME buf[1]
3376#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003377#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003378
Mark Hammond817c9292003-12-03 01:22:38 +00003379
Victor Stinner8c62be82010-05-06 00:08:46 +00003380 if (!PyArg_ParseTuple(args, "O&O:utime",
3381 PyUnicode_FSConverter, &opath, &arg))
3382 return NULL;
3383 path = PyBytes_AsString(opath);
3384 if (arg == Py_None) {
3385 /* optional time values not given */
3386 Py_BEGIN_ALLOW_THREADS
3387 res = utime(path, NULL);
3388 Py_END_ALLOW_THREADS
3389 }
3390 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3391 PyErr_SetString(PyExc_TypeError,
3392 "utime() arg 2 must be a tuple (atime, mtime)");
3393 Py_DECREF(opath);
3394 return NULL;
3395 }
3396 else {
3397 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3398 &atime, &ausec) == -1) {
3399 Py_DECREF(opath);
3400 return NULL;
3401 }
3402 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3403 &mtime, &musec) == -1) {
3404 Py_DECREF(opath);
3405 return NULL;
3406 }
3407 ATIME = atime;
3408 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003409#ifdef HAVE_UTIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00003410 buf[0].tv_usec = ausec;
3411 buf[1].tv_usec = musec;
3412 Py_BEGIN_ALLOW_THREADS
3413 res = utimes(path, buf);
3414 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003415#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003416 Py_BEGIN_ALLOW_THREADS
3417 res = utime(path, UTIME_ARG);
3418 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003419#endif /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003420 }
3421 if (res < 0) {
3422 return posix_error_with_allocated_filename(opath);
3423 }
3424 Py_DECREF(opath);
3425 Py_INCREF(Py_None);
3426 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003427#undef UTIME_ARG
3428#undef ATIME
3429#undef MTIME
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003430#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003431}
3432
Guido van Rossum85e3b011991-06-03 12:42:10 +00003433
Guido van Rossum3b066191991-06-04 19:40:25 +00003434/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003435
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003436PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003437"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003438Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003439
Barry Warsaw53699e91996-12-10 23:23:01 +00003440static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003441posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003442{
Victor Stinner8c62be82010-05-06 00:08:46 +00003443 int sts;
3444 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3445 return NULL;
3446 _exit(sts);
3447 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003448}
3449
Martin v. Löwis114619e2002-10-07 06:44:21 +00003450#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3451static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003452free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003453{
Victor Stinner8c62be82010-05-06 00:08:46 +00003454 Py_ssize_t i;
3455 for (i = 0; i < count; i++)
3456 PyMem_Free(array[i]);
3457 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003458}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003459
Antoine Pitrou69f71142009-05-24 21:25:49 +00003460static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003461int fsconvert_strdup(PyObject *o, char**out)
3462{
Victor Stinner8c62be82010-05-06 00:08:46 +00003463 PyObject *bytes;
3464 Py_ssize_t size;
3465 if (!PyUnicode_FSConverter(o, &bytes))
3466 return 0;
3467 size = PyBytes_GET_SIZE(bytes);
3468 *out = PyMem_Malloc(size+1);
3469 if (!*out)
3470 return 0;
3471 memcpy(*out, PyBytes_AsString(bytes), size+1);
3472 Py_DECREF(bytes);
3473 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003474}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003475#endif
3476
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003477
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003478#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003479PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003480"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003481Execute an executable path with arguments, replacing current process.\n\
3482\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003483 path: path of executable file\n\
3484 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003485
Barry Warsaw53699e91996-12-10 23:23:01 +00003486static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003487posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003488{
Victor Stinner8c62be82010-05-06 00:08:46 +00003489 PyObject *opath;
3490 char *path;
3491 PyObject *argv;
3492 char **argvlist;
3493 Py_ssize_t i, argc;
3494 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003495
Victor Stinner8c62be82010-05-06 00:08:46 +00003496 /* execv has two arguments: (path, argv), where
3497 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003498
Victor Stinner8c62be82010-05-06 00:08:46 +00003499 if (!PyArg_ParseTuple(args, "O&O:execv",
3500 PyUnicode_FSConverter,
3501 &opath, &argv))
3502 return NULL;
3503 path = PyBytes_AsString(opath);
3504 if (PyList_Check(argv)) {
3505 argc = PyList_Size(argv);
3506 getitem = PyList_GetItem;
3507 }
3508 else if (PyTuple_Check(argv)) {
3509 argc = PyTuple_Size(argv);
3510 getitem = PyTuple_GetItem;
3511 }
3512 else {
3513 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3514 Py_DECREF(opath);
3515 return NULL;
3516 }
3517 if (argc < 1) {
3518 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3519 Py_DECREF(opath);
3520 return NULL;
3521 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003522
Victor Stinner8c62be82010-05-06 00:08:46 +00003523 argvlist = PyMem_NEW(char *, argc+1);
3524 if (argvlist == NULL) {
3525 Py_DECREF(opath);
3526 return PyErr_NoMemory();
3527 }
3528 for (i = 0; i < argc; i++) {
3529 if (!fsconvert_strdup((*getitem)(argv, i),
3530 &argvlist[i])) {
3531 free_string_array(argvlist, i);
3532 PyErr_SetString(PyExc_TypeError,
3533 "execv() arg 2 must contain only strings");
3534 Py_DECREF(opath);
3535 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003536
Victor Stinner8c62be82010-05-06 00:08:46 +00003537 }
3538 }
3539 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003540
Victor Stinner8c62be82010-05-06 00:08:46 +00003541 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003542
Victor Stinner8c62be82010-05-06 00:08:46 +00003543 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003544
Victor Stinner8c62be82010-05-06 00:08:46 +00003545 free_string_array(argvlist, argc);
3546 Py_DECREF(opath);
3547 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003548}
3549
Victor Stinner13bb71c2010-04-23 21:41:56 +00003550static char**
3551parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3552{
Victor Stinner8c62be82010-05-06 00:08:46 +00003553 char **envlist;
3554 Py_ssize_t i, pos, envc;
3555 PyObject *keys=NULL, *vals=NULL;
3556 PyObject *key, *val, *key2, *val2;
3557 char *p, *k, *v;
3558 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003559
Victor Stinner8c62be82010-05-06 00:08:46 +00003560 i = PyMapping_Size(env);
3561 if (i < 0)
3562 return NULL;
3563 envlist = PyMem_NEW(char *, i + 1);
3564 if (envlist == NULL) {
3565 PyErr_NoMemory();
3566 return NULL;
3567 }
3568 envc = 0;
3569 keys = PyMapping_Keys(env);
3570 vals = PyMapping_Values(env);
3571 if (!keys || !vals)
3572 goto error;
3573 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3574 PyErr_Format(PyExc_TypeError,
3575 "env.keys() or env.values() is not a list");
3576 goto error;
3577 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003578
Victor Stinner8c62be82010-05-06 00:08:46 +00003579 for (pos = 0; pos < i; pos++) {
3580 key = PyList_GetItem(keys, pos);
3581 val = PyList_GetItem(vals, pos);
3582 if (!key || !val)
3583 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003584
Victor Stinner8c62be82010-05-06 00:08:46 +00003585 if (PyUnicode_FSConverter(key, &key2) == 0)
3586 goto error;
3587 if (PyUnicode_FSConverter(val, &val2) == 0) {
3588 Py_DECREF(key2);
3589 goto error;
3590 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003591
3592#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003593 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3594 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00003595#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003596 k = PyBytes_AsString(key2);
3597 v = PyBytes_AsString(val2);
3598 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003599
Victor Stinner8c62be82010-05-06 00:08:46 +00003600 p = PyMem_NEW(char, len);
3601 if (p == NULL) {
3602 PyErr_NoMemory();
3603 Py_DECREF(key2);
3604 Py_DECREF(val2);
3605 goto error;
3606 }
3607 PyOS_snprintf(p, len, "%s=%s", k, v);
3608 envlist[envc++] = p;
3609 Py_DECREF(key2);
3610 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003611#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003612 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003613#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003614 }
3615 Py_DECREF(vals);
3616 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003617
Victor Stinner8c62be82010-05-06 00:08:46 +00003618 envlist[envc] = 0;
3619 *envc_ptr = envc;
3620 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003621
3622error:
Victor Stinner8c62be82010-05-06 00:08:46 +00003623 Py_XDECREF(keys);
3624 Py_XDECREF(vals);
3625 while (--envc >= 0)
3626 PyMem_DEL(envlist[envc]);
3627 PyMem_DEL(envlist);
3628 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003629}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003630
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003631PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003632"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003633Execute a path with arguments and environment, replacing current process.\n\
3634\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003635 path: path of executable file\n\
3636 args: tuple or list of arguments\n\
3637 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003638
Barry Warsaw53699e91996-12-10 23:23:01 +00003639static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003640posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003641{
Victor Stinner8c62be82010-05-06 00:08:46 +00003642 PyObject *opath;
3643 char *path;
3644 PyObject *argv, *env;
3645 char **argvlist;
3646 char **envlist;
3647 Py_ssize_t i, argc, envc;
3648 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3649 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003650
Victor Stinner8c62be82010-05-06 00:08:46 +00003651 /* execve has three arguments: (path, argv, env), where
3652 argv is a list or tuple of strings and env is a dictionary
3653 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003654
Victor Stinner8c62be82010-05-06 00:08:46 +00003655 if (!PyArg_ParseTuple(args, "O&OO:execve",
3656 PyUnicode_FSConverter,
3657 &opath, &argv, &env))
3658 return NULL;
3659 path = PyBytes_AsString(opath);
3660 if (PyList_Check(argv)) {
3661 argc = PyList_Size(argv);
3662 getitem = PyList_GetItem;
3663 }
3664 else if (PyTuple_Check(argv)) {
3665 argc = PyTuple_Size(argv);
3666 getitem = PyTuple_GetItem;
3667 }
3668 else {
3669 PyErr_SetString(PyExc_TypeError,
3670 "execve() arg 2 must be a tuple or list");
3671 goto fail_0;
3672 }
3673 if (!PyMapping_Check(env)) {
3674 PyErr_SetString(PyExc_TypeError,
3675 "execve() arg 3 must be a mapping object");
3676 goto fail_0;
3677 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003678
Victor Stinner8c62be82010-05-06 00:08:46 +00003679 argvlist = PyMem_NEW(char *, argc+1);
3680 if (argvlist == NULL) {
3681 PyErr_NoMemory();
3682 goto fail_0;
3683 }
3684 for (i = 0; i < argc; i++) {
3685 if (!fsconvert_strdup((*getitem)(argv, i),
3686 &argvlist[i]))
3687 {
3688 lastarg = i;
3689 goto fail_1;
3690 }
3691 }
3692 lastarg = argc;
3693 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003694
Victor Stinner8c62be82010-05-06 00:08:46 +00003695 envlist = parse_envlist(env, &envc);
3696 if (envlist == NULL)
3697 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003698
Victor Stinner8c62be82010-05-06 00:08:46 +00003699 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003700
Victor Stinner8c62be82010-05-06 00:08:46 +00003701 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003702
Victor Stinner8c62be82010-05-06 00:08:46 +00003703 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003704
Victor Stinner8c62be82010-05-06 00:08:46 +00003705 while (--envc >= 0)
3706 PyMem_DEL(envlist[envc]);
3707 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003708 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003709 free_string_array(argvlist, lastarg);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003710 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003711 Py_DECREF(opath);
3712 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003713}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003714#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003715
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003716
Guido van Rossuma1065681999-01-25 23:20:23 +00003717#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003718PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003719"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003720Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003721\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003722 mode: mode of process creation\n\
3723 path: path of executable file\n\
3724 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003725
3726static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003727posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003728{
Victor Stinner8c62be82010-05-06 00:08:46 +00003729 PyObject *opath;
3730 char *path;
3731 PyObject *argv;
3732 char **argvlist;
3733 int mode, i;
3734 Py_ssize_t argc;
3735 Py_intptr_t spawnval;
3736 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003737
Victor Stinner8c62be82010-05-06 00:08:46 +00003738 /* spawnv has three arguments: (mode, path, argv), where
3739 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003740
Victor Stinner8c62be82010-05-06 00:08:46 +00003741 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3742 PyUnicode_FSConverter,
3743 &opath, &argv))
3744 return NULL;
3745 path = PyBytes_AsString(opath);
3746 if (PyList_Check(argv)) {
3747 argc = PyList_Size(argv);
3748 getitem = PyList_GetItem;
3749 }
3750 else if (PyTuple_Check(argv)) {
3751 argc = PyTuple_Size(argv);
3752 getitem = PyTuple_GetItem;
3753 }
3754 else {
3755 PyErr_SetString(PyExc_TypeError,
3756 "spawnv() arg 2 must be a tuple or list");
3757 Py_DECREF(opath);
3758 return NULL;
3759 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003760
Victor Stinner8c62be82010-05-06 00:08:46 +00003761 argvlist = PyMem_NEW(char *, argc+1);
3762 if (argvlist == NULL) {
3763 Py_DECREF(opath);
3764 return PyErr_NoMemory();
3765 }
3766 for (i = 0; i < argc; i++) {
3767 if (!fsconvert_strdup((*getitem)(argv, i),
3768 &argvlist[i])) {
3769 free_string_array(argvlist, i);
3770 PyErr_SetString(
3771 PyExc_TypeError,
3772 "spawnv() arg 2 must contain only strings");
3773 Py_DECREF(opath);
3774 return NULL;
3775 }
3776 }
3777 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003778
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003779#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003780 Py_BEGIN_ALLOW_THREADS
3781 spawnval = spawnv(mode, path, argvlist);
3782 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003783#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003784 if (mode == _OLD_P_OVERLAY)
3785 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003786
Victor Stinner8c62be82010-05-06 00:08:46 +00003787 Py_BEGIN_ALLOW_THREADS
3788 spawnval = _spawnv(mode, path, argvlist);
3789 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003790#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003791
Victor Stinner8c62be82010-05-06 00:08:46 +00003792 free_string_array(argvlist, argc);
3793 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003794
Victor Stinner8c62be82010-05-06 00:08:46 +00003795 if (spawnval == -1)
3796 return posix_error();
3797 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003798#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003799 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003800#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003801 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003802#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003803}
3804
3805
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003806PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003807"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003808Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003809\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003810 mode: mode of process creation\n\
3811 path: path of executable file\n\
3812 args: tuple or list of arguments\n\
3813 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003814
3815static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003816posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003817{
Victor Stinner8c62be82010-05-06 00:08:46 +00003818 PyObject *opath;
3819 char *path;
3820 PyObject *argv, *env;
3821 char **argvlist;
3822 char **envlist;
3823 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003824 int mode;
3825 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003826 Py_intptr_t spawnval;
3827 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3828 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003829
Victor Stinner8c62be82010-05-06 00:08:46 +00003830 /* spawnve has four arguments: (mode, path, argv, env), where
3831 argv is a list or tuple of strings and env is a dictionary
3832 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003833
Victor Stinner8c62be82010-05-06 00:08:46 +00003834 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3835 PyUnicode_FSConverter,
3836 &opath, &argv, &env))
3837 return NULL;
3838 path = PyBytes_AsString(opath);
3839 if (PyList_Check(argv)) {
3840 argc = PyList_Size(argv);
3841 getitem = PyList_GetItem;
3842 }
3843 else if (PyTuple_Check(argv)) {
3844 argc = PyTuple_Size(argv);
3845 getitem = PyTuple_GetItem;
3846 }
3847 else {
3848 PyErr_SetString(PyExc_TypeError,
3849 "spawnve() arg 2 must be a tuple or list");
3850 goto fail_0;
3851 }
3852 if (!PyMapping_Check(env)) {
3853 PyErr_SetString(PyExc_TypeError,
3854 "spawnve() arg 3 must be a mapping object");
3855 goto fail_0;
3856 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003857
Victor Stinner8c62be82010-05-06 00:08:46 +00003858 argvlist = PyMem_NEW(char *, argc+1);
3859 if (argvlist == NULL) {
3860 PyErr_NoMemory();
3861 goto fail_0;
3862 }
3863 for (i = 0; i < argc; i++) {
3864 if (!fsconvert_strdup((*getitem)(argv, i),
3865 &argvlist[i]))
3866 {
3867 lastarg = i;
3868 goto fail_1;
3869 }
3870 }
3871 lastarg = argc;
3872 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003873
Victor Stinner8c62be82010-05-06 00:08:46 +00003874 envlist = parse_envlist(env, &envc);
3875 if (envlist == NULL)
3876 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003877
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003878#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003879 Py_BEGIN_ALLOW_THREADS
3880 spawnval = spawnve(mode, path, argvlist, envlist);
3881 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003882#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003883 if (mode == _OLD_P_OVERLAY)
3884 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003885
Victor Stinner8c62be82010-05-06 00:08:46 +00003886 Py_BEGIN_ALLOW_THREADS
3887 spawnval = _spawnve(mode, path, argvlist, envlist);
3888 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003889#endif
Tim Peters25059d32001-12-07 20:35:43 +00003890
Victor Stinner8c62be82010-05-06 00:08:46 +00003891 if (spawnval == -1)
3892 (void) posix_error();
3893 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003894#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003895 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003896#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003897 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003898#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003899
Victor Stinner8c62be82010-05-06 00:08:46 +00003900 while (--envc >= 0)
3901 PyMem_DEL(envlist[envc]);
3902 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003903 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003904 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003905 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003906 Py_DECREF(opath);
3907 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003908}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003909
3910/* OS/2 supports spawnvp & spawnvpe natively */
3911#if defined(PYOS_OS2)
3912PyDoc_STRVAR(posix_spawnvp__doc__,
3913"spawnvp(mode, file, args)\n\n\
3914Execute the program 'file' in a new process, using the environment\n\
3915search path to find the file.\n\
3916\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003917 mode: mode of process creation\n\
3918 file: executable file name\n\
3919 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003920
3921static PyObject *
3922posix_spawnvp(PyObject *self, PyObject *args)
3923{
Victor Stinner8c62be82010-05-06 00:08:46 +00003924 PyObject *opath;
3925 char *path;
3926 PyObject *argv;
3927 char **argvlist;
3928 int mode, i, argc;
3929 Py_intptr_t spawnval;
3930 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003931
Victor Stinner8c62be82010-05-06 00:08:46 +00003932 /* spawnvp has three arguments: (mode, path, argv), where
3933 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003934
Victor Stinner8c62be82010-05-06 00:08:46 +00003935 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3936 PyUnicode_FSConverter,
3937 &opath, &argv))
3938 return NULL;
3939 path = PyBytes_AsString(opath);
3940 if (PyList_Check(argv)) {
3941 argc = PyList_Size(argv);
3942 getitem = PyList_GetItem;
3943 }
3944 else if (PyTuple_Check(argv)) {
3945 argc = PyTuple_Size(argv);
3946 getitem = PyTuple_GetItem;
3947 }
3948 else {
3949 PyErr_SetString(PyExc_TypeError,
3950 "spawnvp() arg 2 must be a tuple or list");
3951 Py_DECREF(opath);
3952 return NULL;
3953 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003954
Victor Stinner8c62be82010-05-06 00:08:46 +00003955 argvlist = PyMem_NEW(char *, argc+1);
3956 if (argvlist == NULL) {
3957 Py_DECREF(opath);
3958 return PyErr_NoMemory();
3959 }
3960 for (i = 0; i < argc; i++) {
3961 if (!fsconvert_strdup((*getitem)(argv, i),
3962 &argvlist[i])) {
3963 free_string_array(argvlist, i);
3964 PyErr_SetString(
3965 PyExc_TypeError,
3966 "spawnvp() arg 2 must contain only strings");
3967 Py_DECREF(opath);
3968 return NULL;
3969 }
3970 }
3971 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003972
Victor Stinner8c62be82010-05-06 00:08:46 +00003973 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003974#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003975 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003976#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003977 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003978#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003979 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003980
Victor Stinner8c62be82010-05-06 00:08:46 +00003981 free_string_array(argvlist, argc);
3982 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003983
Victor Stinner8c62be82010-05-06 00:08:46 +00003984 if (spawnval == -1)
3985 return posix_error();
3986 else
3987 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003988}
3989
3990
3991PyDoc_STRVAR(posix_spawnvpe__doc__,
3992"spawnvpe(mode, file, args, env)\n\n\
3993Execute the program 'file' in a new process, using the environment\n\
3994search path to find the file.\n\
3995\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003996 mode: mode of process creation\n\
3997 file: executable file name\n\
3998 args: tuple or list of arguments\n\
3999 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004000
4001static PyObject *
4002posix_spawnvpe(PyObject *self, PyObject *args)
4003{
Victor Stinner8c62be82010-05-06 00:08:46 +00004004 PyObject *opath
4005 char *path;
4006 PyObject *argv, *env;
4007 char **argvlist;
4008 char **envlist;
4009 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004010 int mode;
4011 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004012 Py_intptr_t spawnval;
4013 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4014 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004015
Victor Stinner8c62be82010-05-06 00:08:46 +00004016 /* spawnvpe has four arguments: (mode, path, argv, env), where
4017 argv is a list or tuple of strings and env is a dictionary
4018 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004019
Victor Stinner8c62be82010-05-06 00:08:46 +00004020 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
4021 PyUnicode_FSConverter,
4022 &opath, &argv, &env))
4023 return NULL;
4024 path = PyBytes_AsString(opath);
4025 if (PyList_Check(argv)) {
4026 argc = PyList_Size(argv);
4027 getitem = PyList_GetItem;
4028 }
4029 else if (PyTuple_Check(argv)) {
4030 argc = PyTuple_Size(argv);
4031 getitem = PyTuple_GetItem;
4032 }
4033 else {
4034 PyErr_SetString(PyExc_TypeError,
4035 "spawnvpe() arg 2 must be a tuple or list");
4036 goto fail_0;
4037 }
4038 if (!PyMapping_Check(env)) {
4039 PyErr_SetString(PyExc_TypeError,
4040 "spawnvpe() arg 3 must be a mapping object");
4041 goto fail_0;
4042 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004043
Victor Stinner8c62be82010-05-06 00:08:46 +00004044 argvlist = PyMem_NEW(char *, argc+1);
4045 if (argvlist == NULL) {
4046 PyErr_NoMemory();
4047 goto fail_0;
4048 }
4049 for (i = 0; i < argc; i++) {
4050 if (!fsconvert_strdup((*getitem)(argv, i),
4051 &argvlist[i]))
4052 {
4053 lastarg = i;
4054 goto fail_1;
4055 }
4056 }
4057 lastarg = argc;
4058 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004059
Victor Stinner8c62be82010-05-06 00:08:46 +00004060 envlist = parse_envlist(env, &envc);
4061 if (envlist == NULL)
4062 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004063
Victor Stinner8c62be82010-05-06 00:08:46 +00004064 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004065#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004066 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004067#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004068 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004069#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004070 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004071
Victor Stinner8c62be82010-05-06 00:08:46 +00004072 if (spawnval == -1)
4073 (void) posix_error();
4074 else
4075 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004076
Victor Stinner8c62be82010-05-06 00:08:46 +00004077 while (--envc >= 0)
4078 PyMem_DEL(envlist[envc]);
4079 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004080 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004081 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004082 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004083 Py_DECREF(opath);
4084 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004085}
4086#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00004087#endif /* HAVE_SPAWNV */
4088
4089
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004090#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004091PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004092"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004093Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
4094\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004095Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004096
4097static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004098posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004099{
Victor Stinner8c62be82010-05-06 00:08:46 +00004100 pid_t pid;
4101 int result = 0;
4102 _PyImport_AcquireLock();
4103 pid = fork1();
4104 if (pid == 0) {
4105 /* child: this clobbers and resets the import lock. */
4106 PyOS_AfterFork();
4107 } else {
4108 /* parent: release the import lock. */
4109 result = _PyImport_ReleaseLock();
4110 }
4111 if (pid == -1)
4112 return posix_error();
4113 if (result < 0) {
4114 /* Don't clobber the OSError if the fork failed. */
4115 PyErr_SetString(PyExc_RuntimeError,
4116 "not holding the import lock");
4117 return NULL;
4118 }
4119 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004120}
4121#endif
4122
4123
Guido van Rossumad0ee831995-03-01 10:34:45 +00004124#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004125PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004126"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004127Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004128Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004129
Barry Warsaw53699e91996-12-10 23:23:01 +00004130static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004131posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004132{
Victor Stinner8c62be82010-05-06 00:08:46 +00004133 pid_t pid;
4134 int result = 0;
4135 _PyImport_AcquireLock();
4136 pid = fork();
4137 if (pid == 0) {
4138 /* child: this clobbers and resets the import lock. */
4139 PyOS_AfterFork();
4140 } else {
4141 /* parent: release the import lock. */
4142 result = _PyImport_ReleaseLock();
4143 }
4144 if (pid == -1)
4145 return posix_error();
4146 if (result < 0) {
4147 /* Don't clobber the OSError if the fork failed. */
4148 PyErr_SetString(PyExc_RuntimeError,
4149 "not holding the import lock");
4150 return NULL;
4151 }
4152 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00004153}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004154#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004155
Neal Norwitzb59798b2003-03-21 01:43:31 +00004156/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00004157/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
4158#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00004159#define DEV_PTY_FILE "/dev/ptc"
4160#define HAVE_DEV_PTMX
4161#else
4162#define DEV_PTY_FILE "/dev/ptmx"
4163#endif
4164
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004165#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004166#ifdef HAVE_PTY_H
4167#include <pty.h>
4168#else
4169#ifdef HAVE_LIBUTIL_H
4170#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00004171#else
4172#ifdef HAVE_UTIL_H
4173#include <util.h>
4174#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004175#endif /* HAVE_LIBUTIL_H */
4176#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00004177#ifdef HAVE_STROPTS_H
4178#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004179#endif
4180#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004181
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004182#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004183PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004184"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004185Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004186
4187static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004188posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004189{
Victor Stinner8c62be82010-05-06 00:08:46 +00004190 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004191#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004192 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004193#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004194#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004195 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004196#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00004197 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004198#endif
4199#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00004200
Thomas Wouters70c21a12000-07-14 14:28:33 +00004201#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004202 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
4203 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004204#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004205 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
4206 if (slave_name == NULL)
4207 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00004208
Victor Stinner8c62be82010-05-06 00:08:46 +00004209 slave_fd = open(slave_name, O_RDWR);
4210 if (slave_fd < 0)
4211 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004212#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004213 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
4214 if (master_fd < 0)
4215 return posix_error();
4216 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
4217 /* change permission of slave */
4218 if (grantpt(master_fd) < 0) {
4219 PyOS_setsig(SIGCHLD, sig_saved);
4220 return posix_error();
4221 }
4222 /* unlock slave */
4223 if (unlockpt(master_fd) < 0) {
4224 PyOS_setsig(SIGCHLD, sig_saved);
4225 return posix_error();
4226 }
4227 PyOS_setsig(SIGCHLD, sig_saved);
4228 slave_name = ptsname(master_fd); /* get name of slave */
4229 if (slave_name == NULL)
4230 return posix_error();
4231 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
4232 if (slave_fd < 0)
4233 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004234#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004235 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
4236 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00004237#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00004238 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00004239#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004240#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00004241#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00004242
Victor Stinner8c62be82010-05-06 00:08:46 +00004243 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00004244
Fred Drake8cef4cf2000-06-28 16:40:38 +00004245}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004246#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004247
4248#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004249PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004250"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00004251Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
4252Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004253To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004254
4255static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004256posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004257{
Victor Stinner8c62be82010-05-06 00:08:46 +00004258 int master_fd = -1, result = 0;
4259 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00004260
Victor Stinner8c62be82010-05-06 00:08:46 +00004261 _PyImport_AcquireLock();
4262 pid = forkpty(&master_fd, NULL, NULL, NULL);
4263 if (pid == 0) {
4264 /* child: this clobbers and resets the import lock. */
4265 PyOS_AfterFork();
4266 } else {
4267 /* parent: release the import lock. */
4268 result = _PyImport_ReleaseLock();
4269 }
4270 if (pid == -1)
4271 return posix_error();
4272 if (result < 0) {
4273 /* Don't clobber the OSError if the fork failed. */
4274 PyErr_SetString(PyExc_RuntimeError,
4275 "not holding the import lock");
4276 return NULL;
4277 }
4278 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004279}
4280#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004281
Guido van Rossumad0ee831995-03-01 10:34:45 +00004282#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004283PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004284"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004285Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004286
Barry Warsaw53699e91996-12-10 23:23:01 +00004287static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004288posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004289{
Victor Stinner8c62be82010-05-06 00:08:46 +00004290 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004291}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004292#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004293
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004294
Guido van Rossumad0ee831995-03-01 10:34:45 +00004295#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004296PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004297"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004298Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004299
Barry Warsaw53699e91996-12-10 23:23:01 +00004300static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004301posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004302{
Victor Stinner8c62be82010-05-06 00:08:46 +00004303 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004304}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004305#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004306
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004307
Guido van Rossumad0ee831995-03-01 10:34:45 +00004308#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004309PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004310"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004311Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004312
Barry Warsaw53699e91996-12-10 23:23:01 +00004313static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004314posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004315{
Victor Stinner8c62be82010-05-06 00:08:46 +00004316 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004317}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004318#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004319
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004320
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004321PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004322"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004323Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004324
Barry Warsaw53699e91996-12-10 23:23:01 +00004325static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004326posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004327{
Victor Stinner8c62be82010-05-06 00:08:46 +00004328 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004329}
4330
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004331
Fred Drakec9680921999-12-13 16:37:25 +00004332#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004333PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004334"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004335Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004336
4337static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004338posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004339{
4340 PyObject *result = NULL;
4341
Fred Drakec9680921999-12-13 16:37:25 +00004342#ifdef NGROUPS_MAX
4343#define MAX_GROUPS NGROUPS_MAX
4344#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004345 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004346#define MAX_GROUPS 64
4347#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004348 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004349
Victor Stinner26de69d2011-06-17 15:15:38 +02004350 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004351 * This is a helper variable to store the intermediate result when
4352 * that happens.
4353 *
4354 * To keep the code readable the OSX behaviour is unconditional,
4355 * according to the POSIX spec this should be safe on all unix-y
4356 * systems.
4357 */
4358 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00004359 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004360
Victor Stinner8c62be82010-05-06 00:08:46 +00004361 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004362 if (n < 0) {
4363 if (errno == EINVAL) {
4364 n = getgroups(0, NULL);
4365 if (n == -1) {
4366 return posix_error();
4367 }
4368 if (n == 0) {
4369 /* Avoid malloc(0) */
4370 alt_grouplist = grouplist;
4371 } else {
4372 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4373 if (alt_grouplist == NULL) {
4374 errno = EINVAL;
4375 return posix_error();
4376 }
4377 n = getgroups(n, alt_grouplist);
4378 if (n == -1) {
4379 PyMem_Free(alt_grouplist);
4380 return posix_error();
4381 }
4382 }
4383 } else {
4384 return posix_error();
4385 }
4386 }
4387 result = PyList_New(n);
4388 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004389 int i;
4390 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004391 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00004392 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00004393 Py_DECREF(result);
4394 result = NULL;
4395 break;
Fred Drakec9680921999-12-13 16:37:25 +00004396 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004397 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004398 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004399 }
4400
4401 if (alt_grouplist != grouplist) {
4402 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00004403 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004404
Fred Drakec9680921999-12-13 16:37:25 +00004405 return result;
4406}
4407#endif
4408
Antoine Pitroub7572f02009-12-02 20:46:48 +00004409#ifdef HAVE_INITGROUPS
4410PyDoc_STRVAR(posix_initgroups__doc__,
4411"initgroups(username, gid) -> None\n\n\
4412Call the system initgroups() to initialize the group access list with all of\n\
4413the groups of which the specified username is a member, plus the specified\n\
4414group id.");
4415
4416static PyObject *
4417posix_initgroups(PyObject *self, PyObject *args)
4418{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004419 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00004420 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004421 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00004422 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004423
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004424 if (!PyArg_ParseTuple(args, "O&l:initgroups",
4425 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00004426 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004427 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004428
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004429 res = initgroups(username, (gid_t) gid);
4430 Py_DECREF(oname);
4431 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00004432 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004433
Victor Stinner8c62be82010-05-06 00:08:46 +00004434 Py_INCREF(Py_None);
4435 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004436}
4437#endif
4438
Martin v. Löwis606edc12002-06-13 21:09:11 +00004439#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004440PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004441"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004442Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004443
4444static PyObject *
4445posix_getpgid(PyObject *self, PyObject *args)
4446{
Victor Stinner8c62be82010-05-06 00:08:46 +00004447 pid_t pid, pgid;
4448 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
4449 return NULL;
4450 pgid = getpgid(pid);
4451 if (pgid < 0)
4452 return posix_error();
4453 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004454}
4455#endif /* HAVE_GETPGID */
4456
4457
Guido van Rossumb6775db1994-08-01 11:34:53 +00004458#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004459PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004460"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004461Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004462
Barry Warsaw53699e91996-12-10 23:23:01 +00004463static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004464posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004465{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004466#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004467 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004468#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004469 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004470#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004471}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004472#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004473
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004474
Guido van Rossumb6775db1994-08-01 11:34:53 +00004475#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004476PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004477"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00004478Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004479
Barry Warsaw53699e91996-12-10 23:23:01 +00004480static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004481posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004482{
Guido van Rossum64933891994-10-20 21:56:42 +00004483#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004484 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004485#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004486 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004487#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004488 return posix_error();
4489 Py_INCREF(Py_None);
4490 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004491}
4492
Guido van Rossumb6775db1994-08-01 11:34:53 +00004493#endif /* HAVE_SETPGRP */
4494
Guido van Rossumad0ee831995-03-01 10:34:45 +00004495#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004496
4497#ifdef MS_WINDOWS
4498#include <tlhelp32.h>
4499
4500static PyObject*
4501win32_getppid()
4502{
4503 HANDLE snapshot;
4504 pid_t mypid;
4505 PyObject* result = NULL;
4506 BOOL have_record;
4507 PROCESSENTRY32 pe;
4508
4509 mypid = getpid(); /* This function never fails */
4510
4511 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
4512 if (snapshot == INVALID_HANDLE_VALUE)
4513 return PyErr_SetFromWindowsErr(GetLastError());
4514
4515 pe.dwSize = sizeof(pe);
4516 have_record = Process32First(snapshot, &pe);
4517 while (have_record) {
4518 if (mypid == (pid_t)pe.th32ProcessID) {
4519 /* We could cache the ulong value in a static variable. */
4520 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
4521 break;
4522 }
4523
4524 have_record = Process32Next(snapshot, &pe);
4525 }
4526
4527 /* If our loop exits and our pid was not found (result will be NULL)
4528 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
4529 * error anyway, so let's raise it. */
4530 if (!result)
4531 result = PyErr_SetFromWindowsErr(GetLastError());
4532
4533 CloseHandle(snapshot);
4534
4535 return result;
4536}
4537#endif /*MS_WINDOWS*/
4538
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004539PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004540"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004541Return the parent's process id. If the parent process has already exited,\n\
4542Windows machines will still return its id; others systems will return the id\n\
4543of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004544
Barry Warsaw53699e91996-12-10 23:23:01 +00004545static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004546posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004547{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004548#ifdef MS_WINDOWS
4549 return win32_getppid();
4550#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004551 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00004552#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004553}
4554#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004555
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004556
Fred Drake12c6e2d1999-12-14 21:25:03 +00004557#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004558PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004559"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004560Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004561
4562static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004563posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004564{
Victor Stinner8c62be82010-05-06 00:08:46 +00004565 PyObject *result = NULL;
Victor Stinner26de69d2011-06-17 15:15:38 +02004566#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004567 wchar_t user_name[UNLEN + 1];
4568 DWORD num_chars = sizeof(user_name)/sizeof(user_name[0]);
4569
4570 if (GetUserNameW(user_name, &num_chars)) {
4571 /* num_chars is the number of unicode chars plus null terminator */
4572 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Victor Stinner26de69d2011-06-17 15:15:38 +02004573 }
4574 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004575 result = PyErr_SetFromWindowsErr(GetLastError());
4576#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004577 char *name;
4578 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004579
Victor Stinner8c62be82010-05-06 00:08:46 +00004580 errno = 0;
4581 name = getlogin();
4582 if (name == NULL) {
4583 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00004584 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004585 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004586 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00004587 }
4588 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004589 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00004590 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004591#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00004592 return result;
4593}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004594#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00004595
Guido van Rossumad0ee831995-03-01 10:34:45 +00004596#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004597PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004598"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004599Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004600
Barry Warsaw53699e91996-12-10 23:23:01 +00004601static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004602posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004603{
Victor Stinner8c62be82010-05-06 00:08:46 +00004604 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004605}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004606#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004607
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004608
Guido van Rossumad0ee831995-03-01 10:34:45 +00004609#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004610PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004611"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004612Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004613
Barry Warsaw53699e91996-12-10 23:23:01 +00004614static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004615posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004616{
Victor Stinner8c62be82010-05-06 00:08:46 +00004617 pid_t pid;
4618 int sig;
4619 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
4620 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004621#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004622 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4623 APIRET rc;
4624 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004625 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004626
4627 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4628 APIRET rc;
4629 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004630 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004631
4632 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004633 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004634#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004635 if (kill(pid, sig) == -1)
4636 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004637#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004638 Py_INCREF(Py_None);
4639 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004640}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004641#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004642
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004643#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004644PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004645"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004646Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004647
4648static PyObject *
4649posix_killpg(PyObject *self, PyObject *args)
4650{
Victor Stinner8c62be82010-05-06 00:08:46 +00004651 int sig;
4652 pid_t pgid;
4653 /* XXX some man pages make the `pgid` parameter an int, others
4654 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4655 take the same type. Moreover, pid_t is always at least as wide as
4656 int (else compilation of this module fails), which is safe. */
4657 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
4658 return NULL;
4659 if (killpg(pgid, sig) == -1)
4660 return posix_error();
4661 Py_INCREF(Py_None);
4662 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004663}
4664#endif
4665
Brian Curtineb24d742010-04-12 17:16:38 +00004666#ifdef MS_WINDOWS
4667PyDoc_STRVAR(win32_kill__doc__,
4668"kill(pid, sig)\n\n\
4669Kill a process with a signal.");
4670
4671static PyObject *
4672win32_kill(PyObject *self, PyObject *args)
4673{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00004674 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004675 DWORD pid, sig, err;
4676 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00004677
Victor Stinner8c62be82010-05-06 00:08:46 +00004678 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4679 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00004680
Victor Stinner8c62be82010-05-06 00:08:46 +00004681 /* Console processes which share a common console can be sent CTRL+C or
4682 CTRL+BREAK events, provided they handle said events. */
4683 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4684 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4685 err = GetLastError();
4686 PyErr_SetFromWindowsErr(err);
4687 }
4688 else
4689 Py_RETURN_NONE;
4690 }
Brian Curtineb24d742010-04-12 17:16:38 +00004691
Victor Stinner8c62be82010-05-06 00:08:46 +00004692 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4693 attempt to open and terminate the process. */
4694 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4695 if (handle == NULL) {
4696 err = GetLastError();
4697 return PyErr_SetFromWindowsErr(err);
4698 }
Brian Curtineb24d742010-04-12 17:16:38 +00004699
Victor Stinner8c62be82010-05-06 00:08:46 +00004700 if (TerminateProcess(handle, sig) == 0) {
4701 err = GetLastError();
4702 result = PyErr_SetFromWindowsErr(err);
4703 } else {
4704 Py_INCREF(Py_None);
4705 result = Py_None;
4706 }
Brian Curtineb24d742010-04-12 17:16:38 +00004707
Victor Stinner8c62be82010-05-06 00:08:46 +00004708 CloseHandle(handle);
4709 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00004710}
4711#endif /* MS_WINDOWS */
4712
Guido van Rossumc0125471996-06-28 18:55:32 +00004713#ifdef HAVE_PLOCK
4714
4715#ifdef HAVE_SYS_LOCK_H
4716#include <sys/lock.h>
4717#endif
4718
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004719PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004720"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004721Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004722
Barry Warsaw53699e91996-12-10 23:23:01 +00004723static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004724posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004725{
Victor Stinner8c62be82010-05-06 00:08:46 +00004726 int op;
4727 if (!PyArg_ParseTuple(args, "i:plock", &op))
4728 return NULL;
4729 if (plock(op) == -1)
4730 return posix_error();
4731 Py_INCREF(Py_None);
4732 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004733}
4734#endif
4735
Guido van Rossumb6775db1994-08-01 11:34:53 +00004736#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004737PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004738"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004739Set the current process's user id.");
4740
Barry Warsaw53699e91996-12-10 23:23:01 +00004741static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004742posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004743{
Victor Stinner8c62be82010-05-06 00:08:46 +00004744 long uid_arg;
4745 uid_t uid;
4746 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
4747 return NULL;
4748 uid = uid_arg;
4749 if (uid != uid_arg) {
4750 PyErr_SetString(PyExc_OverflowError, "user id too big");
4751 return NULL;
4752 }
4753 if (setuid(uid) < 0)
4754 return posix_error();
4755 Py_INCREF(Py_None);
4756 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004757}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004758#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004759
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004760
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004761#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004762PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004763"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004764Set the current process's effective user id.");
4765
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004766static PyObject *
4767posix_seteuid (PyObject *self, PyObject *args)
4768{
Victor Stinner8c62be82010-05-06 00:08:46 +00004769 long euid_arg;
4770 uid_t euid;
4771 if (!PyArg_ParseTuple(args, "l", &euid_arg))
4772 return NULL;
4773 euid = euid_arg;
4774 if (euid != euid_arg) {
4775 PyErr_SetString(PyExc_OverflowError, "user id too big");
4776 return NULL;
4777 }
4778 if (seteuid(euid) < 0) {
4779 return posix_error();
4780 } else {
4781 Py_INCREF(Py_None);
4782 return Py_None;
4783 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004784}
4785#endif /* HAVE_SETEUID */
4786
4787#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004788PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004789"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004790Set the current process's effective group id.");
4791
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004792static PyObject *
4793posix_setegid (PyObject *self, PyObject *args)
4794{
Victor Stinner8c62be82010-05-06 00:08:46 +00004795 long egid_arg;
4796 gid_t egid;
4797 if (!PyArg_ParseTuple(args, "l", &egid_arg))
4798 return NULL;
4799 egid = egid_arg;
4800 if (egid != egid_arg) {
4801 PyErr_SetString(PyExc_OverflowError, "group id too big");
4802 return NULL;
4803 }
4804 if (setegid(egid) < 0) {
4805 return posix_error();
4806 } else {
4807 Py_INCREF(Py_None);
4808 return Py_None;
4809 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004810}
4811#endif /* HAVE_SETEGID */
4812
4813#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004814PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004815"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004816Set the current process's real and effective user ids.");
4817
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004818static PyObject *
4819posix_setreuid (PyObject *self, PyObject *args)
4820{
Victor Stinner8c62be82010-05-06 00:08:46 +00004821 long ruid_arg, euid_arg;
4822 uid_t ruid, euid;
4823 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
4824 return NULL;
4825 if (ruid_arg == -1)
4826 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
4827 else
4828 ruid = ruid_arg; /* otherwise, assign from our long */
4829 if (euid_arg == -1)
4830 euid = (uid_t)-1;
4831 else
4832 euid = euid_arg;
4833 if ((euid_arg != -1 && euid != euid_arg) ||
4834 (ruid_arg != -1 && ruid != ruid_arg)) {
4835 PyErr_SetString(PyExc_OverflowError, "user id too big");
4836 return NULL;
4837 }
4838 if (setreuid(ruid, euid) < 0) {
4839 return posix_error();
4840 } else {
4841 Py_INCREF(Py_None);
4842 return Py_None;
4843 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004844}
4845#endif /* HAVE_SETREUID */
4846
4847#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004848PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004849"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004850Set the current process's real and effective group ids.");
4851
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004852static PyObject *
4853posix_setregid (PyObject *self, PyObject *args)
4854{
Victor Stinner8c62be82010-05-06 00:08:46 +00004855 long rgid_arg, egid_arg;
4856 gid_t rgid, egid;
4857 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
4858 return NULL;
4859 if (rgid_arg == -1)
4860 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
4861 else
4862 rgid = rgid_arg; /* otherwise, assign from our long */
4863 if (egid_arg == -1)
4864 egid = (gid_t)-1;
4865 else
4866 egid = egid_arg;
4867 if ((egid_arg != -1 && egid != egid_arg) ||
4868 (rgid_arg != -1 && rgid != rgid_arg)) {
4869 PyErr_SetString(PyExc_OverflowError, "group id too big");
4870 return NULL;
4871 }
4872 if (setregid(rgid, egid) < 0) {
4873 return posix_error();
4874 } else {
4875 Py_INCREF(Py_None);
4876 return Py_None;
4877 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004878}
4879#endif /* HAVE_SETREGID */
4880
Guido van Rossumb6775db1994-08-01 11:34:53 +00004881#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004882PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004883"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004884Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004885
Barry Warsaw53699e91996-12-10 23:23:01 +00004886static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004887posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004888{
Victor Stinner8c62be82010-05-06 00:08:46 +00004889 long gid_arg;
4890 gid_t gid;
4891 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
4892 return NULL;
4893 gid = gid_arg;
4894 if (gid != gid_arg) {
4895 PyErr_SetString(PyExc_OverflowError, "group id too big");
4896 return NULL;
4897 }
4898 if (setgid(gid) < 0)
4899 return posix_error();
4900 Py_INCREF(Py_None);
4901 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004902}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004903#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004904
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004905#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004906PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004907"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004908Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004909
4910static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004911posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004912{
Victor Stinner8c62be82010-05-06 00:08:46 +00004913 int i, len;
4914 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004915
Victor Stinner8c62be82010-05-06 00:08:46 +00004916 if (!PySequence_Check(groups)) {
4917 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4918 return NULL;
4919 }
4920 len = PySequence_Size(groups);
4921 if (len > MAX_GROUPS) {
4922 PyErr_SetString(PyExc_ValueError, "too many groups");
4923 return NULL;
4924 }
4925 for(i = 0; i < len; i++) {
4926 PyObject *elem;
4927 elem = PySequence_GetItem(groups, i);
4928 if (!elem)
4929 return NULL;
4930 if (!PyLong_Check(elem)) {
4931 PyErr_SetString(PyExc_TypeError,
4932 "groups must be integers");
4933 Py_DECREF(elem);
4934 return NULL;
4935 } else {
4936 unsigned long x = PyLong_AsUnsignedLong(elem);
4937 if (PyErr_Occurred()) {
4938 PyErr_SetString(PyExc_TypeError,
4939 "group id too big");
4940 Py_DECREF(elem);
4941 return NULL;
4942 }
4943 grouplist[i] = x;
4944 /* read back the value to see if it fitted in gid_t */
4945 if (grouplist[i] != x) {
4946 PyErr_SetString(PyExc_TypeError,
4947 "group id too big");
4948 Py_DECREF(elem);
4949 return NULL;
4950 }
4951 }
4952 Py_DECREF(elem);
4953 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004954
Victor Stinner8c62be82010-05-06 00:08:46 +00004955 if (setgroups(len, grouplist) < 0)
4956 return posix_error();
4957 Py_INCREF(Py_None);
4958 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004959}
4960#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004961
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004962#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4963static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004964wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004965{
Victor Stinner8c62be82010-05-06 00:08:46 +00004966 PyObject *result;
4967 static PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004968
Victor Stinner8c62be82010-05-06 00:08:46 +00004969 if (pid == -1)
4970 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004971
Victor Stinner8c62be82010-05-06 00:08:46 +00004972 if (struct_rusage == NULL) {
4973 PyObject *m = PyImport_ImportModuleNoBlock("resource");
4974 if (m == NULL)
4975 return NULL;
4976 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4977 Py_DECREF(m);
4978 if (struct_rusage == NULL)
4979 return NULL;
4980 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004981
Victor Stinner8c62be82010-05-06 00:08:46 +00004982 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4983 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4984 if (!result)
4985 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004986
4987#ifndef doubletime
4988#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4989#endif
4990
Victor Stinner8c62be82010-05-06 00:08:46 +00004991 PyStructSequence_SET_ITEM(result, 0,
4992 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4993 PyStructSequence_SET_ITEM(result, 1,
4994 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004995#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00004996 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
4997 SET_INT(result, 2, ru->ru_maxrss);
4998 SET_INT(result, 3, ru->ru_ixrss);
4999 SET_INT(result, 4, ru->ru_idrss);
5000 SET_INT(result, 5, ru->ru_isrss);
5001 SET_INT(result, 6, ru->ru_minflt);
5002 SET_INT(result, 7, ru->ru_majflt);
5003 SET_INT(result, 8, ru->ru_nswap);
5004 SET_INT(result, 9, ru->ru_inblock);
5005 SET_INT(result, 10, ru->ru_oublock);
5006 SET_INT(result, 11, ru->ru_msgsnd);
5007 SET_INT(result, 12, ru->ru_msgrcv);
5008 SET_INT(result, 13, ru->ru_nsignals);
5009 SET_INT(result, 14, ru->ru_nvcsw);
5010 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005011#undef SET_INT
5012
Victor Stinner8c62be82010-05-06 00:08:46 +00005013 if (PyErr_Occurred()) {
5014 Py_DECREF(result);
5015 return NULL;
5016 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005017
Victor Stinner8c62be82010-05-06 00:08:46 +00005018 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005019}
5020#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
5021
5022#ifdef HAVE_WAIT3
5023PyDoc_STRVAR(posix_wait3__doc__,
5024"wait3(options) -> (pid, status, rusage)\n\n\
5025Wait for completion of a child process.");
5026
5027static PyObject *
5028posix_wait3(PyObject *self, PyObject *args)
5029{
Victor Stinner8c62be82010-05-06 00:08:46 +00005030 pid_t pid;
5031 int options;
5032 struct rusage ru;
5033 WAIT_TYPE status;
5034 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005035
Victor Stinner8c62be82010-05-06 00:08:46 +00005036 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5037 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005038
Victor Stinner8c62be82010-05-06 00:08:46 +00005039 Py_BEGIN_ALLOW_THREADS
5040 pid = wait3(&status, options, &ru);
5041 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005042
Victor Stinner8c62be82010-05-06 00:08:46 +00005043 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005044}
5045#endif /* HAVE_WAIT3 */
5046
5047#ifdef HAVE_WAIT4
5048PyDoc_STRVAR(posix_wait4__doc__,
5049"wait4(pid, options) -> (pid, status, rusage)\n\n\
5050Wait for completion of a given child process.");
5051
5052static PyObject *
5053posix_wait4(PyObject *self, PyObject *args)
5054{
Victor Stinner8c62be82010-05-06 00:08:46 +00005055 pid_t pid;
5056 int options;
5057 struct rusage ru;
5058 WAIT_TYPE status;
5059 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005060
Victor Stinner8c62be82010-05-06 00:08:46 +00005061 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
5062 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005063
Victor Stinner8c62be82010-05-06 00:08:46 +00005064 Py_BEGIN_ALLOW_THREADS
5065 pid = wait4(pid, &status, options, &ru);
5066 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005067
Victor Stinner8c62be82010-05-06 00:08:46 +00005068 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005069}
5070#endif /* HAVE_WAIT4 */
5071
Guido van Rossumb6775db1994-08-01 11:34:53 +00005072#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005073PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005074"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005075Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005076
Barry Warsaw53699e91996-12-10 23:23:01 +00005077static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005078posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005079{
Victor Stinner8c62be82010-05-06 00:08:46 +00005080 pid_t pid;
5081 int options;
5082 WAIT_TYPE status;
5083 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005084
Victor Stinner8c62be82010-05-06 00:08:46 +00005085 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
5086 return NULL;
5087 Py_BEGIN_ALLOW_THREADS
5088 pid = waitpid(pid, &status, options);
5089 Py_END_ALLOW_THREADS
5090 if (pid == -1)
5091 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005092
Victor Stinner8c62be82010-05-06 00:08:46 +00005093 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005094}
5095
Tim Petersab034fa2002-02-01 11:27:43 +00005096#elif defined(HAVE_CWAIT)
5097
5098/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005099PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005100"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005101"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005102
5103static PyObject *
5104posix_waitpid(PyObject *self, PyObject *args)
5105{
Victor Stinner8c62be82010-05-06 00:08:46 +00005106 Py_intptr_t pid;
5107 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005108
Victor Stinner8c62be82010-05-06 00:08:46 +00005109 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
5110 return NULL;
5111 Py_BEGIN_ALLOW_THREADS
5112 pid = _cwait(&status, pid, options);
5113 Py_END_ALLOW_THREADS
5114 if (pid == -1)
5115 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005116
Victor Stinner8c62be82010-05-06 00:08:46 +00005117 /* shift the status left a byte so this is more like the POSIX waitpid */
5118 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005119}
5120#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005121
Guido van Rossumad0ee831995-03-01 10:34:45 +00005122#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005123PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005124"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005125Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005126
Barry Warsaw53699e91996-12-10 23:23:01 +00005127static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005128posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005129{
Victor Stinner8c62be82010-05-06 00:08:46 +00005130 pid_t pid;
5131 WAIT_TYPE status;
5132 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005133
Victor Stinner8c62be82010-05-06 00:08:46 +00005134 Py_BEGIN_ALLOW_THREADS
5135 pid = wait(&status);
5136 Py_END_ALLOW_THREADS
5137 if (pid == -1)
5138 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005139
Victor Stinner8c62be82010-05-06 00:08:46 +00005140 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005141}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005142#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005143
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005144
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005145PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005146"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005147Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005148
Barry Warsaw53699e91996-12-10 23:23:01 +00005149static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005150posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005151{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005152#ifdef HAVE_LSTAT
Victor Stinner8c62be82010-05-06 00:08:46 +00005153 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005154#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005155#ifdef MS_WINDOWS
Brian Curtind25aef52011-06-13 15:16:04 -05005156 return posix_do_stat(self, args, "O&:lstat", win32_lstat, "U:lstat",
Brian Curtind40e6f72010-07-08 21:39:08 +00005157 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005158#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005159 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005160#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005161#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005162}
5163
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005164
Guido van Rossumb6775db1994-08-01 11:34:53 +00005165#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005166PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005167"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005168Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005169
Barry Warsaw53699e91996-12-10 23:23:01 +00005170static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005171posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005172{
Victor Stinner8c62be82010-05-06 00:08:46 +00005173 PyObject* v;
5174 char buf[MAXPATHLEN];
5175 PyObject *opath;
5176 char *path;
5177 int n;
5178 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00005179
Victor Stinner8c62be82010-05-06 00:08:46 +00005180 if (!PyArg_ParseTuple(args, "O&:readlink",
5181 PyUnicode_FSConverter, &opath))
5182 return NULL;
5183 path = PyBytes_AsString(opath);
5184 v = PySequence_GetItem(args, 0);
5185 if (v == NULL) {
5186 Py_DECREF(opath);
5187 return NULL;
5188 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00005189
Victor Stinner8c62be82010-05-06 00:08:46 +00005190 if (PyUnicode_Check(v)) {
5191 arg_is_unicode = 1;
5192 }
5193 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005194
Victor Stinner8c62be82010-05-06 00:08:46 +00005195 Py_BEGIN_ALLOW_THREADS
5196 n = readlink(path, buf, (int) sizeof buf);
5197 Py_END_ALLOW_THREADS
5198 if (n < 0)
5199 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005200
Victor Stinner8c62be82010-05-06 00:08:46 +00005201 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00005202 if (arg_is_unicode)
5203 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
5204 else
5205 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005206}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005207#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005208
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005209
Brian Curtin52173d42010-12-02 18:29:18 +00005210#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005211PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005212"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005213Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005214
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005215static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005216posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005217{
Victor Stinner8c62be82010-05-06 00:08:46 +00005218 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005219}
5220#endif /* HAVE_SYMLINK */
5221
Brian Curtind40e6f72010-07-08 21:39:08 +00005222#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
5223
5224PyDoc_STRVAR(win_readlink__doc__,
5225"readlink(path) -> path\n\n\
5226Return a string representing the path to which the symbolic link points.");
5227
Brian Curtind40e6f72010-07-08 21:39:08 +00005228/* Windows readlink implementation */
5229static PyObject *
5230win_readlink(PyObject *self, PyObject *args)
5231{
5232 wchar_t *path;
5233 DWORD n_bytes_returned;
5234 DWORD io_result;
5235 PyObject *result;
5236 HANDLE reparse_point_handle;
5237
5238 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
5239 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
5240 wchar_t *print_name;
5241
5242 if (!PyArg_ParseTuple(args,
5243 "u:readlink",
5244 &path))
5245 return NULL;
5246
5247 /* First get a handle to the reparse point */
5248 Py_BEGIN_ALLOW_THREADS
5249 reparse_point_handle = CreateFileW(
5250 path,
5251 0,
5252 0,
5253 0,
5254 OPEN_EXISTING,
5255 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
5256 0);
5257 Py_END_ALLOW_THREADS
Victor Stinner26de69d2011-06-17 15:15:38 +02005258
Brian Curtind40e6f72010-07-08 21:39:08 +00005259 if (reparse_point_handle==INVALID_HANDLE_VALUE)
5260 {
5261 return win32_error_unicode("readlink", path);
5262 }
Victor Stinner26de69d2011-06-17 15:15:38 +02005263
Brian Curtind40e6f72010-07-08 21:39:08 +00005264 Py_BEGIN_ALLOW_THREADS
5265 /* New call DeviceIoControl to read the reparse point */
5266 io_result = DeviceIoControl(
5267 reparse_point_handle,
5268 FSCTL_GET_REPARSE_POINT,
5269 0, 0, /* in buffer */
5270 target_buffer, sizeof(target_buffer),
5271 &n_bytes_returned,
5272 0 /* we're not using OVERLAPPED_IO */
5273 );
5274 CloseHandle(reparse_point_handle);
5275 Py_END_ALLOW_THREADS
5276
5277 if (io_result==0)
5278 {
5279 return win32_error_unicode("readlink", path);
5280 }
5281
5282 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
5283 {
5284 PyErr_SetString(PyExc_ValueError,
5285 "not a symbolic link");
5286 return NULL;
5287 }
Brian Curtin74e45612010-07-09 15:58:59 +00005288 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
5289 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
5290
5291 result = PyUnicode_FromWideChar(print_name,
5292 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00005293 return result;
5294}
5295
5296#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
5297
Brian Curtin52173d42010-12-02 18:29:18 +00005298#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtind40e6f72010-07-08 21:39:08 +00005299
5300/* Grab CreateSymbolicLinkW dynamically from kernel32 */
5301static int has_CreateSymbolicLinkW = 0;
5302static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
5303static int
5304check_CreateSymbolicLinkW()
5305{
5306 HINSTANCE hKernel32;
5307 /* only recheck */
5308 if (has_CreateSymbolicLinkW)
5309 return has_CreateSymbolicLinkW;
5310 hKernel32 = GetModuleHandle("KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00005311 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
5312 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00005313 if (Py_CreateSymbolicLinkW)
5314 has_CreateSymbolicLinkW = 1;
5315 return has_CreateSymbolicLinkW;
5316}
5317
5318PyDoc_STRVAR(win_symlink__doc__,
5319"symlink(src, dst, target_is_directory=False)\n\n\
5320Create a symbolic link pointing to src named dst.\n\
5321target_is_directory is required if the target is to be interpreted as\n\
5322a directory.\n\
5323This function requires Windows 6.0 or greater, and raises a\n\
5324NotImplementedError otherwise.");
5325
5326static PyObject *
5327win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
5328{
5329 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
5330 PyObject *src, *dest;
5331 int target_is_directory = 0;
5332 DWORD res;
5333 WIN32_FILE_ATTRIBUTE_DATA src_info;
Victor Stinner26de69d2011-06-17 15:15:38 +02005334
Brian Curtind40e6f72010-07-08 21:39:08 +00005335 if (!check_CreateSymbolicLinkW())
5336 {
5337 /* raise NotImplementedError */
5338 return PyErr_Format(PyExc_NotImplementedError,
5339 "CreateSymbolicLinkW not found");
5340 }
5341 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:symlink",
5342 kwlist, &src, &dest, &target_is_directory))
5343 return NULL;
Brian Curtin3b4499c2010-12-28 14:31:47 +00005344
5345 if (win32_can_symlink == 0)
5346 return PyErr_Format(PyExc_OSError, "symbolic link privilege not held");
5347
Brian Curtind40e6f72010-07-08 21:39:08 +00005348 if (!convert_to_unicode(&src)) { return NULL; }
5349 if (!convert_to_unicode(&dest)) {
5350 Py_DECREF(src);
5351 return NULL;
5352 }
Victor Stinner26de69d2011-06-17 15:15:38 +02005353
Brian Curtind40e6f72010-07-08 21:39:08 +00005354 /* if src is a directory, ensure target_is_directory==1 */
5355 if(
5356 GetFileAttributesExW(
5357 PyUnicode_AsUnicode(src), GetFileExInfoStandard, &src_info
5358 ))
5359 {
5360 target_is_directory = target_is_directory ||
5361 (src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
5362 }
5363
5364 Py_BEGIN_ALLOW_THREADS
5365 res = Py_CreateSymbolicLinkW(
5366 PyUnicode_AsUnicode(dest),
5367 PyUnicode_AsUnicode(src),
5368 target_is_directory);
5369 Py_END_ALLOW_THREADS
5370 Py_DECREF(src);
5371 Py_DECREF(dest);
5372 if (!res)
5373 {
5374 return win32_error_unicode("symlink", PyUnicode_AsUnicode(src));
5375 }
Victor Stinner26de69d2011-06-17 15:15:38 +02005376
Brian Curtind40e6f72010-07-08 21:39:08 +00005377 Py_INCREF(Py_None);
5378 return Py_None;
5379}
Brian Curtin52173d42010-12-02 18:29:18 +00005380#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005381
5382#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00005383#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5384static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005385system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005386{
5387 ULONG value = 0;
5388
5389 Py_BEGIN_ALLOW_THREADS
5390 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5391 Py_END_ALLOW_THREADS
5392
5393 return value;
5394}
5395
5396static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005397posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005398{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005399 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00005400 return Py_BuildValue("ddddd",
5401 (double)0 /* t.tms_utime / HZ */,
5402 (double)0 /* t.tms_stime / HZ */,
5403 (double)0 /* t.tms_cutime / HZ */,
5404 (double)0 /* t.tms_cstime / HZ */,
5405 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005406}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005407#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00005408#define NEED_TICKS_PER_SECOND
5409static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00005410static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005411posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005412{
Victor Stinner8c62be82010-05-06 00:08:46 +00005413 struct tms t;
5414 clock_t c;
5415 errno = 0;
5416 c = times(&t);
5417 if (c == (clock_t) -1)
5418 return posix_error();
5419 return Py_BuildValue("ddddd",
5420 (double)t.tms_utime / ticks_per_second,
5421 (double)t.tms_stime / ticks_per_second,
5422 (double)t.tms_cutime / ticks_per_second,
5423 (double)t.tms_cstime / ticks_per_second,
5424 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005425}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005426#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005427#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005428
5429
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005430#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005431#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005432static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005433posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005434{
Victor Stinner8c62be82010-05-06 00:08:46 +00005435 FILETIME create, exit, kernel, user;
5436 HANDLE hProc;
5437 hProc = GetCurrentProcess();
5438 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5439 /* The fields of a FILETIME structure are the hi and lo part
5440 of a 64-bit value expressed in 100 nanosecond units.
5441 1e7 is one second in such units; 1e-7 the inverse.
5442 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5443 */
5444 return Py_BuildValue(
5445 "ddddd",
5446 (double)(user.dwHighDateTime*429.4967296 +
5447 user.dwLowDateTime*1e-7),
5448 (double)(kernel.dwHighDateTime*429.4967296 +
5449 kernel.dwLowDateTime*1e-7),
5450 (double)0,
5451 (double)0,
5452 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005453}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005454#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005455
5456#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005457PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005458"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005459Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005460#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005461
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005462
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005463#ifdef HAVE_GETSID
5464PyDoc_STRVAR(posix_getsid__doc__,
5465"getsid(pid) -> sid\n\n\
5466Call the system call getsid().");
5467
5468static PyObject *
5469posix_getsid(PyObject *self, PyObject *args)
5470{
Victor Stinner8c62be82010-05-06 00:08:46 +00005471 pid_t pid;
5472 int sid;
5473 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
5474 return NULL;
5475 sid = getsid(pid);
5476 if (sid < 0)
5477 return posix_error();
5478 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005479}
5480#endif /* HAVE_GETSID */
5481
5482
Guido van Rossumb6775db1994-08-01 11:34:53 +00005483#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005484PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005485"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005486Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005487
Barry Warsaw53699e91996-12-10 23:23:01 +00005488static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005489posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005490{
Victor Stinner8c62be82010-05-06 00:08:46 +00005491 if (setsid() < 0)
5492 return posix_error();
5493 Py_INCREF(Py_None);
5494 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005495}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005496#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005497
Guido van Rossumb6775db1994-08-01 11:34:53 +00005498#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005499PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005500"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005501Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005502
Barry Warsaw53699e91996-12-10 23:23:01 +00005503static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005504posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005505{
Victor Stinner8c62be82010-05-06 00:08:46 +00005506 pid_t pid;
5507 int pgrp;
5508 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
5509 return NULL;
5510 if (setpgid(pid, pgrp) < 0)
5511 return posix_error();
5512 Py_INCREF(Py_None);
5513 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005514}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005515#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005516
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005517
Guido van Rossumb6775db1994-08-01 11:34:53 +00005518#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005519PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005520"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005521Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005522
Barry Warsaw53699e91996-12-10 23:23:01 +00005523static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005524posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005525{
Victor Stinner8c62be82010-05-06 00:08:46 +00005526 int fd;
5527 pid_t pgid;
5528 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
5529 return NULL;
5530 pgid = tcgetpgrp(fd);
5531 if (pgid < 0)
5532 return posix_error();
5533 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005534}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005535#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005536
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005537
Guido van Rossumb6775db1994-08-01 11:34:53 +00005538#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005539PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005540"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005541Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005542
Barry Warsaw53699e91996-12-10 23:23:01 +00005543static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005544posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005545{
Victor Stinner8c62be82010-05-06 00:08:46 +00005546 int fd;
5547 pid_t pgid;
5548 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
5549 return NULL;
5550 if (tcsetpgrp(fd, pgid) < 0)
5551 return posix_error();
5552 Py_INCREF(Py_None);
5553 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005554}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005555#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005556
Guido van Rossum687dd131993-05-17 08:34:16 +00005557/* Functions acting on file descriptors */
5558
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005559PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005560"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005561Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005562
Barry Warsaw53699e91996-12-10 23:23:01 +00005563static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005564posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005565{
Victor Stinner8c62be82010-05-06 00:08:46 +00005566 PyObject *ofile;
5567 char *file;
5568 int flag;
5569 int mode = 0777;
5570 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005571
5572#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005573 PyUnicodeObject *po;
Victor Stinner26de69d2011-06-17 15:15:38 +02005574 if (PyArg_ParseTuple(args, "Ui|i:open", &po, &flag, &mode)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005575 Py_BEGIN_ALLOW_THREADS
5576 /* PyUnicode_AS_UNICODE OK without thread
5577 lock as it is a simple dereference. */
5578 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5579 Py_END_ALLOW_THREADS
5580 if (fd < 0)
5581 return posix_error();
5582 return PyLong_FromLong((long)fd);
5583 }
5584 /* Drop the argument parsing error as narrow strings
5585 are also valid. */
5586 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005587#endif
5588
Victor Stinner26de69d2011-06-17 15:15:38 +02005589 if (!PyArg_ParseTuple(args, "O&i|i:open",
Victor Stinner8c62be82010-05-06 00:08:46 +00005590 PyUnicode_FSConverter, &ofile,
5591 &flag, &mode))
5592 return NULL;
5593 file = PyBytes_AsString(ofile);
5594 Py_BEGIN_ALLOW_THREADS
5595 fd = open(file, flag, mode);
5596 Py_END_ALLOW_THREADS
5597 if (fd < 0)
5598 return posix_error_with_allocated_filename(ofile);
5599 Py_DECREF(ofile);
5600 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005601}
5602
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005603
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005604PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005605"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005606Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005607
Barry Warsaw53699e91996-12-10 23:23:01 +00005608static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005609posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005610{
Victor Stinner8c62be82010-05-06 00:08:46 +00005611 int fd, res;
5612 if (!PyArg_ParseTuple(args, "i:close", &fd))
5613 return NULL;
5614 if (!_PyVerify_fd(fd))
5615 return posix_error();
5616 Py_BEGIN_ALLOW_THREADS
5617 res = close(fd);
5618 Py_END_ALLOW_THREADS
5619 if (res < 0)
5620 return posix_error();
5621 Py_INCREF(Py_None);
5622 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005623}
5624
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005625
Victor Stinner8c62be82010-05-06 00:08:46 +00005626PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00005627"closerange(fd_low, fd_high)\n\n\
5628Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
5629
5630static PyObject *
5631posix_closerange(PyObject *self, PyObject *args)
5632{
Victor Stinner8c62be82010-05-06 00:08:46 +00005633 int fd_from, fd_to, i;
5634 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
5635 return NULL;
5636 Py_BEGIN_ALLOW_THREADS
5637 for (i = fd_from; i < fd_to; i++)
5638 if (_PyVerify_fd(i))
5639 close(i);
5640 Py_END_ALLOW_THREADS
5641 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00005642}
5643
5644
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005645PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005646"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005647Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005648
Barry Warsaw53699e91996-12-10 23:23:01 +00005649static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005650posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005651{
Victor Stinner8c62be82010-05-06 00:08:46 +00005652 int fd;
5653 if (!PyArg_ParseTuple(args, "i:dup", &fd))
5654 return NULL;
5655 if (!_PyVerify_fd(fd))
5656 return posix_error();
5657 Py_BEGIN_ALLOW_THREADS
5658 fd = dup(fd);
5659 Py_END_ALLOW_THREADS
5660 if (fd < 0)
5661 return posix_error();
5662 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005663}
5664
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005665
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005666PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005667"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005668Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005669
Barry Warsaw53699e91996-12-10 23:23:01 +00005670static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005671posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005672{
Victor Stinner8c62be82010-05-06 00:08:46 +00005673 int fd, fd2, res;
5674 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5675 return NULL;
5676 if (!_PyVerify_fd_dup2(fd, fd2))
5677 return posix_error();
5678 Py_BEGIN_ALLOW_THREADS
5679 res = dup2(fd, fd2);
5680 Py_END_ALLOW_THREADS
5681 if (res < 0)
5682 return posix_error();
5683 Py_INCREF(Py_None);
5684 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005685}
5686
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005687
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005688PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005689"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005690Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005691
Barry Warsaw53699e91996-12-10 23:23:01 +00005692static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005693posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005694{
Victor Stinner8c62be82010-05-06 00:08:46 +00005695 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005696#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005697 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005698#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005699 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005700#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005701 PyObject *posobj;
5702 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5703 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005704#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00005705 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5706 switch (how) {
5707 case 0: how = SEEK_SET; break;
5708 case 1: how = SEEK_CUR; break;
5709 case 2: how = SEEK_END; break;
5710 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005711#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005712
5713#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005714 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005715#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005716 pos = PyLong_Check(posobj) ?
5717 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005718#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005719 if (PyErr_Occurred())
5720 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005721
Victor Stinner8c62be82010-05-06 00:08:46 +00005722 if (!_PyVerify_fd(fd))
5723 return posix_error();
5724 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005725#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005726 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005727#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005728 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005729#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005730 Py_END_ALLOW_THREADS
5731 if (res < 0)
5732 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005733
5734#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005735 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005736#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005737 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005738#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005739}
5740
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005741
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005742PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005743"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005744Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005745
Barry Warsaw53699e91996-12-10 23:23:01 +00005746static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005747posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005748{
Victor Stinner8c62be82010-05-06 00:08:46 +00005749 int fd, size;
5750 Py_ssize_t n;
5751 PyObject *buffer;
5752 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5753 return NULL;
5754 if (size < 0) {
5755 errno = EINVAL;
5756 return posix_error();
5757 }
5758 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
5759 if (buffer == NULL)
5760 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00005761 if (!_PyVerify_fd(fd)) {
5762 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00005763 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00005764 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005765 Py_BEGIN_ALLOW_THREADS
5766 n = read(fd, PyBytes_AS_STRING(buffer), size);
5767 Py_END_ALLOW_THREADS
5768 if (n < 0) {
5769 Py_DECREF(buffer);
5770 return posix_error();
5771 }
5772 if (n != size)
5773 _PyBytes_Resize(&buffer, n);
5774 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00005775}
5776
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005777
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005778PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005779"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005780Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005781
Barry Warsaw53699e91996-12-10 23:23:01 +00005782static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005783posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005784{
Victor Stinner8c62be82010-05-06 00:08:46 +00005785 Py_buffer pbuf;
5786 int fd;
Victor Stinnere6edec22011-01-04 00:29:35 +00005787 Py_ssize_t size, len;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005788
Victor Stinner8c62be82010-05-06 00:08:46 +00005789 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
5790 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00005791 if (!_PyVerify_fd(fd)) {
5792 PyBuffer_Release(&pbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00005793 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00005794 }
Victor Stinnere6edec22011-01-04 00:29:35 +00005795 len = pbuf.len;
Victor Stinner8c62be82010-05-06 00:08:46 +00005796 Py_BEGIN_ALLOW_THREADS
Victor Stinnere6edec22011-01-04 00:29:35 +00005797#if defined(MS_WIN64) || defined(MS_WINDOWS)
5798 if (len > INT_MAX)
5799 len = INT_MAX;
5800 size = write(fd, pbuf.buf, (int)len);
5801#else
Victor Stinner72344792011-01-11 00:04:12 +00005802 size = write(fd, pbuf.buf, len);
Victor Stinnere6edec22011-01-04 00:29:35 +00005803#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005804 Py_END_ALLOW_THREADS
Stefan Krah99439262010-11-26 12:58:05 +00005805 PyBuffer_Release(&pbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00005806 if (size < 0)
5807 return posix_error();
5808 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005809}
5810
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005811
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005812PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005813"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005814Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005815
Barry Warsaw53699e91996-12-10 23:23:01 +00005816static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005817posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005818{
Victor Stinner8c62be82010-05-06 00:08:46 +00005819 int fd;
5820 STRUCT_STAT st;
5821 int res;
5822 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5823 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005824#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00005825 /* on OpenVMS we must ensure that all bytes are written to the file */
5826 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005827#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005828 if (!_PyVerify_fd(fd))
5829 return posix_error();
5830 Py_BEGIN_ALLOW_THREADS
5831 res = FSTAT(fd, &st);
5832 Py_END_ALLOW_THREADS
5833 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00005834#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005835 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00005836#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005837 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005838#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005839 }
Tim Peters5aa91602002-01-30 05:46:57 +00005840
Victor Stinner8c62be82010-05-06 00:08:46 +00005841 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005842}
5843
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005844PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005845"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005846Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005847connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005848
5849static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005850posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005851{
Victor Stinner8c62be82010-05-06 00:08:46 +00005852 int fd;
5853 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5854 return NULL;
5855 if (!_PyVerify_fd(fd))
5856 return PyBool_FromLong(0);
5857 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005858}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005859
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005860#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005861PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005862"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005863Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005864
Barry Warsaw53699e91996-12-10 23:23:01 +00005865static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005866posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005867{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005868#if defined(PYOS_OS2)
5869 HFILE read, write;
5870 APIRET rc;
5871
Victor Stinner8c62be82010-05-06 00:08:46 +00005872 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005873 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinner8c62be82010-05-06 00:08:46 +00005874 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005875 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005876 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005877
5878 return Py_BuildValue("(ii)", read, write);
5879#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005880#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005881 int fds[2];
5882 int res;
5883 Py_BEGIN_ALLOW_THREADS
5884 res = pipe(fds);
5885 Py_END_ALLOW_THREADS
5886 if (res != 0)
5887 return posix_error();
5888 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005889#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00005890 HANDLE read, write;
5891 int read_fd, write_fd;
5892 BOOL ok;
5893 Py_BEGIN_ALLOW_THREADS
5894 ok = CreatePipe(&read, &write, NULL, 0);
5895 Py_END_ALLOW_THREADS
5896 if (!ok)
5897 return win32_error("CreatePipe", NULL);
5898 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5899 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5900 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005901#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005902#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005903}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005904#endif /* HAVE_PIPE */
5905
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005906
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005907#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005908PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005909"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005910Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005911
Barry Warsaw53699e91996-12-10 23:23:01 +00005912static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005913posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005914{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005915 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005916 char *filename;
5917 int mode = 0666;
5918 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005919 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
5920 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00005921 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005922 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005923 Py_BEGIN_ALLOW_THREADS
5924 res = mkfifo(filename, mode);
5925 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005926 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005927 if (res < 0)
5928 return posix_error();
5929 Py_INCREF(Py_None);
5930 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005931}
5932#endif
5933
5934
Neal Norwitz11690112002-07-30 01:08:28 +00005935#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005936PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005937"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005938Create a filesystem node (file, device special file or named pipe)\n\
5939named filename. mode specifies both the permissions to use and the\n\
5940type of node to be created, being combined (bitwise OR) with one of\n\
5941S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005942device defines the newly created device special file (probably using\n\
5943os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005944
5945
5946static PyObject *
5947posix_mknod(PyObject *self, PyObject *args)
5948{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005949 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005950 char *filename;
5951 int mode = 0600;
5952 int device = 0;
5953 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005954 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
5955 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00005956 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005957 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005958 Py_BEGIN_ALLOW_THREADS
5959 res = mknod(filename, mode, device);
5960 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005961 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005962 if (res < 0)
5963 return posix_error();
5964 Py_INCREF(Py_None);
5965 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005966}
5967#endif
5968
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005969#ifdef HAVE_DEVICE_MACROS
5970PyDoc_STRVAR(posix_major__doc__,
5971"major(device) -> major number\n\
5972Extracts a device major number from a raw device number.");
5973
5974static PyObject *
5975posix_major(PyObject *self, PyObject *args)
5976{
Victor Stinner8c62be82010-05-06 00:08:46 +00005977 int device;
5978 if (!PyArg_ParseTuple(args, "i:major", &device))
5979 return NULL;
5980 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005981}
5982
5983PyDoc_STRVAR(posix_minor__doc__,
5984"minor(device) -> minor number\n\
5985Extracts a device minor number from a raw device number.");
5986
5987static PyObject *
5988posix_minor(PyObject *self, PyObject *args)
5989{
Victor Stinner8c62be82010-05-06 00:08:46 +00005990 int device;
5991 if (!PyArg_ParseTuple(args, "i:minor", &device))
5992 return NULL;
5993 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005994}
5995
5996PyDoc_STRVAR(posix_makedev__doc__,
5997"makedev(major, minor) -> device number\n\
5998Composes a raw device number from the major and minor device numbers.");
5999
6000static PyObject *
6001posix_makedev(PyObject *self, PyObject *args)
6002{
Victor Stinner8c62be82010-05-06 00:08:46 +00006003 int major, minor;
6004 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6005 return NULL;
6006 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006007}
6008#endif /* device macros */
6009
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006010
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006011#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006012PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006013"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006014Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006015
Barry Warsaw53699e91996-12-10 23:23:01 +00006016static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006017posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006018{
Victor Stinner8c62be82010-05-06 00:08:46 +00006019 int fd;
6020 off_t length;
6021 int res;
6022 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006023
Victor Stinner8c62be82010-05-06 00:08:46 +00006024 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
6025 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006026
6027#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006028 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006029#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006030 length = PyLong_Check(lenobj) ?
6031 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006032#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006033 if (PyErr_Occurred())
6034 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006035
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 Py_BEGIN_ALLOW_THREADS
6037 res = ftruncate(fd, length);
6038 Py_END_ALLOW_THREADS
6039 if (res < 0)
6040 return posix_error();
6041 Py_INCREF(Py_None);
6042 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006043}
6044#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006045
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006046#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006047PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006048"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006049Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006050
Fred Drake762e2061999-08-26 17:23:54 +00006051/* Save putenv() parameters as values here, so we can collect them when they
6052 * get re-set with another call for the same key. */
6053static PyObject *posix_putenv_garbage;
6054
Tim Peters5aa91602002-01-30 05:46:57 +00006055static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006056posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006057{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006058#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006059 wchar_t *s1, *s2;
6060 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006061#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006062 PyObject *os1, *os2;
6063 char *s1, *s2;
6064 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006065#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006066 PyObject *newstr = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006067 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006068
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006069#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006070 if (!PyArg_ParseTuple(args,
6071 "uu:putenv",
6072 &s1, &s2))
6073 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00006074#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006075 if (!PyArg_ParseTuple(args,
6076 "O&O&:putenv",
6077 PyUnicode_FSConverter, &os1,
6078 PyUnicode_FSConverter, &os2))
6079 return NULL;
6080 s1 = PyBytes_AsString(os1);
6081 s2 = PyBytes_AsString(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00006082#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00006083
6084#if defined(PYOS_OS2)
6085 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6086 APIRET rc;
6087
Guido van Rossumd48f2521997-12-05 22:19:34 +00006088 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00006089 if (rc != NO_ERROR) {
6090 os2_error(rc);
6091 goto error;
6092 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006093
6094 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6095 APIRET rc;
6096
Guido van Rossumd48f2521997-12-05 22:19:34 +00006097 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00006098 if (rc != NO_ERROR) {
6099 os2_error(rc);
6100 goto error;
6101 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006102 } else {
6103#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006104 /* XXX This can leak memory -- not easy to fix :-( */
6105 /* len includes space for a trailing \0; the size arg to
6106 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006107#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006108 len = wcslen(s1) + wcslen(s2) + 2;
6109 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006110#else
Victor Stinner84ae1182010-05-06 22:05:07 +00006111 len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2;
Victor Stinner8c62be82010-05-06 00:08:46 +00006112 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006113#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006114 if (newstr == NULL) {
6115 PyErr_NoMemory();
6116 goto error;
6117 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006118#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006119 newenv = PyUnicode_AsUnicode(newstr);
6120 _snwprintf(newenv, len, L"%s=%s", s1, s2);
6121 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006122 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00006123 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006124 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006125#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006126 newenv = PyBytes_AS_STRING(newstr);
6127 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6128 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006129 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00006130 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006131 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006132#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006133
Victor Stinner8c62be82010-05-06 00:08:46 +00006134 /* Install the first arg and newstr in posix_putenv_garbage;
6135 * this will cause previous value to be collected. This has to
6136 * happen after the real putenv() call because the old value
6137 * was still accessible until then. */
6138 if (PyDict_SetItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00006139#ifdef MS_WINDOWS
6140 PyTuple_GET_ITEM(args, 0),
6141#else
6142 os1,
6143#endif
6144 newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006145 /* really not much we can do; just leak */
6146 PyErr_Clear();
6147 }
6148 else {
6149 Py_DECREF(newstr);
6150 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006151
6152#if defined(PYOS_OS2)
6153 }
6154#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006155
Martin v. Löwis011e8422009-05-05 04:43:17 +00006156#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006157 Py_DECREF(os1);
6158 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00006159#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006160 Py_RETURN_NONE;
6161
6162error:
6163#ifndef MS_WINDOWS
6164 Py_DECREF(os1);
6165 Py_DECREF(os2);
6166#endif
6167 Py_XDECREF(newstr);
6168 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006169}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006170#endif /* putenv */
6171
Guido van Rossumc524d952001-10-19 01:31:59 +00006172#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006173PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006174"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006175Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006176
6177static PyObject *
6178posix_unsetenv(PyObject *self, PyObject *args)
6179{
Victor Stinner84ae1182010-05-06 22:05:07 +00006180#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006181 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00006182
Victor Stinner8c62be82010-05-06 00:08:46 +00006183 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6184 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00006185#else
6186 PyObject *os1;
6187 char *s1;
6188
6189 if (!PyArg_ParseTuple(args, "O&:unsetenv",
6190 PyUnicode_FSConverter, &os1))
6191 return NULL;
6192 s1 = PyBytes_AsString(os1);
6193#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006194
Victor Stinner8c62be82010-05-06 00:08:46 +00006195 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00006196
Victor Stinner8c62be82010-05-06 00:08:46 +00006197 /* Remove the key from posix_putenv_garbage;
6198 * this will cause it to be collected. This has to
6199 * happen after the real unsetenv() call because the
6200 * old value was still accessible until then.
6201 */
6202 if (PyDict_DelItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00006203#ifdef MS_WINDOWS
6204 PyTuple_GET_ITEM(args, 0)
6205#else
6206 os1
6207#endif
6208 )) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006209 /* really not much we can do; just leak */
6210 PyErr_Clear();
6211 }
Guido van Rossumc524d952001-10-19 01:31:59 +00006212
Victor Stinner84ae1182010-05-06 22:05:07 +00006213#ifndef MS_WINDOWS
6214 Py_DECREF(os1);
6215#endif
6216 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00006217}
6218#endif /* unsetenv */
6219
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006220PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006221"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006222Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006223
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006224static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006225posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006226{
Victor Stinner8c62be82010-05-06 00:08:46 +00006227 int code;
6228 char *message;
6229 if (!PyArg_ParseTuple(args, "i:strerror", &code))
6230 return NULL;
6231 message = strerror(code);
6232 if (message == NULL) {
6233 PyErr_SetString(PyExc_ValueError,
6234 "strerror() argument out of range");
6235 return NULL;
6236 }
6237 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006238}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006239
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006240
Guido van Rossumc9641791998-08-04 15:26:23 +00006241#ifdef HAVE_SYS_WAIT_H
6242
Fred Drake106c1a02002-04-23 15:58:02 +00006243#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006244PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006245"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006246Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006247
6248static PyObject *
6249posix_WCOREDUMP(PyObject *self, PyObject *args)
6250{
Victor Stinner8c62be82010-05-06 00:08:46 +00006251 WAIT_TYPE status;
6252 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006253
Victor Stinner8c62be82010-05-06 00:08:46 +00006254 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
6255 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006256
Victor Stinner8c62be82010-05-06 00:08:46 +00006257 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006258}
6259#endif /* WCOREDUMP */
6260
6261#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006262PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006263"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006264Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006265job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006266
6267static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006268posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006269{
Victor Stinner8c62be82010-05-06 00:08:46 +00006270 WAIT_TYPE status;
6271 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006272
Victor Stinner8c62be82010-05-06 00:08:46 +00006273 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
6274 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006275
Victor Stinner8c62be82010-05-06 00:08:46 +00006276 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006277}
6278#endif /* WIFCONTINUED */
6279
Guido van Rossumc9641791998-08-04 15:26:23 +00006280#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006281PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006282"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006283Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006284
6285static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006286posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006287{
Victor Stinner8c62be82010-05-06 00:08:46 +00006288 WAIT_TYPE status;
6289 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006290
Victor Stinner8c62be82010-05-06 00:08:46 +00006291 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
6292 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006293
Victor Stinner8c62be82010-05-06 00:08:46 +00006294 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006295}
6296#endif /* WIFSTOPPED */
6297
6298#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006299PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006300"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006301Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006302
6303static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006304posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006305{
Victor Stinner8c62be82010-05-06 00:08:46 +00006306 WAIT_TYPE status;
6307 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006308
Victor Stinner8c62be82010-05-06 00:08:46 +00006309 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
6310 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006311
Victor Stinner8c62be82010-05-06 00:08:46 +00006312 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006313}
6314#endif /* WIFSIGNALED */
6315
6316#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006317PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006318"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006319Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006320system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006321
6322static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006323posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006324{
Victor Stinner8c62be82010-05-06 00:08:46 +00006325 WAIT_TYPE status;
6326 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006327
Victor Stinner8c62be82010-05-06 00:08:46 +00006328 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
6329 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006330
Victor Stinner8c62be82010-05-06 00:08:46 +00006331 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006332}
6333#endif /* WIFEXITED */
6334
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006335#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006336PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006337"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006338Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006339
6340static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006341posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006342{
Victor Stinner8c62be82010-05-06 00:08:46 +00006343 WAIT_TYPE status;
6344 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006345
Victor Stinner8c62be82010-05-06 00:08:46 +00006346 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
6347 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006348
Victor Stinner8c62be82010-05-06 00:08:46 +00006349 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006350}
6351#endif /* WEXITSTATUS */
6352
6353#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006354PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006355"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006356Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006357value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006358
6359static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006360posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006361{
Victor Stinner8c62be82010-05-06 00:08:46 +00006362 WAIT_TYPE status;
6363 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006364
Victor Stinner8c62be82010-05-06 00:08:46 +00006365 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
6366 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006367
Victor Stinner8c62be82010-05-06 00:08:46 +00006368 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006369}
6370#endif /* WTERMSIG */
6371
6372#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006373PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006374"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006375Return the signal that stopped the process that provided\n\
6376the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006377
6378static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006379posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006380{
Victor Stinner8c62be82010-05-06 00:08:46 +00006381 WAIT_TYPE status;
6382 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006383
Victor Stinner8c62be82010-05-06 00:08:46 +00006384 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
6385 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006386
Victor Stinner8c62be82010-05-06 00:08:46 +00006387 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006388}
6389#endif /* WSTOPSIG */
6390
6391#endif /* HAVE_SYS_WAIT_H */
6392
6393
Thomas Wouters477c8d52006-05-27 19:21:47 +00006394#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006395#ifdef _SCO_DS
6396/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6397 needed definitions in sys/statvfs.h */
6398#define _SVID3
6399#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006400#include <sys/statvfs.h>
6401
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006402static PyObject*
6403_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006404 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6405 if (v == NULL)
6406 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006407
6408#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006409 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6410 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6411 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
6412 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
6413 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
6414 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
6415 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
6416 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
6417 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6418 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006419#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006420 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6421 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6422 PyStructSequence_SET_ITEM(v, 2,
6423 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
6424 PyStructSequence_SET_ITEM(v, 3,
6425 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
6426 PyStructSequence_SET_ITEM(v, 4,
6427 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
6428 PyStructSequence_SET_ITEM(v, 5,
6429 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
6430 PyStructSequence_SET_ITEM(v, 6,
6431 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
6432 PyStructSequence_SET_ITEM(v, 7,
6433 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
6434 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6435 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006436#endif
6437
Victor Stinner8c62be82010-05-06 00:08:46 +00006438 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006439}
6440
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006441PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006442"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006443Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006444
6445static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006446posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006447{
Victor Stinner8c62be82010-05-06 00:08:46 +00006448 int fd, res;
6449 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006450
Victor Stinner8c62be82010-05-06 00:08:46 +00006451 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
6452 return NULL;
6453 Py_BEGIN_ALLOW_THREADS
6454 res = fstatvfs(fd, &st);
6455 Py_END_ALLOW_THREADS
6456 if (res != 0)
6457 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006458
Victor Stinner8c62be82010-05-06 00:08:46 +00006459 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006460}
Thomas Wouters477c8d52006-05-27 19:21:47 +00006461#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006462
6463
Thomas Wouters477c8d52006-05-27 19:21:47 +00006464#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006465#include <sys/statvfs.h>
6466
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006467PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006468"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006469Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006470
6471static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006472posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006473{
Victor Stinner8c62be82010-05-06 00:08:46 +00006474 char *path;
6475 int res;
6476 struct statvfs st;
6477 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
6478 return NULL;
6479 Py_BEGIN_ALLOW_THREADS
6480 res = statvfs(path, &st);
6481 Py_END_ALLOW_THREADS
6482 if (res != 0)
6483 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006484
Victor Stinner8c62be82010-05-06 00:08:46 +00006485 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006486}
6487#endif /* HAVE_STATVFS */
6488
Fred Drakec9680921999-12-13 16:37:25 +00006489/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6490 * It maps strings representing configuration variable names to
6491 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006492 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006493 * rarely-used constants. There are three separate tables that use
6494 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006495 *
6496 * This code is always included, even if none of the interfaces that
6497 * need it are included. The #if hackery needed to avoid it would be
6498 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006499 */
6500struct constdef {
6501 char *name;
6502 long value;
6503};
6504
Fred Drake12c6e2d1999-12-14 21:25:03 +00006505static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006506conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00006507 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006508{
Christian Heimes217cfd12007-12-02 14:31:20 +00006509 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006510 *valuep = PyLong_AS_LONG(arg);
6511 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006512 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00006513 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00006514 /* look up the value in the table using a binary search */
6515 size_t lo = 0;
6516 size_t mid;
6517 size_t hi = tablesize;
6518 int cmp;
6519 const char *confname;
6520 if (!PyUnicode_Check(arg)) {
6521 PyErr_SetString(PyExc_TypeError,
6522 "configuration names must be strings or integers");
6523 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006524 }
Stefan Krah0e803b32010-11-26 16:16:47 +00006525 confname = _PyUnicode_AsString(arg);
6526 if (confname == NULL)
6527 return 0;
6528 while (lo < hi) {
6529 mid = (lo + hi) / 2;
6530 cmp = strcmp(confname, table[mid].name);
6531 if (cmp < 0)
6532 hi = mid;
6533 else if (cmp > 0)
6534 lo = mid + 1;
6535 else {
6536 *valuep = table[mid].value;
6537 return 1;
6538 }
6539 }
6540 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6541 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006542 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00006543}
6544
6545
6546#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6547static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006548#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006549 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006550#endif
6551#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006552 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006553#endif
Fred Drakec9680921999-12-13 16:37:25 +00006554#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006555 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006556#endif
6557#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00006558 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00006559#endif
6560#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00006561 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00006562#endif
6563#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00006564 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00006565#endif
6566#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006567 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006568#endif
6569#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00006570 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00006571#endif
6572#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00006573 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00006574#endif
6575#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006576 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006577#endif
6578#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006579 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00006580#endif
6581#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006582 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006583#endif
6584#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006585 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00006586#endif
6587#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006588 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006589#endif
6590#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006591 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00006592#endif
6593#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006594 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006595#endif
6596#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00006597 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00006598#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00006599#ifdef _PC_ACL_ENABLED
6600 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
6601#endif
6602#ifdef _PC_MIN_HOLE_SIZE
6603 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
6604#endif
6605#ifdef _PC_ALLOC_SIZE_MIN
6606 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
6607#endif
6608#ifdef _PC_REC_INCR_XFER_SIZE
6609 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
6610#endif
6611#ifdef _PC_REC_MAX_XFER_SIZE
6612 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
6613#endif
6614#ifdef _PC_REC_MIN_XFER_SIZE
6615 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
6616#endif
6617#ifdef _PC_REC_XFER_ALIGN
6618 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
6619#endif
6620#ifdef _PC_SYMLINK_MAX
6621 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
6622#endif
6623#ifdef _PC_XATTR_ENABLED
6624 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
6625#endif
6626#ifdef _PC_XATTR_EXISTS
6627 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
6628#endif
6629#ifdef _PC_TIMESTAMP_RESOLUTION
6630 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
6631#endif
Fred Drakec9680921999-12-13 16:37:25 +00006632};
6633
Fred Drakec9680921999-12-13 16:37:25 +00006634static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006635conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006636{
6637 return conv_confname(arg, valuep, posix_constants_pathconf,
6638 sizeof(posix_constants_pathconf)
6639 / sizeof(struct constdef));
6640}
6641#endif
6642
6643#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006644PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006645"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006646Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006647If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006648
6649static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006650posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006651{
6652 PyObject *result = NULL;
6653 int name, fd;
6654
Fred Drake12c6e2d1999-12-14 21:25:03 +00006655 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6656 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006657 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006658
Stefan Krah0e803b32010-11-26 16:16:47 +00006659 errno = 0;
6660 limit = fpathconf(fd, name);
6661 if (limit == -1 && errno != 0)
6662 posix_error();
6663 else
6664 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006665 }
6666 return result;
6667}
6668#endif
6669
6670
6671#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006672PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006673"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006674Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006675If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006676
6677static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006678posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006679{
6680 PyObject *result = NULL;
6681 int name;
6682 char *path;
6683
6684 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6685 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006686 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006687
Victor Stinner8c62be82010-05-06 00:08:46 +00006688 errno = 0;
6689 limit = pathconf(path, name);
6690 if (limit == -1 && errno != 0) {
6691 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00006692 /* could be a path or name problem */
6693 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00006694 else
Stefan Krah99439262010-11-26 12:58:05 +00006695 posix_error_with_filename(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00006696 }
6697 else
6698 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006699 }
6700 return result;
6701}
6702#endif
6703
6704#ifdef HAVE_CONFSTR
6705static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006706#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00006707 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00006708#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00006709#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006710 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006711#endif
6712#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006713 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006714#endif
Fred Draked86ed291999-12-15 15:34:33 +00006715#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006716 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006717#endif
6718#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006719 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006720#endif
6721#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006722 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006723#endif
6724#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006725 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006726#endif
Fred Drakec9680921999-12-13 16:37:25 +00006727#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006728 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006729#endif
6730#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006731 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006732#endif
6733#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006734 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006735#endif
6736#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006737 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006738#endif
6739#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006740 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006741#endif
6742#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006743 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006744#endif
6745#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006746 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006747#endif
6748#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006749 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006750#endif
Fred Draked86ed291999-12-15 15:34:33 +00006751#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00006752 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00006753#endif
Fred Drakec9680921999-12-13 16:37:25 +00006754#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00006755 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00006756#endif
Fred Draked86ed291999-12-15 15:34:33 +00006757#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006758 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00006759#endif
6760#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006761 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00006762#endif
6763#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006764 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006765#endif
6766#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006767 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00006768#endif
Fred Drakec9680921999-12-13 16:37:25 +00006769#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006770 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006771#endif
6772#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006773 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006774#endif
6775#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006776 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006777#endif
6778#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006779 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006780#endif
6781#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006782 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006783#endif
6784#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006785 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006786#endif
6787#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006788 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006789#endif
6790#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006791 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006792#endif
6793#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006794 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006795#endif
6796#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006797 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006798#endif
6799#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006801#endif
6802#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006803 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006804#endif
6805#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006806 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006807#endif
6808#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006809 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006810#endif
6811#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006812 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006813#endif
6814#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006815 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006816#endif
Fred Draked86ed291999-12-15 15:34:33 +00006817#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006818 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006819#endif
6820#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006821 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00006822#endif
6823#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00006824 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00006825#endif
6826#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006827 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006828#endif
6829#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006830 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006831#endif
6832#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00006833 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00006834#endif
6835#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006836 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00006837#endif
6838#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00006839 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00006840#endif
6841#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006842 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006843#endif
6844#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006845 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006846#endif
6847#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006848 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006849#endif
6850#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006851 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006852#endif
6853#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00006854 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00006855#endif
Fred Drakec9680921999-12-13 16:37:25 +00006856};
6857
6858static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006859conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006860{
6861 return conv_confname(arg, valuep, posix_constants_confstr,
6862 sizeof(posix_constants_confstr)
6863 / sizeof(struct constdef));
6864}
6865
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006866PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006867"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006868Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006869
6870static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006871posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006872{
6873 PyObject *result = NULL;
6874 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00006875 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00006876 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006877
Victor Stinnercb043522010-09-10 23:49:04 +00006878 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
6879 return NULL;
6880
6881 errno = 0;
6882 len = confstr(name, buffer, sizeof(buffer));
6883 if (len == 0) {
6884 if (errno) {
6885 posix_error();
6886 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00006887 }
6888 else {
Victor Stinnercb043522010-09-10 23:49:04 +00006889 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00006890 }
6891 }
Victor Stinnercb043522010-09-10 23:49:04 +00006892
6893 if ((unsigned int)len >= sizeof(buffer)) {
6894 char *buf = PyMem_Malloc(len);
6895 if (buf == NULL)
6896 return PyErr_NoMemory();
6897 confstr(name, buf, len);
6898 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
6899 PyMem_Free(buf);
6900 }
6901 else
6902 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006903 return result;
6904}
6905#endif
6906
6907
6908#ifdef HAVE_SYSCONF
6909static struct constdef posix_constants_sysconf[] = {
6910#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00006911 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00006912#endif
6913#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00006914 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00006915#endif
6916#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006917 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006918#endif
6919#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006920 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006921#endif
6922#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006923 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006924#endif
6925#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00006926 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00006927#endif
6928#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00006929 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00006930#endif
6931#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006932 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006933#endif
6934#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00006935 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00006936#endif
6937#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006938 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006939#endif
Fred Draked86ed291999-12-15 15:34:33 +00006940#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006941 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006942#endif
6943#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00006944 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00006945#endif
Fred Drakec9680921999-12-13 16:37:25 +00006946#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006947 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006948#endif
Fred Drakec9680921999-12-13 16:37:25 +00006949#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006950 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006951#endif
6952#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006953 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006954#endif
6955#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006956 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006957#endif
6958#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006959 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006960#endif
6961#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006962 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006963#endif
Fred Draked86ed291999-12-15 15:34:33 +00006964#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006965 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00006966#endif
Fred Drakec9680921999-12-13 16:37:25 +00006967#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00006968 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006969#endif
6970#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006971 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006972#endif
6973#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006974 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006975#endif
6976#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006977 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006978#endif
6979#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006980 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006981#endif
Fred Draked86ed291999-12-15 15:34:33 +00006982#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00006983 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00006984#endif
Fred Drakec9680921999-12-13 16:37:25 +00006985#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006986 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006987#endif
6988#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006989 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006990#endif
6991#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006992 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006993#endif
6994#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006995 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006996#endif
6997#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006998 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006999#endif
7000#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007001 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00007002#endif
7003#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007004 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007005#endif
7006#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007007 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007008#endif
7009#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00007010 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00007011#endif
7012#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007013 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007014#endif
7015#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007016 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00007017#endif
7018#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007019 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00007020#endif
7021#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007022 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007023#endif
7024#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007025 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007026#endif
7027#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007028 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007029#endif
7030#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007031 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007032#endif
7033#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007034 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00007035#endif
7036#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007037 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007038#endif
7039#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007040 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007041#endif
7042#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00007043 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00007044#endif
7045#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007046 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007047#endif
7048#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007049 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00007050#endif
7051#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007052 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00007053#endif
Fred Draked86ed291999-12-15 15:34:33 +00007054#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00007055 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00007056#endif
Fred Drakec9680921999-12-13 16:37:25 +00007057#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007058 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007059#endif
7060#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007061 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007062#endif
7063#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007064 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007065#endif
Fred Draked86ed291999-12-15 15:34:33 +00007066#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007067 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00007068#endif
Fred Drakec9680921999-12-13 16:37:25 +00007069#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00007070 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00007071#endif
Fred Draked86ed291999-12-15 15:34:33 +00007072#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00007073 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00007074#endif
7075#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00007076 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00007077#endif
Fred Drakec9680921999-12-13 16:37:25 +00007078#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007079 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007080#endif
7081#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007082 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007083#endif
7084#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007085 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007086#endif
7087#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007088 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007089#endif
Fred Draked86ed291999-12-15 15:34:33 +00007090#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00007091 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00007092#endif
Fred Drakec9680921999-12-13 16:37:25 +00007093#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00007094 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00007095#endif
7096#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00007097 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00007098#endif
7099#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007100 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007101#endif
7102#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007103 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00007104#endif
7105#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00007106 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00007107#endif
7108#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00007109 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00007110#endif
7111#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00007112 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00007113#endif
Fred Draked86ed291999-12-15 15:34:33 +00007114#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00007115 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00007116#endif
Fred Drakec9680921999-12-13 16:37:25 +00007117#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007118 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007119#endif
7120#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007121 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007122#endif
Fred Draked86ed291999-12-15 15:34:33 +00007123#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007124 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00007125#endif
Fred Drakec9680921999-12-13 16:37:25 +00007126#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007127 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007128#endif
7129#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007130 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007131#endif
7132#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007133 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007134#endif
7135#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007136 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007137#endif
7138#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007139 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007140#endif
7141#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007142 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007143#endif
7144#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007145 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007146#endif
7147#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007148 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00007149#endif
7150#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00007151 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00007152#endif
Fred Draked86ed291999-12-15 15:34:33 +00007153#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007154 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00007155#endif
7156#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00007157 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00007158#endif
Fred Drakec9680921999-12-13 16:37:25 +00007159#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00007160 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00007161#endif
7162#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007163 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007164#endif
7165#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007166 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007167#endif
7168#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007169 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007170#endif
7171#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007172 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007173#endif
7174#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00007175 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00007176#endif
7177#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00007178 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00007179#endif
7180#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00007181 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00007182#endif
7183#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00007184 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00007185#endif
7186#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00007187 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00007188#endif
7189#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00007190 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00007191#endif
7192#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007193 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00007194#endif
7195#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007196 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00007197#endif
7198#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00007199 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00007200#endif
7201#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00007202 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00007203#endif
7204#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00007205 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00007206#endif
7207#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00007208 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00007209#endif
7210#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007211 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007212#endif
7213#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007214 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007215#endif
7216#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00007217 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00007218#endif
7219#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007220 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007221#endif
7222#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007223 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007224#endif
7225#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00007226 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00007227#endif
7228#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007229 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007230#endif
7231#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007232 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007233#endif
7234#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007235 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00007236#endif
7237#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00007238 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00007239#endif
7240#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007241 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007242#endif
7243#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007244 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007245#endif
7246#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007247 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00007248#endif
7249#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007250 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007251#endif
7252#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007253 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007254#endif
7255#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007256 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007257#endif
7258#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007259 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007260#endif
7261#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007262 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007263#endif
Fred Draked86ed291999-12-15 15:34:33 +00007264#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00007265 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00007266#endif
Fred Drakec9680921999-12-13 16:37:25 +00007267#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00007268 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00007269#endif
7270#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007271 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007272#endif
7273#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00007274 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00007275#endif
7276#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007277 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007278#endif
7279#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007280 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007281#endif
7282#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007283 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007284#endif
7285#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00007286 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00007287#endif
7288#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007289 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007290#endif
7291#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007292 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007293#endif
7294#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007295 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007296#endif
7297#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007298 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007299#endif
7300#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007301 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00007302#endif
7303#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007304 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00007305#endif
7306#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00007307 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00007308#endif
7309#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007310 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007311#endif
7312#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007313 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007314#endif
7315#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007316 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007317#endif
7318#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00007319 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00007320#endif
7321#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007322 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007323#endif
7324#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007325 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007326#endif
7327#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007328 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007329#endif
7330#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007331 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007332#endif
7333#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007334 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007335#endif
7336#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007337 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007338#endif
7339#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00007340 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00007341#endif
7342#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007343 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007344#endif
7345#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007346 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007347#endif
7348#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007349 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007350#endif
7351#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007352 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007353#endif
7354#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00007355 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00007356#endif
7357#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007358 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007359#endif
7360#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00007361 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00007362#endif
7363#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007364 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007365#endif
7366#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00007367 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00007368#endif
7369#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00007370 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00007371#endif
7372#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00007373 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00007374#endif
7375#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00007376 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00007377#endif
7378#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007379 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007380#endif
7381#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00007382 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00007383#endif
7384#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00007385 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00007386#endif
7387#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007388 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007389#endif
7390#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007391 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007392#endif
7393#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00007394 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00007395#endif
7396#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00007397 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00007398#endif
7399#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00007400 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00007401#endif
7402};
7403
7404static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007405conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007406{
7407 return conv_confname(arg, valuep, posix_constants_sysconf,
7408 sizeof(posix_constants_sysconf)
7409 / sizeof(struct constdef));
7410}
7411
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007412PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007413"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007414Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007415
7416static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007417posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007418{
7419 PyObject *result = NULL;
7420 int name;
7421
7422 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7423 int value;
7424
7425 errno = 0;
7426 value = sysconf(name);
7427 if (value == -1 && errno != 0)
7428 posix_error();
7429 else
Christian Heimes217cfd12007-12-02 14:31:20 +00007430 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00007431 }
7432 return result;
7433}
7434#endif
7435
7436
Fred Drakebec628d1999-12-15 18:31:10 +00007437/* This code is used to ensure that the tables of configuration value names
7438 * are in sorted order as required by conv_confname(), and also to build the
7439 * the exported dictionaries that are used to publish information about the
7440 * names available on the host platform.
7441 *
7442 * Sorting the table at runtime ensures that the table is properly ordered
7443 * when used, even for platforms we're not able to test on. It also makes
7444 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007445 */
Fred Drakebec628d1999-12-15 18:31:10 +00007446
7447static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007448cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007449{
7450 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007451 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00007452 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007453 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00007454
7455 return strcmp(c1->name, c2->name);
7456}
7457
7458static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007459setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00007460 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007461{
Fred Drakebec628d1999-12-15 18:31:10 +00007462 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007463 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007464
7465 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7466 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007467 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00007468 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007469
Barry Warsaw3155db32000-04-13 15:20:40 +00007470 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007471 PyObject *o = PyLong_FromLong(table[i].value);
7472 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7473 Py_XDECREF(o);
7474 Py_DECREF(d);
7475 return -1;
7476 }
7477 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007478 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007479 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007480}
7481
Fred Drakebec628d1999-12-15 18:31:10 +00007482/* Return -1 on failure, 0 on success. */
7483static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007484setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007485{
7486#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007487 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007488 sizeof(posix_constants_pathconf)
7489 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007490 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00007491 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007492#endif
7493#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007494 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007495 sizeof(posix_constants_confstr)
7496 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007497 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00007498 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007499#endif
7500#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007501 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007502 sizeof(posix_constants_sysconf)
7503 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007504 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00007505 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007506#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007507 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007508}
Fred Draked86ed291999-12-15 15:34:33 +00007509
7510
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007511PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007512"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007513Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007514in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007515
7516static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007517posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007518{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007519 abort();
7520 /*NOTREACHED*/
7521 Py_FatalError("abort() called from Python code didn't abort!");
7522 return NULL;
7523}
Fred Drakebec628d1999-12-15 18:31:10 +00007524
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007525#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007526PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007527"startfile(filepath [, operation]) - Start a file with its associated\n\
7528application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007529\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007530When \"operation\" is not specified or \"open\", this acts like\n\
7531double-clicking the file in Explorer, or giving the file name as an\n\
7532argument to the DOS \"start\" command: the file is opened with whatever\n\
7533application (if any) its extension is associated.\n\
7534When another \"operation\" is given, it specifies what should be done with\n\
7535the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007536\n\
7537startfile returns as soon as the associated application is launched.\n\
7538There is no option to wait for the application to close, and no way\n\
7539to retrieve the application's exit status.\n\
7540\n\
7541The filepath is relative to the current directory. If you want to use\n\
7542an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007543the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007544
7545static PyObject *
7546win32_startfile(PyObject *self, PyObject *args)
7547{
Victor Stinner8c62be82010-05-06 00:08:46 +00007548 PyObject *ofilepath;
7549 char *filepath;
7550 char *operation = NULL;
7551 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00007552
Victor Stinner8c62be82010-05-06 00:08:46 +00007553 PyObject *unipath, *woperation = NULL;
7554 if (!PyArg_ParseTuple(args, "U|s:startfile",
7555 &unipath, &operation)) {
7556 PyErr_Clear();
7557 goto normal;
7558 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007559
Victor Stinner8c62be82010-05-06 00:08:46 +00007560 if (operation) {
7561 woperation = PyUnicode_DecodeASCII(operation,
7562 strlen(operation), NULL);
7563 if (!woperation) {
7564 PyErr_Clear();
7565 operation = NULL;
7566 goto normal;
7567 }
7568 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007569
Victor Stinner8c62be82010-05-06 00:08:46 +00007570 Py_BEGIN_ALLOW_THREADS
7571 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
7572 PyUnicode_AS_UNICODE(unipath),
7573 NULL, NULL, SW_SHOWNORMAL);
7574 Py_END_ALLOW_THREADS
7575
7576 Py_XDECREF(woperation);
7577 if (rc <= (HINSTANCE)32) {
7578 PyObject *errval = win32_error_unicode("startfile",
7579 PyUnicode_AS_UNICODE(unipath));
7580 return errval;
7581 }
7582 Py_INCREF(Py_None);
7583 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007584
7585normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00007586 if (!PyArg_ParseTuple(args, "O&|s:startfile",
7587 PyUnicode_FSConverter, &ofilepath,
7588 &operation))
7589 return NULL;
7590 filepath = PyBytes_AsString(ofilepath);
7591 Py_BEGIN_ALLOW_THREADS
7592 rc = ShellExecute((HWND)0, operation, filepath,
7593 NULL, NULL, SW_SHOWNORMAL);
7594 Py_END_ALLOW_THREADS
7595 if (rc <= (HINSTANCE)32) {
7596 PyObject *errval = win32_error("startfile", filepath);
7597 Py_DECREF(ofilepath);
7598 return errval;
7599 }
7600 Py_DECREF(ofilepath);
7601 Py_INCREF(Py_None);
7602 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007603}
7604#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007605
Martin v. Löwis438b5342002-12-27 10:16:42 +00007606#ifdef HAVE_GETLOADAVG
7607PyDoc_STRVAR(posix_getloadavg__doc__,
7608"getloadavg() -> (float, float, float)\n\n\
7609Return the number of processes in the system run queue averaged over\n\
7610the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7611was unobtainable");
7612
7613static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007614posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007615{
7616 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007617 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00007618 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7619 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00007620 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00007621 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00007622}
7623#endif
7624
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007625#ifdef MS_WINDOWS
7626
7627PyDoc_STRVAR(win32_urandom__doc__,
7628"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007629Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007630
7631typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7632 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7633 DWORD dwFlags );
7634typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7635 BYTE *pbBuffer );
7636
7637static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00007638/* This handle is never explicitly released. Instead, the operating
7639 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007640static HCRYPTPROV hCryptProv = 0;
7641
Tim Peters4ad82172004-08-30 17:02:04 +00007642static PyObject*
7643win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007644{
Victor Stinner8c62be82010-05-06 00:08:46 +00007645 int howMany;
7646 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007647
Victor Stinner8c62be82010-05-06 00:08:46 +00007648 /* Read arguments */
7649 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7650 return NULL;
7651 if (howMany < 0)
7652 return PyErr_Format(PyExc_ValueError,
7653 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007654
Victor Stinner8c62be82010-05-06 00:08:46 +00007655 if (hCryptProv == 0) {
7656 HINSTANCE hAdvAPI32 = NULL;
7657 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007658
Victor Stinner8c62be82010-05-06 00:08:46 +00007659 /* Obtain handle to the DLL containing CryptoAPI
7660 This should not fail */
7661 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7662 if(hAdvAPI32 == NULL)
7663 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007664
Victor Stinner8c62be82010-05-06 00:08:46 +00007665 /* Obtain pointers to the CryptoAPI functions
7666 This will fail on some early versions of Win95 */
7667 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7668 hAdvAPI32,
7669 "CryptAcquireContextA");
7670 if (pCryptAcquireContext == NULL)
7671 return PyErr_Format(PyExc_NotImplementedError,
7672 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007673
Victor Stinner8c62be82010-05-06 00:08:46 +00007674 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7675 hAdvAPI32, "CryptGenRandom");
7676 if (pCryptGenRandom == NULL)
7677 return PyErr_Format(PyExc_NotImplementedError,
7678 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007679
Victor Stinner8c62be82010-05-06 00:08:46 +00007680 /* Acquire context */
7681 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7682 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7683 return win32_error("CryptAcquireContext", NULL);
7684 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007685
Victor Stinner8c62be82010-05-06 00:08:46 +00007686 /* Allocate bytes */
7687 result = PyBytes_FromStringAndSize(NULL, howMany);
7688 if (result != NULL) {
7689 /* Get random data */
7690 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
7691 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7692 PyBytes_AS_STRING(result))) {
7693 Py_DECREF(result);
7694 return win32_error("CryptGenRandom", NULL);
7695 }
7696 }
7697 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007698}
7699#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007700
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007701PyDoc_STRVAR(device_encoding__doc__,
7702"device_encoding(fd) -> str\n\n\
7703Return a string describing the encoding of the device\n\
7704if the output is a terminal; else return None.");
7705
7706static PyObject *
7707device_encoding(PyObject *self, PyObject *args)
7708{
Victor Stinner8c62be82010-05-06 00:08:46 +00007709 int fd;
7710 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
7711 return NULL;
7712 if (!_PyVerify_fd(fd) || !isatty(fd)) {
7713 Py_INCREF(Py_None);
7714 return Py_None;
7715 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007716#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner8c62be82010-05-06 00:08:46 +00007717 if (fd == 0) {
7718 char buf[100];
7719 sprintf(buf, "cp%d", GetConsoleCP());
7720 return PyUnicode_FromString(buf);
7721 }
7722 if (fd == 1 || fd == 2) {
7723 char buf[100];
7724 sprintf(buf, "cp%d", GetConsoleOutputCP());
7725 return PyUnicode_FromString(buf);
7726 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007727#elif defined(CODESET)
Victor Stinner8c62be82010-05-06 00:08:46 +00007728 {
7729 char *codeset = nl_langinfo(CODESET);
7730 if (codeset != NULL && codeset[0] != 0)
7731 return PyUnicode_FromString(codeset);
7732 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007733#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007734 Py_INCREF(Py_None);
7735 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007736}
7737
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007738#ifdef __VMS
7739/* Use openssl random routine */
7740#include <openssl/rand.h>
7741PyDoc_STRVAR(vms_urandom__doc__,
7742"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007743Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007744
7745static PyObject*
7746vms_urandom(PyObject *self, PyObject *args)
7747{
Victor Stinner8c62be82010-05-06 00:08:46 +00007748 int howMany;
7749 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007750
Victor Stinner8c62be82010-05-06 00:08:46 +00007751 /* Read arguments */
7752 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7753 return NULL;
7754 if (howMany < 0)
7755 return PyErr_Format(PyExc_ValueError,
7756 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007757
Victor Stinner8c62be82010-05-06 00:08:46 +00007758 /* Allocate bytes */
7759 result = PyBytes_FromStringAndSize(NULL, howMany);
7760 if (result != NULL) {
7761 /* Get random data */
7762 if (RAND_pseudo_bytes((unsigned char*)
7763 PyBytes_AS_STRING(result),
7764 howMany) < 0) {
7765 Py_DECREF(result);
7766 return PyErr_Format(PyExc_ValueError,
7767 "RAND_pseudo_bytes");
7768 }
7769 }
7770 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007771}
7772#endif
7773
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007774#ifdef HAVE_SETRESUID
7775PyDoc_STRVAR(posix_setresuid__doc__,
7776"setresuid(ruid, euid, suid)\n\n\
7777Set the current process's real, effective, and saved user ids.");
7778
7779static PyObject*
7780posix_setresuid (PyObject *self, PyObject *args)
7781{
Victor Stinner8c62be82010-05-06 00:08:46 +00007782 /* We assume uid_t is no larger than a long. */
7783 long ruid, euid, suid;
7784 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
7785 return NULL;
7786 if (setresuid(ruid, euid, suid) < 0)
7787 return posix_error();
7788 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007789}
7790#endif
7791
7792#ifdef HAVE_SETRESGID
7793PyDoc_STRVAR(posix_setresgid__doc__,
7794"setresgid(rgid, egid, sgid)\n\n\
7795Set the current process's real, effective, and saved group ids.");
7796
7797static PyObject*
7798posix_setresgid (PyObject *self, PyObject *args)
7799{
Victor Stinner8c62be82010-05-06 00:08:46 +00007800 /* We assume uid_t is no larger than a long. */
7801 long rgid, egid, sgid;
7802 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
7803 return NULL;
7804 if (setresgid(rgid, egid, sgid) < 0)
7805 return posix_error();
7806 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007807}
7808#endif
7809
7810#ifdef HAVE_GETRESUID
7811PyDoc_STRVAR(posix_getresuid__doc__,
7812"getresuid() -> (ruid, euid, suid)\n\n\
7813Get tuple of the current process's real, effective, and saved user ids.");
7814
7815static PyObject*
7816posix_getresuid (PyObject *self, PyObject *noargs)
7817{
Victor Stinner8c62be82010-05-06 00:08:46 +00007818 uid_t ruid, euid, suid;
7819 long l_ruid, l_euid, l_suid;
7820 if (getresuid(&ruid, &euid, &suid) < 0)
7821 return posix_error();
7822 /* Force the values into long's as we don't know the size of uid_t. */
7823 l_ruid = ruid;
7824 l_euid = euid;
7825 l_suid = suid;
7826 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007827}
7828#endif
7829
7830#ifdef HAVE_GETRESGID
7831PyDoc_STRVAR(posix_getresgid__doc__,
7832"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00007833Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007834
7835static PyObject*
7836posix_getresgid (PyObject *self, PyObject *noargs)
7837{
Victor Stinner8c62be82010-05-06 00:08:46 +00007838 uid_t rgid, egid, sgid;
7839 long l_rgid, l_egid, l_sgid;
7840 if (getresgid(&rgid, &egid, &sgid) < 0)
7841 return posix_error();
7842 /* Force the values into long's as we don't know the size of uid_t. */
7843 l_rgid = rgid;
7844 l_egid = egid;
7845 l_sgid = sgid;
7846 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007847}
7848#endif
7849
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007850static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00007851 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007852#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007853 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007854#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007855 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007856#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007857 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007858#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007859 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007860#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007861 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007862#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007863#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007864 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007865#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00007866#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007867 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007868#endif /* HAVE_LCHMOD */
7869#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007870 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007871#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00007872#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007873 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007874#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007875#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007876 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007877#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007878#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +00007879 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00007880#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007881#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +00007882 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007883#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007884#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +00007885 {"getcwd", (PyCFunction)posix_getcwd_unicode,
7886 METH_NOARGS, posix_getcwd__doc__},
7887 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
7888 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007889#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007890#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007891 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007892#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +00007893 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7894 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7895 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007896#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +00007897 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007898#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007899#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007900 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007901#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007902#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007903 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007904#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007905 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7906 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7907 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +00007908 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Brian Curtin52173d42010-12-02 18:29:18 +00007909#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007910 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007911#endif /* HAVE_SYMLINK */
Brian Curtin52173d42010-12-02 18:29:18 +00007912#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +00007913 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
Brian Curtin52173d42010-12-02 18:29:18 +00007914 win_symlink__doc__},
7915#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007916#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +00007917 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007918#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007919 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007920#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007921 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007922#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +00007923 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7924 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7925 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007926#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00007927 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007928#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00007929 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007930#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +00007931 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7932 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007933#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007934#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +00007935 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7936 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007937#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00007938 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7939 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007940#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007941#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007942#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +00007943 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007944#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007945#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +00007946 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007947#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007948#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +00007949 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007950#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007951#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007952 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007953#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007954#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007955 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007956#endif /* HAVE_GETEGID */
7957#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007958 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007959#endif /* HAVE_GETEUID */
7960#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007961 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007962#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007963#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007964 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007965#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007966 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007967#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007968 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007969#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007970#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +00007971 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007972#endif /* HAVE_GETPPID */
7973#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007974 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007975#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007976#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007977 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007978#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007979#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +00007980 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007981#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007982#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +00007983 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007984#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007985#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007986 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007987#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007988#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007989 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7990 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Brian Curtin1b9df392010-11-24 20:24:31 +00007991 {"link", win32_link, METH_VARARGS, win32_link__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +00007992#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007993#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007994 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007995#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007996#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007997 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007998#endif /* HAVE_SETEUID */
7999#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008000 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008001#endif /* HAVE_SETEGID */
8002#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008003 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008004#endif /* HAVE_SETREUID */
8005#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008006 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008007#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008008#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008009 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008010#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008011#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00008012 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008013#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +00008014#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00008015 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +00008016#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008017#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008018 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00008019#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008020#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00008021 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008022#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008023#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008024 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008025#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008026#ifdef HAVE_WAIT3
Victor Stinner8c62be82010-05-06 00:08:46 +00008027 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008028#endif /* HAVE_WAIT3 */
8029#ifdef HAVE_WAIT4
Victor Stinner8c62be82010-05-06 00:08:46 +00008030 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008031#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008032#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008033 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008034#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008035#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00008036 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008037#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008038#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00008039 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008040#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008041#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008042 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008043#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008044#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00008045 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008046#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008047#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00008048 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008049#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +00008050 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8051 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8052 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
8053 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
8054 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8055 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8056 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8057 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8058 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8059 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8060 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008061#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +00008062 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008063#endif
8064#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +00008065 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008066#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008067#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +00008068 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008069#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008070#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +00008071 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8072 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8073 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008074#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008075#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +00008076 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008077#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008078#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00008079 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008080#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008081#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +00008082 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00008083#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008084 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008085#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +00008086 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008087#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008088#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008089 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008090#endif
8091#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008092 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008093#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008094#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008095#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +00008096 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00008097#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008098#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00008099 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008100#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008101#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +00008102 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008103#endif /* WIFSTOPPED */
8104#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +00008105 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008106#endif /* WIFSIGNALED */
8107#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +00008108 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008109#endif /* WIFEXITED */
8110#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +00008111 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008112#endif /* WEXITSTATUS */
8113#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008114 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008115#endif /* WTERMSIG */
8116#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008117 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008118#endif /* WSTOPSIG */
8119#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008120#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00008121 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008122#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00008123#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00008124 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008125#endif
Fred Drakec9680921999-12-13 16:37:25 +00008126#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +00008127 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008128#endif
8129#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008130 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008131#endif
8132#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008133 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008134#endif
8135#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008136 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008137#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008138 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008139#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008140 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +00008141 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +00008142 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -05008143 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00008144#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008145#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +00008146 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008147#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008148 #ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008149 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008150 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008151 #ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008152 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008153 #endif
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008154#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008155 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008156#endif
8157#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008158 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008159#endif
8160#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008161 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008162#endif
8163#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008164 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008165#endif
8166
Victor Stinner8c62be82010-05-06 00:08:46 +00008167 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008168};
8169
8170
Barry Warsaw4a342091996-12-19 23:50:02 +00008171static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008172ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008173{
Victor Stinner8c62be82010-05-06 00:08:46 +00008174 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008175}
8176
Guido van Rossumd48f2521997-12-05 22:19:34 +00008177#if defined(PYOS_OS2)
8178/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008179static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008180{
8181 APIRET rc;
8182 ULONG values[QSV_MAX+1];
8183 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008184 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008185
8186 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008187 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008188 Py_END_ALLOW_THREADS
8189
8190 if (rc != NO_ERROR) {
8191 os2_error(rc);
8192 return -1;
8193 }
8194
Fred Drake4d1e64b2002-04-15 19:40:07 +00008195 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8196 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8197 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8198 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8199 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8200 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8201 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008202
8203 switch (values[QSV_VERSION_MINOR]) {
8204 case 0: ver = "2.00"; break;
8205 case 10: ver = "2.10"; break;
8206 case 11: ver = "2.11"; break;
8207 case 30: ver = "3.00"; break;
8208 case 40: ver = "4.00"; break;
8209 case 50: ver = "5.00"; break;
8210 default:
Tim Peters885d4572001-11-28 20:27:42 +00008211 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +00008212 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00008213 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008214 ver = &tmp[0];
8215 }
8216
8217 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008218 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008219 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008220
8221 /* Add Indicator of Which Drive was Used to Boot the System */
8222 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8223 tmp[1] = ':';
8224 tmp[2] = '\0';
8225
Fred Drake4d1e64b2002-04-15 19:40:07 +00008226 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008227}
8228#endif
8229
Brian Curtin52173d42010-12-02 18:29:18 +00008230#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +00008231static int
Brian Curtin52173d42010-12-02 18:29:18 +00008232enable_symlink()
8233{
8234 HANDLE tok;
8235 TOKEN_PRIVILEGES tok_priv;
8236 LUID luid;
8237 int meth_idx = 0;
8238
8239 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +00008240 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +00008241
8242 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +00008243 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +00008244
8245 tok_priv.PrivilegeCount = 1;
8246 tok_priv.Privileges[0].Luid = luid;
8247 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
8248
8249 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
8250 sizeof(TOKEN_PRIVILEGES),
8251 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +00008252 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +00008253
Brian Curtin3b4499c2010-12-28 14:31:47 +00008254 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
8255 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +00008256}
8257#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
8258
Barry Warsaw4a342091996-12-19 23:50:02 +00008259static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008260all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008261{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008262#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008263 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008264#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008265#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008266 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008267#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008268#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008269 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008270#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008271#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008272 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008273#endif
Fred Drakec9680921999-12-13 16:37:25 +00008274#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008275 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00008276#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008277#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008278 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008279#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008280#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00008281 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008282#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008283#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +00008284 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008285#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008286#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +00008287 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008288#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008289#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008290 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008291#endif
8292#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008293 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008294#endif
8295#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +00008296 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008297#endif
8298#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +00008299 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008300#endif
8301#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008302 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008303#endif
8304#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +00008305 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008306#endif
8307#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008308 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008309#endif
8310#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008311 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008312#endif
8313#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008314 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008315#endif
8316#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +00008317 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008318#endif
8319#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008320 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008321#endif
8322#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +00008323 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008324#endif
8325#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008326 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008327#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008328#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008329 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008330#endif
8331#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +00008332 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008333#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008334#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008335 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008336#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008337#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008338 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008339#endif
8340#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008341 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008342#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008343
Tim Peters5aa91602002-01-30 05:46:57 +00008344/* MS Windows */
8345#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008346 /* Don't inherit in child processes. */
8347 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008348#endif
8349#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +00008350 /* Optimize for short life (keep in memory). */
8351 /* MS forgot to define this one with a non-underscore form too. */
8352 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008353#endif
8354#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008355 /* Automatically delete when last handle is closed. */
8356 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008357#endif
8358#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +00008359 /* Optimize for random access. */
8360 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008361#endif
8362#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008363 /* Optimize for sequential access. */
8364 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008365#endif
8366
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008367/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008368#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008369 /* Send a SIGIO signal whenever input or output
8370 becomes available on file descriptor */
8371 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008372#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008373#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008374 /* Direct disk access. */
8375 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008376#endif
8377#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +00008378 /* Must be a directory. */
8379 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008380#endif
8381#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +00008382 /* Do not follow links. */
8383 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008384#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008385#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +00008386 /* Do not update the access time. */
8387 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008388#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008389
Victor Stinner8c62be82010-05-06 00:08:46 +00008390 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008391#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008392 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008393#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008394#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008395 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008396#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008397#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008398 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008399#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008400#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008401 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008402#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008403#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +00008404 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008405#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008406#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +00008407 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008408#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008409#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008410 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008411#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008412#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +00008413 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008414#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008415#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008416 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008417#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008418#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008419 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008420#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008421#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008422 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008423#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008424#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008425 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008426#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008427#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +00008428 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008429#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008430#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +00008431 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008432#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008433#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008434 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008435#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008436#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008437 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008438#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008439#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +00008440 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008441#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008442
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008443 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008444#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008445 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008446#endif /* ST_RDONLY */
8447#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008448 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008449#endif /* ST_NOSUID */
8450
Guido van Rossum246bc171999-02-01 23:54:31 +00008451#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008452#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00008453 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8454 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8455 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8456 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8457 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8458 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8459 if (ins(d, "P_PM", (long)P_PM)) return -1;
8460 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8461 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8462 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8463 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8464 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8465 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8466 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8467 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8468 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8469 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8470 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8471 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8472 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008473#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008474 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8475 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8476 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8477 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8478 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008479#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008480#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008481
Guido van Rossumd48f2521997-12-05 22:19:34 +00008482#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00008483 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008484#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008485 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00008486}
8487
8488
Tim Peters5aa91602002-01-30 05:46:57 +00008489#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008490#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008491#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008492
8493#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008494#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008495#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008496
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008497#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00008498#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008499#define MODNAME "posix"
8500#endif
8501
Martin v. Löwis1a214512008-06-11 05:26:20 +00008502static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +00008503 PyModuleDef_HEAD_INIT,
8504 MODNAME,
8505 posix__doc__,
8506 -1,
8507 posix_methods,
8508 NULL,
8509 NULL,
8510 NULL,
8511 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00008512};
8513
8514
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008515PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008516INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008517{
Victor Stinner8c62be82010-05-06 00:08:46 +00008518 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008519
Brian Curtin52173d42010-12-02 18:29:18 +00008520#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +00008521 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +00008522#endif
8523
Victor Stinner8c62be82010-05-06 00:08:46 +00008524 m = PyModule_Create(&posixmodule);
8525 if (m == NULL)
8526 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008527
Victor Stinner8c62be82010-05-06 00:08:46 +00008528 /* Initialize environ dictionary */
8529 v = convertenviron();
8530 Py_XINCREF(v);
8531 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
8532 return NULL;
8533 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008534
Victor Stinner8c62be82010-05-06 00:08:46 +00008535 if (all_ins(m))
8536 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00008537
Victor Stinner8c62be82010-05-06 00:08:46 +00008538 if (setup_confname_tables(m))
8539 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00008540
Victor Stinner8c62be82010-05-06 00:08:46 +00008541 Py_INCREF(PyExc_OSError);
8542 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008543
Guido van Rossumb3d39562000-01-31 18:41:26 +00008544#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00008545 if (posix_putenv_garbage == NULL)
8546 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008547#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008548
Victor Stinner8c62be82010-05-06 00:08:46 +00008549 if (!initialized) {
8550 stat_result_desc.name = MODNAME ".stat_result";
8551 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8552 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8553 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8554 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8555 structseq_new = StatResultType.tp_new;
8556 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008557
Victor Stinner8c62be82010-05-06 00:08:46 +00008558 statvfs_result_desc.name = MODNAME ".statvfs_result";
8559 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008560#ifdef NEED_TICKS_PER_SECOND
8561# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +00008562 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008563# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +00008564 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008565# else
Victor Stinner8c62be82010-05-06 00:08:46 +00008566 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008567# endif
8568#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008569 }
8570 Py_INCREF((PyObject*) &StatResultType);
8571 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
8572 Py_INCREF((PyObject*) &StatVFSResultType);
8573 PyModule_AddObject(m, "statvfs_result",
8574 (PyObject*) &StatVFSResultType);
8575 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008576
8577#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +00008578 /*
8579 * Step 2 of weak-linking support on Mac OS X.
8580 *
8581 * The code below removes functions that are not available on the
8582 * currently active platform.
8583 *
8584 * This block allow one to use a python binary that was build on
8585 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8586 * OSX 10.4.
8587 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008588#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008589 if (fstatvfs == NULL) {
8590 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8591 return NULL;
8592 }
8593 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008594#endif /* HAVE_FSTATVFS */
8595
8596#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008597 if (statvfs == NULL) {
8598 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8599 return NULL;
8600 }
8601 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008602#endif /* HAVE_STATVFS */
8603
8604# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00008605 if (lchown == NULL) {
8606 if (PyObject_DelAttrString(m, "lchown") == -1) {
8607 return NULL;
8608 }
8609 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008610#endif /* HAVE_LCHOWN */
8611
8612
8613#endif /* __APPLE__ */
Victor Stinner8c62be82010-05-06 00:08:46 +00008614 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008615
Guido van Rossumb6775db1994-08-01 11:34:53 +00008616}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008617
8618#ifdef __cplusplus
8619}
8620#endif