blob: a93aa6a4fa103818748a7c42aecb7c954ea11cdf [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Thomas Wouters477c8d52006-05-27 19:21:47 +000016#ifdef __APPLE__
17 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000018 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000019 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
20 * at the end of this file for more information.
21 */
22# pragma weak lchown
23# pragma weak statvfs
24# pragma weak fstatvfs
25
26#endif /* __APPLE__ */
27
Thomas Wouters68bc4f92006-03-01 01:05:10 +000028#define PY_SSIZE_T_CLEAN
29
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000030#include "Python.h"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000031
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000032#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000034#endif /* defined(__VMS) */
35
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000036#ifdef __cplusplus
37extern "C" {
38#endif
39
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000040PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000041"This module provides access to operating system functionality that is\n\
42standardized by the C Standard and the POSIX standard (a thinly\n\
43disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000044corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000045
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000046
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000047#if defined(PYOS_OS2)
48#define INCL_DOS
49#define INCL_DOSERRORS
50#define INCL_DOSPROCESS
51#define INCL_NOPMAPI
52#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000053#if defined(PYCC_GCC)
54#include <ctype.h>
55#include <io.h>
56#include <stdio.h>
57#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000058#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000059#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000060#endif
61
Thomas Wouters0e3f5912006-08-11 14:57:12 +000062#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000063#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#endif /* HAVE_SYS_TYPES_H */
65
66#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000067#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000068#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000069
Guido van Rossum36bc6801995-06-14 22:54:23 +000070#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000071#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000072#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000073
Thomas Wouters0e3f5912006-08-11 14:57:12 +000074#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000075#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000076#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000077
Guido van Rossumb6775db1994-08-01 11:34:53 +000078#ifdef HAVE_FCNTL_H
79#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000080#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000081
Guido van Rossuma6535fd2001-10-18 19:44:10 +000082#ifdef HAVE_GRP_H
83#include <grp.h>
84#endif
85
Barry Warsaw5676bd12003-01-07 20:57:09 +000086#ifdef HAVE_SYSEXITS_H
87#include <sysexits.h>
88#endif /* HAVE_SYSEXITS_H */
89
Anthony Baxter8a560de2004-10-13 15:30:56 +000090#ifdef HAVE_SYS_LOADAVG_H
91#include <sys/loadavg.h>
92#endif
93
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000094#ifdef HAVE_LANGINFO_H
95#include <langinfo.h>
96#endif
97
Guido van Rossuma4916fa1996-05-23 22:58:55 +000098/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000099/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000100#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000101#include <process.h>
102#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000103#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000104#define HAVE_GETCWD 1
105#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000106#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000107#if defined(__OS2__)
108#define HAVE_EXECV 1
109#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000110#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000111#include <process.h>
112#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000113#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000114#define HAVE_EXECV 1
115#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000116#define HAVE_OPENDIR 1
117#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000118#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000119#define HAVE_WAIT 1
120#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000121#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000122#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000123#define HAVE_GETPPID 1
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000124#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000125#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000126#define HAVE_EXECV 1
127#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000128#define HAVE_SYSTEM 1
129#define HAVE_CWAIT 1
130#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000131#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000132#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000133#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
134/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000135#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000136/* Unix functions that the configure script doesn't check for */
137#define HAVE_EXECV 1
138#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000139#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000140#define HAVE_FORK1 1
141#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000142#define HAVE_GETCWD 1
143#define HAVE_GETEGID 1
144#define HAVE_GETEUID 1
145#define HAVE_GETGID 1
146#define HAVE_GETPPID 1
147#define HAVE_GETUID 1
148#define HAVE_KILL 1
149#define HAVE_OPENDIR 1
150#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000151#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000152#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000153#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000154#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#endif /* _MSC_VER */
156#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000157#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000158#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000159
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000161
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000162#if defined(__sgi)&&_COMPILER_VERSION>=700
163/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
164 (default) */
165extern char *ctermid_r(char *);
166#endif
167
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000168#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000169#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000170extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000171#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000172#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000173extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000174#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000175extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000176#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000177#endif
178#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000179extern int chdir(char *);
180extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000181#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000182extern int chdir(const char *);
183extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000184#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000185#ifdef __BORLANDC__
186extern int chmod(const char *, int);
187#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000188extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000189#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000190/*#ifdef HAVE_FCHMOD
191extern int fchmod(int, mode_t);
192#endif*/
193/*#ifdef HAVE_LCHMOD
194extern int lchmod(const char *, mode_t);
195#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000196extern int chown(const char *, uid_t, gid_t);
197extern char *getcwd(char *, int);
198extern char *strerror(int);
199extern int link(const char *, const char *);
200extern int rename(const char *, const char *);
201extern int stat(const char *, struct stat *);
202extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000203#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000204extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000205#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000206#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000207extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000208#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000210
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000211#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000212
Guido van Rossumb6775db1994-08-01 11:34:53 +0000213#ifdef HAVE_UTIME_H
214#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000215#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000216
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000217#ifdef HAVE_SYS_UTIME_H
218#include <sys/utime.h>
219#define HAVE_UTIME_H /* pretend we do for the rest of this file */
220#endif /* HAVE_SYS_UTIME_H */
221
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222#ifdef HAVE_SYS_TIMES_H
223#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000224#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000225
226#ifdef HAVE_SYS_PARAM_H
227#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000228#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000229
230#ifdef HAVE_SYS_UTSNAME_H
231#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000232#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000233
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000234#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000236#define NAMLEN(dirent) strlen((dirent)->d_name)
237#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000238#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000239#include <direct.h>
240#define NAMLEN(dirent) strlen((dirent)->d_name)
241#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000243#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000244#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000245#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000246#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000247#endif
248#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000249#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000250#endif
251#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000253#endif
254#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000256#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000257#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000259#endif
260#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000261#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000262#endif
263#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000265#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000266#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000267#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000268#endif
269#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000270#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000271#endif
272#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000273#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000274#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000275#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000276#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000278#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000279#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000280#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
281#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000282static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000283#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000284#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000285
Guido van Rossumd48f2521997-12-05 22:19:34 +0000286#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000288#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000289
Tim Petersbc2e10e2002-03-03 23:17:02 +0000290#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000291#if defined(PATH_MAX) && PATH_MAX > 1024
292#define MAXPATHLEN PATH_MAX
293#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000294#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000295#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000296#endif /* MAXPATHLEN */
297
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000298#ifdef UNION_WAIT
299/* Emulate some macros on systems that have a union instead of macros */
300
301#ifndef WIFEXITED
302#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
303#endif
304
305#ifndef WEXITSTATUS
306#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
307#endif
308
309#ifndef WTERMSIG
310#define WTERMSIG(u_wait) ((u_wait).w_termsig)
311#endif
312
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000313#define WAIT_TYPE union wait
314#define WAIT_STATUS_INT(s) (s.w_status)
315
316#else /* !UNION_WAIT */
317#define WAIT_TYPE int
318#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000319#endif /* UNION_WAIT */
320
Greg Wardb48bc172000-03-01 21:51:56 +0000321/* Don't use the "_r" form if we don't need it (also, won't have a
322 prototype for it, at least on Solaris -- maybe others as well?). */
323#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
324#define USE_CTERMID_R
325#endif
326
Fred Drake699f3522000-06-29 21:12:41 +0000327/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000328#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000329#undef FSTAT
330#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000331#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000332# define STAT win32_stat
333# define FSTAT win32_fstat
334# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000335#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000336# define STAT stat
337# define FSTAT fstat
338# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000339#endif
340
Tim Peters11b23062003-04-23 02:39:17 +0000341#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000342#include <sys/mkdev.h>
343#else
344#if defined(MAJOR_IN_SYSMACROS)
345#include <sys/sysmacros.h>
346#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000347#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
348#include <sys/mkdev.h>
349#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000350#endif
Fred Drake699f3522000-06-29 21:12:41 +0000351
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000352#if defined _MSC_VER && _MSC_VER >= 1400
353/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
354 * valid and throw an assertion if it isn't.
355 * Normally, an invalid fd is likely to be a C program error and therefore
356 * an assertion can be useful, but it does contradict the POSIX standard
357 * which for write(2) states:
358 * "Otherwise, -1 shall be returned and errno set to indicate the error."
359 * "[EBADF] The fildes argument is not a valid file descriptor open for
360 * writing."
361 * Furthermore, python allows the user to enter any old integer
362 * as a fd and should merely raise a python exception on error.
363 * The Microsoft CRT doesn't provide an official way to check for the
364 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000365 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000366 * internal structures involved.
367 * The structures below must be updated for each version of visual studio
368 * according to the file internal.h in the CRT source, until MS comes
369 * up with a less hacky way to do this.
370 * (all of this is to avoid globally modifying the CRT behaviour using
371 * _set_invalid_parameter_handler() and _CrtSetReportMode())
372 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000373/* The actual size of the structure is determined at runtime.
374 * Only the first items must be present.
375 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000376typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000377 intptr_t osfhnd;
378 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000379} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000380
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000381extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000382#define IOINFO_L2E 5
383#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
384#define IOINFO_ARRAYS 64
385#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
386#define FOPEN 0x01
387#define _NO_CONSOLE_FILENO (intptr_t)-2
388
389/* This function emulates what the windows CRT does to validate file handles */
390int
391_PyVerify_fd(int fd)
392{
Victor Stinner8c62be82010-05-06 00:08:46 +0000393 const int i1 = fd >> IOINFO_L2E;
394 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000395
Antoine Pitrou22e41552010-08-15 18:07:50 +0000396 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000397
Victor Stinner8c62be82010-05-06 00:08:46 +0000398 /* Determine the actual size of the ioinfo structure,
399 * as used by the CRT loaded in memory
400 */
401 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
402 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
403 }
404 if (sizeof_ioinfo == 0) {
405 /* This should not happen... */
406 goto fail;
407 }
408
409 /* See that it isn't a special CLEAR fileno */
410 if (fd != _NO_CONSOLE_FILENO) {
411 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
412 * we check pointer validity and other info
413 */
414 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
415 /* finally, check that the file is open */
416 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
417 if (info->osfile & FOPEN) {
418 return 1;
419 }
420 }
421 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000422 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000423 errno = EBADF;
424 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000425}
426
427/* the special case of checking dup2. The target fd must be in a sensible range */
428static int
429_PyVerify_fd_dup2(int fd1, int fd2)
430{
Victor Stinner8c62be82010-05-06 00:08:46 +0000431 if (!_PyVerify_fd(fd1))
432 return 0;
433 if (fd2 == _NO_CONSOLE_FILENO)
434 return 0;
435 if ((unsigned)fd2 < _NHANDLE_)
436 return 1;
437 else
438 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000439}
440#else
441/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
442#define _PyVerify_fd_dup2(A, B) (1)
443#endif
444
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000445#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000446/* The following structure was copied from
447 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
448 include doesn't seem to be present in the Windows SDK (at least as included
449 with Visual Studio Express). */
450typedef struct _REPARSE_DATA_BUFFER {
451 ULONG ReparseTag;
452 USHORT ReparseDataLength;
453 USHORT Reserved;
454 union {
455 struct {
456 USHORT SubstituteNameOffset;
457 USHORT SubstituteNameLength;
458 USHORT PrintNameOffset;
459 USHORT PrintNameLength;
460 ULONG Flags;
461 WCHAR PathBuffer[1];
462 } SymbolicLinkReparseBuffer;
463
464 struct {
465 USHORT SubstituteNameOffset;
466 USHORT SubstituteNameLength;
467 USHORT PrintNameOffset;
468 USHORT PrintNameLength;
469 WCHAR PathBuffer[1];
470 } MountPointReparseBuffer;
471
472 struct {
473 UCHAR DataBuffer[1];
474 } GenericReparseBuffer;
475 };
476} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
477
478#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
479 GenericReparseBuffer)
480#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
481
482static int
Brian Curtind25aef52011-06-13 15:16:04 -0500483win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +0000484{
485 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
486 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
487 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000488
489 if (0 == DeviceIoControl(
490 reparse_point_handle,
491 FSCTL_GET_REPARSE_POINT,
492 NULL, 0, /* in buffer */
493 target_buffer, sizeof(target_buffer),
494 &n_bytes_returned,
495 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -0500496 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000497
498 if (reparse_tag)
499 *reparse_tag = rdb->ReparseTag;
500
Brian Curtind25aef52011-06-13 15:16:04 -0500501 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000502}
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000503#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000504
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000505/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000506#ifdef WITH_NEXT_FRAMEWORK
507/* On Darwin/MacOSX a shared library or framework has no access to
508** environ directly, we must obtain it with _NSGetEnviron().
509*/
510#include <crt_externs.h>
511static char **environ;
512#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000513extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000514#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000515
Barry Warsaw53699e91996-12-10 23:23:01 +0000516static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000517convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000518{
Victor Stinner8c62be82010-05-06 00:08:46 +0000519 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000520#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000521 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000522#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000523 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000524#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000525#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000526 APIRET rc;
527 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
528#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000529
Victor Stinner8c62be82010-05-06 00:08:46 +0000530 d = PyDict_New();
531 if (d == NULL)
532 return NULL;
533#ifdef WITH_NEXT_FRAMEWORK
534 if (environ == NULL)
535 environ = *_NSGetEnviron();
536#endif
537#ifdef MS_WINDOWS
538 /* _wenviron must be initialized in this way if the program is started
539 through main() instead of wmain(). */
540 _wgetenv(L"");
541 if (_wenviron == NULL)
542 return d;
543 /* This part ignores errors */
544 for (e = _wenviron; *e != NULL; e++) {
545 PyObject *k;
546 PyObject *v;
547 wchar_t *p = wcschr(*e, L'=');
548 if (p == NULL)
549 continue;
550 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
551 if (k == NULL) {
552 PyErr_Clear();
553 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000554 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000555 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
556 if (v == NULL) {
557 PyErr_Clear();
558 Py_DECREF(k);
559 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000560 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000561 if (PyDict_GetItem(d, k) == NULL) {
562 if (PyDict_SetItem(d, k, v) != 0)
563 PyErr_Clear();
564 }
565 Py_DECREF(k);
566 Py_DECREF(v);
567 }
568#else
569 if (environ == NULL)
570 return d;
571 /* This part ignores errors */
572 for (e = environ; *e != NULL; e++) {
573 PyObject *k;
574 PyObject *v;
575 char *p = strchr(*e, '=');
576 if (p == NULL)
577 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000578 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000579 if (k == NULL) {
580 PyErr_Clear();
581 continue;
582 }
Victor Stinner84ae1182010-05-06 22:05:07 +0000583 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +0000584 if (v == NULL) {
585 PyErr_Clear();
586 Py_DECREF(k);
587 continue;
588 }
589 if (PyDict_GetItem(d, k) == NULL) {
590 if (PyDict_SetItem(d, k, v) != 0)
591 PyErr_Clear();
592 }
593 Py_DECREF(k);
594 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000595 }
596#endif
Victor Stinner8c62be82010-05-06 00:08:46 +0000597#if defined(PYOS_OS2)
598 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
599 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
600 PyObject *v = PyBytes_FromString(buffer);
601 PyDict_SetItemString(d, "BEGINLIBPATH", v);
602 Py_DECREF(v);
603 }
604 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
605 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
606 PyObject *v = PyBytes_FromString(buffer);
607 PyDict_SetItemString(d, "ENDLIBPATH", v);
608 Py_DECREF(v);
609 }
610#endif
611 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000612}
613
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000614/* Set a POSIX-specific error from errno, and return NULL */
615
Barry Warsawd58d7641998-07-23 16:14:40 +0000616static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000617posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000618{
Victor Stinner8c62be82010-05-06 00:08:46 +0000619 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000620}
Barry Warsawd58d7641998-07-23 16:14:40 +0000621static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000622posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000623{
Victor Stinner8c62be82010-05-06 00:08:46 +0000624 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000625}
626
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000627
Mark Hammondef8b6542001-05-13 08:04:26 +0000628static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000629posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000630{
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000631 PyObject *name_str, *rc;
632 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
633 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +0000634 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000635 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
636 name_str);
637 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +0000638 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000639}
640
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000641#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000642static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +0000643win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000644{
Victor Stinner8c62be82010-05-06 00:08:46 +0000645 /* XXX We should pass the function name along in the future.
646 (winreg.c also wants to pass the function name.)
647 This would however require an additional param to the
648 Windows error object, which is non-trivial.
649 */
650 errno = GetLastError();
651 if (filename)
652 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
653 else
654 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000655}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000656
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000657static PyObject *
658win32_error_unicode(char* function, Py_UNICODE* filename)
659{
Victor Stinner8c62be82010-05-06 00:08:46 +0000660 /* XXX - see win32_error for comments on 'function' */
661 errno = GetLastError();
662 if (filename)
663 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
664 else
665 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000666}
667
Thomas Wouters477c8d52006-05-27 19:21:47 +0000668static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000669convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000670{
Victor Stinner8c62be82010-05-06 00:08:46 +0000671 if (PyUnicode_CheckExact(*param))
672 Py_INCREF(*param);
673 else if (PyUnicode_Check(*param))
674 /* For a Unicode subtype that's not a Unicode object,
675 return a true Unicode object with the same data. */
676 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
677 PyUnicode_GET_SIZE(*param));
678 else
679 *param = PyUnicode_FromEncodedObject(*param,
680 Py_FileSystemDefaultEncoding,
681 "strict");
682 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000683}
684
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000685#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000686
Guido van Rossumd48f2521997-12-05 22:19:34 +0000687#if defined(PYOS_OS2)
688/**********************************************************************
689 * Helper Function to Trim and Format OS/2 Messages
690 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000691static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000692os2_formatmsg(char *msgbuf, int msglen, char *reason)
693{
694 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
695
696 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
697 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
698
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000699 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000700 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
701 }
702
703 /* Add Optional Reason Text */
704 if (reason) {
705 strcat(msgbuf, " : ");
706 strcat(msgbuf, reason);
707 }
708}
709
710/**********************************************************************
711 * Decode an OS/2 Operating System Error Code
712 *
713 * A convenience function to lookup an OS/2 error code and return a
714 * text message we can use to raise a Python exception.
715 *
716 * Notes:
717 * The messages for errors returned from the OS/2 kernel reside in
718 * the file OSO001.MSG in the \OS2 directory hierarchy.
719 *
720 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000721static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000722os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
723{
724 APIRET rc;
725 ULONG msglen;
726
727 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
728 Py_BEGIN_ALLOW_THREADS
729 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
730 errorcode, "oso001.msg", &msglen);
731 Py_END_ALLOW_THREADS
732
733 if (rc == NO_ERROR)
734 os2_formatmsg(msgbuf, msglen, reason);
735 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000736 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +0000737 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000738
739 return msgbuf;
740}
741
742/* Set an OS/2-specific error and return NULL. OS/2 kernel
743 errors are not in a global variable e.g. 'errno' nor are
744 they congruent with posix error numbers. */
745
Victor Stinner8c62be82010-05-06 00:08:46 +0000746static PyObject *
747os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000748{
749 char text[1024];
750 PyObject *v;
751
752 os2_strerror(text, sizeof(text), code, "");
753
754 v = Py_BuildValue("(is)", code, text);
755 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000756 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000757 Py_DECREF(v);
758 }
759 return NULL; /* Signal to Python that an Exception is Pending */
760}
761
762#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000763
764/* POSIX generic methods */
765
Barry Warsaw53699e91996-12-10 23:23:01 +0000766static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000767posix_fildes(PyObject *fdobj, int (*func)(int))
768{
Victor Stinner8c62be82010-05-06 00:08:46 +0000769 int fd;
770 int res;
771 fd = PyObject_AsFileDescriptor(fdobj);
772 if (fd < 0)
773 return NULL;
774 if (!_PyVerify_fd(fd))
775 return posix_error();
776 Py_BEGIN_ALLOW_THREADS
777 res = (*func)(fd);
778 Py_END_ALLOW_THREADS
779 if (res < 0)
780 return posix_error();
781 Py_INCREF(Py_None);
782 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000783}
Guido van Rossum21142a01999-01-08 21:05:37 +0000784
785static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000786posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000787{
Victor Stinner8c62be82010-05-06 00:08:46 +0000788 PyObject *opath1 = NULL;
789 char *path1;
790 int res;
791 if (!PyArg_ParseTuple(args, format,
792 PyUnicode_FSConverter, &opath1))
793 return NULL;
794 path1 = PyBytes_AsString(opath1);
795 Py_BEGIN_ALLOW_THREADS
796 res = (*func)(path1);
797 Py_END_ALLOW_THREADS
798 if (res < 0)
799 return posix_error_with_allocated_filename(opath1);
800 Py_DECREF(opath1);
801 Py_INCREF(Py_None);
802 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000803}
804
Barry Warsaw53699e91996-12-10 23:23:01 +0000805static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000806posix_2str(PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +0000807 char *format,
808 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000809{
Victor Stinner8c62be82010-05-06 00:08:46 +0000810 PyObject *opath1 = NULL, *opath2 = NULL;
811 char *path1, *path2;
812 int res;
813 if (!PyArg_ParseTuple(args, format,
814 PyUnicode_FSConverter, &opath1,
815 PyUnicode_FSConverter, &opath2)) {
816 return NULL;
817 }
818 path1 = PyBytes_AsString(opath1);
819 path2 = PyBytes_AsString(opath2);
820 Py_BEGIN_ALLOW_THREADS
821 res = (*func)(path1, path2);
822 Py_END_ALLOW_THREADS
823 Py_DECREF(opath1);
824 Py_DECREF(opath2);
825 if (res != 0)
826 /* XXX how to report both path1 and path2??? */
827 return posix_error();
828 Py_INCREF(Py_None);
829 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000830}
831
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000832#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000833static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +0000834win32_1str(PyObject* args, char* func,
835 char* format, BOOL (__stdcall *funcA)(LPCSTR),
836 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000837{
Victor Stinner8c62be82010-05-06 00:08:46 +0000838 PyObject *uni;
839 char *ansi;
840 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +0000841
Victor Stinner8c62be82010-05-06 00:08:46 +0000842 if (!PyArg_ParseTuple(args, wformat, &uni))
843 PyErr_Clear();
844 else {
845 Py_BEGIN_ALLOW_THREADS
846 result = funcW(PyUnicode_AsUnicode(uni));
847 Py_END_ALLOW_THREADS
848 if (!result)
849 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
850 Py_INCREF(Py_None);
851 return Py_None;
852 }
853 if (!PyArg_ParseTuple(args, format, &ansi))
854 return NULL;
855 Py_BEGIN_ALLOW_THREADS
856 result = funcA(ansi);
857 Py_END_ALLOW_THREADS
858 if (!result)
859 return win32_error(func, ansi);
860 Py_INCREF(Py_None);
861 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000862
863}
864
865/* This is a reimplementation of the C library's chdir function,
866 but one that produces Win32 errors instead of DOS error codes.
867 chdir is essentially a wrapper around SetCurrentDirectory; however,
868 it also needs to set "magic" environment variables indicating
869 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000870static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000871win32_chdir(LPCSTR path)
872{
Victor Stinner8c62be82010-05-06 00:08:46 +0000873 char new_path[MAX_PATH+1];
874 int result;
875 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000876
Victor Stinner8c62be82010-05-06 00:08:46 +0000877 if(!SetCurrentDirectoryA(path))
878 return FALSE;
879 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
880 if (!result)
881 return FALSE;
882 /* In the ANSI API, there should not be any paths longer
883 than MAX_PATH. */
884 assert(result <= MAX_PATH+1);
885 if (strncmp(new_path, "\\\\", 2) == 0 ||
886 strncmp(new_path, "//", 2) == 0)
887 /* UNC path, nothing to do. */
888 return TRUE;
889 env[1] = new_path[0];
890 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000891}
892
893/* The Unicode version differs from the ANSI version
894 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000895static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000896win32_wchdir(LPCWSTR path)
897{
Victor Stinner8c62be82010-05-06 00:08:46 +0000898 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
899 int result;
900 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000901
Victor Stinner8c62be82010-05-06 00:08:46 +0000902 if(!SetCurrentDirectoryW(path))
903 return FALSE;
904 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
905 if (!result)
906 return FALSE;
907 if (result > MAX_PATH+1) {
908 new_path = malloc(result * sizeof(wchar_t));
909 if (!new_path) {
910 SetLastError(ERROR_OUTOFMEMORY);
911 return FALSE;
912 }
913 result = GetCurrentDirectoryW(result, new_path);
914 if (!result) {
915 free(new_path);
916 return FALSE;
917 }
918 }
919 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
920 wcsncmp(new_path, L"//", 2) == 0)
921 /* UNC path, nothing to do. */
922 return TRUE;
923 env[1] = new_path[0];
924 result = SetEnvironmentVariableW(env, new_path);
925 if (new_path != _new_path)
926 free(new_path);
927 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000928}
929#endif
930
Martin v. Löwis14694662006-02-03 12:54:16 +0000931#ifdef MS_WINDOWS
932/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
933 - time stamps are restricted to second resolution
934 - file modification times suffer from forth-and-back conversions between
935 UTC and local time
936 Therefore, we implement our own stat, based on the Win32 API directly.
937*/
Victor Stinner8c62be82010-05-06 00:08:46 +0000938#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +0000939
940struct win32_stat{
941 int st_dev;
942 __int64 st_ino;
943 unsigned short st_mode;
944 int st_nlink;
945 int st_uid;
946 int st_gid;
947 int st_rdev;
948 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +0000949 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000950 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +0000951 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000952 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +0000953 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000954 int st_ctime_nsec;
955};
956
957static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
958
959static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +0000960FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +0000961{
Victor Stinner8c62be82010-05-06 00:08:46 +0000962 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
963 /* Cannot simply cast and dereference in_ptr,
964 since it might not be aligned properly */
965 __int64 in;
966 memcpy(&in, in_ptr, sizeof(in));
967 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +0000968 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +0000969}
970
Thomas Wouters477c8d52006-05-27 19:21:47 +0000971static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +0000972time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000973{
Victor Stinner8c62be82010-05-06 00:08:46 +0000974 /* XXX endianness */
975 __int64 out;
976 out = time_in + secs_between_epochs;
977 out = out * 10000000 + nsec_in / 100;
978 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000979}
980
Martin v. Löwis14694662006-02-03 12:54:16 +0000981/* Below, we *know* that ugo+r is 0444 */
982#if _S_IREAD != 0400
983#error Unsupported C library
984#endif
985static int
986attributes_to_mode(DWORD attr)
987{
Victor Stinner8c62be82010-05-06 00:08:46 +0000988 int m = 0;
989 if (attr & FILE_ATTRIBUTE_DIRECTORY)
990 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
991 else
992 m |= _S_IFREG;
993 if (attr & FILE_ATTRIBUTE_READONLY)
994 m |= 0444;
995 else
996 m |= 0666;
997 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +0000998}
999
1000static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001001attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001002{
Victor Stinner8c62be82010-05-06 00:08:46 +00001003 memset(result, 0, sizeof(*result));
1004 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1005 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1006 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1007 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1008 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001009 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001010 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001011 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1012 /* first clear the S_IFMT bits */
1013 result->st_mode ^= (result->st_mode & 0170000);
1014 /* now set the bits that make this a symlink */
1015 result->st_mode |= 0120000;
1016 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001017
Victor Stinner8c62be82010-05-06 00:08:46 +00001018 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001019}
1020
Guido van Rossumd8faa362007-04-27 19:54:29 +00001021static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001022attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001023{
Victor Stinner8c62be82010-05-06 00:08:46 +00001024 HANDLE hFindFile;
1025 WIN32_FIND_DATAA FileData;
1026 hFindFile = FindFirstFileA(pszFile, &FileData);
1027 if (hFindFile == INVALID_HANDLE_VALUE)
1028 return FALSE;
1029 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001030 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001031 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001032 info->dwFileAttributes = FileData.dwFileAttributes;
1033 info->ftCreationTime = FileData.ftCreationTime;
1034 info->ftLastAccessTime = FileData.ftLastAccessTime;
1035 info->ftLastWriteTime = FileData.ftLastWriteTime;
1036 info->nFileSizeHigh = FileData.nFileSizeHigh;
1037 info->nFileSizeLow = FileData.nFileSizeLow;
1038/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001039 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1040 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001041 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001042}
1043
1044static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001045attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001046{
Victor Stinner8c62be82010-05-06 00:08:46 +00001047 HANDLE hFindFile;
1048 WIN32_FIND_DATAW FileData;
1049 hFindFile = FindFirstFileW(pszFile, &FileData);
1050 if (hFindFile == INVALID_HANDLE_VALUE)
1051 return FALSE;
1052 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001053 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001054 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001055 info->dwFileAttributes = FileData.dwFileAttributes;
1056 info->ftCreationTime = FileData.ftCreationTime;
1057 info->ftLastAccessTime = FileData.ftLastAccessTime;
1058 info->ftLastWriteTime = FileData.ftLastWriteTime;
1059 info->nFileSizeHigh = FileData.nFileSizeHigh;
1060 info->nFileSizeLow = FileData.nFileSizeLow;
1061/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001062 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1063 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001064 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001065}
1066
Brian Curtind25aef52011-06-13 15:16:04 -05001067/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1068static int has_GetFinalPathNameByHandle = 0;
1069static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1070 DWORD);
1071static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1072 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001073static int
Brian Curtind25aef52011-06-13 15:16:04 -05001074check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001075{
Brian Curtind25aef52011-06-13 15:16:04 -05001076 HINSTANCE hKernel32;
1077 /* only recheck */
1078 if (!has_GetFinalPathNameByHandle)
1079 {
1080 hKernel32 = GetModuleHandle("KERNEL32");
1081 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1082 "GetFinalPathNameByHandleA");
1083 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1084 "GetFinalPathNameByHandleW");
1085 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1086 Py_GetFinalPathNameByHandleW;
1087 }
1088 return has_GetFinalPathNameByHandle;
1089}
1090
1091static BOOL
1092get_target_path(HANDLE hdl, wchar_t **target_path)
1093{
1094 int buf_size, result_length;
1095 wchar_t *buf;
1096
1097 /* We have a good handle to the target, use it to determine
1098 the target path name (then we'll call lstat on it). */
1099 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1100 VOLUME_NAME_DOS);
1101 if(!buf_size)
1102 return FALSE;
1103
1104 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001105 if (!buf) {
1106 SetLastError(ERROR_OUTOFMEMORY);
1107 return FALSE;
1108 }
1109
Brian Curtind25aef52011-06-13 15:16:04 -05001110 result_length = Py_GetFinalPathNameByHandleW(hdl,
1111 buf, buf_size, VOLUME_NAME_DOS);
1112
1113 if(!result_length) {
1114 free(buf);
1115 return FALSE;
1116 }
1117
1118 if(!CloseHandle(hdl)) {
1119 free(buf);
1120 return FALSE;
1121 }
1122
1123 buf[result_length] = 0;
1124
1125 *target_path = buf;
1126 return TRUE;
1127}
1128
1129static int
1130win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1131 BOOL traverse);
1132static int
1133win32_xstat_impl(const char *path, struct win32_stat *result,
1134 BOOL traverse)
1135{
1136 int code;
1137 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001138 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001139 ULONG reparse_tag = 0;
Brian Curtind25aef52011-06-13 15:16:04 -05001140 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001141 const char *dot;
1142
Brian Curtind25aef52011-06-13 15:16:04 -05001143 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001144 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1145 traverse reparse point. */
1146 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001147 }
1148
Brian Curtinf5e76d02010-11-24 13:14:05 +00001149 hFile = CreateFileA(
1150 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001151 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001152 0, /* share mode */
1153 NULL, /* security attributes */
1154 OPEN_EXISTING,
1155 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001156 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1157 Because of this, calls like GetFinalPathNameByHandle will return
1158 the symlink path agin and not the actual final path. */
1159 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1160 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001161 NULL);
1162
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001163 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001164 /* Either the target doesn't exist, or we don't have access to
1165 get a handle to it. If the former, we need to return an error.
1166 If the latter, we can use attributes_from_dir. */
1167 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001168 return -1;
1169 /* Could not get attributes on open file. Fall back to
1170 reading the directory. */
1171 if (!attributes_from_dir(path, &info, &reparse_tag))
1172 /* Very strange. This should not fail now */
1173 return -1;
1174 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1175 if (traverse) {
1176 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001177 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001178 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001179 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001180 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001181 } else {
1182 if (!GetFileInformationByHandle(hFile, &info)) {
1183 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001184 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001185 }
1186 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001187 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1188 return -1;
1189
1190 /* Close the outer open file handle now that we're about to
1191 reopen it with different flags. */
1192 if (!CloseHandle(hFile))
1193 return -1;
1194
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001195 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001196 /* In order to call GetFinalPathNameByHandle we need to open
1197 the file without the reparse handling flag set. */
1198 hFile2 = CreateFileA(
1199 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1200 NULL, OPEN_EXISTING,
1201 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1202 NULL);
1203 if (hFile2 == INVALID_HANDLE_VALUE)
1204 return -1;
1205
1206 if (!get_target_path(hFile2, &target_path))
1207 return -1;
1208
1209 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001210 free(target_path);
1211 return code;
1212 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001213 } else
1214 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001215 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001216 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001217
1218 /* Set S_IEXEC if it is an .exe, .bat, ... */
1219 dot = strrchr(path, '.');
1220 if (dot) {
1221 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1222 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1223 result->st_mode |= 0111;
1224 }
1225 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001226}
1227
1228static int
Brian Curtind25aef52011-06-13 15:16:04 -05001229win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1230 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001231{
1232 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001233 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001234 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001235 ULONG reparse_tag = 0;
1236 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001237 const wchar_t *dot;
1238
Brian Curtind25aef52011-06-13 15:16:04 -05001239 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001240 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1241 traverse reparse point. */
1242 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001243 }
1244
Brian Curtinf5e76d02010-11-24 13:14:05 +00001245 hFile = CreateFileW(
1246 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001247 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001248 0, /* share mode */
1249 NULL, /* security attributes */
1250 OPEN_EXISTING,
1251 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001252 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1253 Because of this, calls like GetFinalPathNameByHandle will return
1254 the symlink path agin and not the actual final path. */
1255 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1256 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001257 NULL);
1258
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001259 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001260 /* Either the target doesn't exist, or we don't have access to
1261 get a handle to it. If the former, we need to return an error.
1262 If the latter, we can use attributes_from_dir. */
1263 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001264 return -1;
1265 /* Could not get attributes on open file. Fall back to
1266 reading the directory. */
1267 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1268 /* Very strange. This should not fail now */
1269 return -1;
1270 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1271 if (traverse) {
1272 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001273 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001274 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001275 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001276 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001277 } else {
1278 if (!GetFileInformationByHandle(hFile, &info)) {
1279 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001280 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001281 }
1282 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001283 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1284 return -1;
1285
1286 /* Close the outer open file handle now that we're about to
1287 reopen it with different flags. */
1288 if (!CloseHandle(hFile))
1289 return -1;
1290
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001291 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001292 /* In order to call GetFinalPathNameByHandle we need to open
1293 the file without the reparse handling flag set. */
1294 hFile2 = CreateFileW(
1295 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1296 NULL, OPEN_EXISTING,
1297 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1298 NULL);
1299 if (hFile2 == INVALID_HANDLE_VALUE)
1300 return -1;
1301
1302 if (!get_target_path(hFile2, &target_path))
1303 return -1;
1304
1305 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001306 free(target_path);
1307 return code;
1308 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001309 } else
1310 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001311 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001312 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001313
1314 /* Set S_IEXEC if it is an .exe, .bat, ... */
1315 dot = wcsrchr(path, '.');
1316 if (dot) {
1317 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1318 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1319 result->st_mode |= 0111;
1320 }
1321 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001322}
1323
1324static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001325win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001326{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001327 /* Protocol violation: we explicitly clear errno, instead of
1328 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001329 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001330 errno = 0;
1331 return code;
1332}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001333
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001334static int
1335win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1336{
1337 /* Protocol violation: we explicitly clear errno, instead of
1338 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001339 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001340 errno = 0;
1341 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001342}
Brian Curtind25aef52011-06-13 15:16:04 -05001343/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001344
1345 In Posix, stat automatically traverses symlinks and returns the stat
1346 structure for the target. In Windows, the equivalent GetFileAttributes by
1347 default does not traverse symlinks and instead returns attributes for
1348 the symlink.
1349
1350 Therefore, win32_lstat will get the attributes traditionally, and
1351 win32_stat will first explicitly resolve the symlink target and then will
1352 call win32_lstat on that result.
1353
Ezio Melotti4969f702011-03-15 05:59:46 +02001354 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001355
Brian Curtind25aef52011-06-13 15:16:04 -05001356static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001357win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001358{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001359 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001360}
1361
Victor Stinner8c62be82010-05-06 00:08:46 +00001362static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001363win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001364{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001365 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001366}
1367
1368static int
1369win32_stat(const char* path, struct win32_stat *result)
1370{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001371 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001372}
1373
1374static int
1375win32_stat_w(const wchar_t* path, struct win32_stat *result)
1376{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001377 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001378}
1379
1380static int
1381win32_fstat(int file_number, struct win32_stat *result)
1382{
Victor Stinner8c62be82010-05-06 00:08:46 +00001383 BY_HANDLE_FILE_INFORMATION info;
1384 HANDLE h;
1385 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001386
Victor Stinner8c62be82010-05-06 00:08:46 +00001387 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001388
Victor Stinner8c62be82010-05-06 00:08:46 +00001389 /* Protocol violation: we explicitly clear errno, instead of
1390 setting it to a POSIX error. Callers should use GetLastError. */
1391 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001392
Victor Stinner8c62be82010-05-06 00:08:46 +00001393 if (h == INVALID_HANDLE_VALUE) {
1394 /* This is really a C library error (invalid file handle).
1395 We set the Win32 error to the closes one matching. */
1396 SetLastError(ERROR_INVALID_HANDLE);
1397 return -1;
1398 }
1399 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001400
Victor Stinner8c62be82010-05-06 00:08:46 +00001401 type = GetFileType(h);
1402 if (type == FILE_TYPE_UNKNOWN) {
1403 DWORD error = GetLastError();
1404 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001405 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001406 }
1407 /* else: valid but unknown file */
1408 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001409
Victor Stinner8c62be82010-05-06 00:08:46 +00001410 if (type != FILE_TYPE_DISK) {
1411 if (type == FILE_TYPE_CHAR)
1412 result->st_mode = _S_IFCHR;
1413 else if (type == FILE_TYPE_PIPE)
1414 result->st_mode = _S_IFIFO;
1415 return 0;
1416 }
1417
1418 if (!GetFileInformationByHandle(h, &info)) {
1419 return -1;
1420 }
1421
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001422 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001423 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001424 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1425 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001426}
1427
1428#endif /* MS_WINDOWS */
1429
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001430PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001431"stat_result: Result from stat or lstat.\n\n\
1432This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001433 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001434or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1435\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001436Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1437or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001438\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001439See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001440
1441static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001442 {"st_mode", "protection bits"},
1443 {"st_ino", "inode"},
1444 {"st_dev", "device"},
1445 {"st_nlink", "number of hard links"},
1446 {"st_uid", "user ID of owner"},
1447 {"st_gid", "group ID of owner"},
1448 {"st_size", "total size, in bytes"},
1449 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1450 {NULL, "integer time of last access"},
1451 {NULL, "integer time of last modification"},
1452 {NULL, "integer time of last change"},
1453 {"st_atime", "time of last access"},
1454 {"st_mtime", "time of last modification"},
1455 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001456#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001457 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001458#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001459#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001460 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001461#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001462#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001463 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001464#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001465#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001466 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001467#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001468#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001469 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001470#endif
1471#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001472 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001473#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001474 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001475};
1476
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001477#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001478#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001479#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001480#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001481#endif
1482
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001483#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001484#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1485#else
1486#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1487#endif
1488
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001489#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001490#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1491#else
1492#define ST_RDEV_IDX ST_BLOCKS_IDX
1493#endif
1494
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001495#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1496#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1497#else
1498#define ST_FLAGS_IDX ST_RDEV_IDX
1499#endif
1500
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001501#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001502#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001503#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001504#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001505#endif
1506
1507#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1508#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1509#else
1510#define ST_BIRTHTIME_IDX ST_GEN_IDX
1511#endif
1512
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001513static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001514 "stat_result", /* name */
1515 stat_result__doc__, /* doc */
1516 stat_result_fields,
1517 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001518};
1519
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001520PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001521"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1522This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001523 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001524or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001525\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001526See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001527
1528static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001529 {"f_bsize", },
1530 {"f_frsize", },
1531 {"f_blocks", },
1532 {"f_bfree", },
1533 {"f_bavail", },
1534 {"f_files", },
1535 {"f_ffree", },
1536 {"f_favail", },
1537 {"f_flag", },
1538 {"f_namemax",},
1539 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001540};
1541
1542static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001543 "statvfs_result", /* name */
1544 statvfs_result__doc__, /* doc */
1545 statvfs_result_fields,
1546 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001547};
1548
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001549static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001550static PyTypeObject StatResultType;
1551static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001552static newfunc structseq_new;
1553
1554static PyObject *
1555statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1556{
Victor Stinner8c62be82010-05-06 00:08:46 +00001557 PyStructSequence *result;
1558 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001559
Victor Stinner8c62be82010-05-06 00:08:46 +00001560 result = (PyStructSequence*)structseq_new(type, args, kwds);
1561 if (!result)
1562 return NULL;
1563 /* If we have been initialized from a tuple,
1564 st_?time might be set to None. Initialize it
1565 from the int slots. */
1566 for (i = 7; i <= 9; i++) {
1567 if (result->ob_item[i+3] == Py_None) {
1568 Py_DECREF(Py_None);
1569 Py_INCREF(result->ob_item[i]);
1570 result->ob_item[i+3] = result->ob_item[i];
1571 }
1572 }
1573 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001574}
1575
1576
1577
1578/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001579static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001580
1581PyDoc_STRVAR(stat_float_times__doc__,
1582"stat_float_times([newval]) -> oldval\n\n\
1583Determine whether os.[lf]stat represents time stamps as float objects.\n\
1584If newval is True, future calls to stat() return floats, if it is False,\n\
1585future calls return ints. \n\
1586If newval is omitted, return the current setting.\n");
1587
1588static PyObject*
1589stat_float_times(PyObject* self, PyObject *args)
1590{
Victor Stinner8c62be82010-05-06 00:08:46 +00001591 int newval = -1;
1592 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1593 return NULL;
1594 if (newval == -1)
1595 /* Return old value */
1596 return PyBool_FromLong(_stat_float_times);
1597 _stat_float_times = newval;
1598 Py_INCREF(Py_None);
1599 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001600}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001601
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001602static void
1603fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1604{
Victor Stinner8c62be82010-05-06 00:08:46 +00001605 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001606#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner8c62be82010-05-06 00:08:46 +00001607 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001608#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001609 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001610#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001611 if (!ival)
1612 return;
1613 if (_stat_float_times) {
1614 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1615 } else {
1616 fval = ival;
1617 Py_INCREF(fval);
1618 }
1619 PyStructSequence_SET_ITEM(v, index, ival);
1620 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001621}
1622
Tim Peters5aa91602002-01-30 05:46:57 +00001623/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001624 (used by posix_stat() and posix_fstat()) */
1625static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001626_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001627{
Victor Stinner8c62be82010-05-06 00:08:46 +00001628 unsigned long ansec, mnsec, cnsec;
1629 PyObject *v = PyStructSequence_New(&StatResultType);
1630 if (v == NULL)
1631 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001632
Victor Stinner8c62be82010-05-06 00:08:46 +00001633 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001634#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001635 PyStructSequence_SET_ITEM(v, 1,
1636 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001637#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001638 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001639#endif
1640#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001641 PyStructSequence_SET_ITEM(v, 2,
1642 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001643#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001644 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001645#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001646 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1647 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1648 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001649#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001650 PyStructSequence_SET_ITEM(v, 6,
1651 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001652#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001653 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001654#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001655
Martin v. Löwis14694662006-02-03 12:54:16 +00001656#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001657 ansec = st->st_atim.tv_nsec;
1658 mnsec = st->st_mtim.tv_nsec;
1659 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001660#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001661 ansec = st->st_atimespec.tv_nsec;
1662 mnsec = st->st_mtimespec.tv_nsec;
1663 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001664#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001665 ansec = st->st_atime_nsec;
1666 mnsec = st->st_mtime_nsec;
1667 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001668#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001669 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001670#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001671 fill_time(v, 7, st->st_atime, ansec);
1672 fill_time(v, 8, st->st_mtime, mnsec);
1673 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001674
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001675#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001676 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1677 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001678#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001679#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001680 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1681 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001682#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001683#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001684 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1685 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001686#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001687#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001688 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1689 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001690#endif
1691#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001692 {
1693 PyObject *val;
1694 unsigned long bsec,bnsec;
1695 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001696#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner8c62be82010-05-06 00:08:46 +00001697 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001698#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001699 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001700#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001701 if (_stat_float_times) {
1702 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1703 } else {
1704 val = PyLong_FromLong((long)bsec);
1705 }
1706 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1707 val);
1708 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001709#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001710#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001711 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1712 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001713#endif
Fred Drake699f3522000-06-29 21:12:41 +00001714
Victor Stinner8c62be82010-05-06 00:08:46 +00001715 if (PyErr_Occurred()) {
1716 Py_DECREF(v);
1717 return NULL;
1718 }
Fred Drake699f3522000-06-29 21:12:41 +00001719
Victor Stinner8c62be82010-05-06 00:08:46 +00001720 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001721}
1722
Barry Warsaw53699e91996-12-10 23:23:01 +00001723static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001724posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +00001725 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001726#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00001727 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001728#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001729 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001730#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001731 char *wformat,
1732 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001733{
Victor Stinner8c62be82010-05-06 00:08:46 +00001734 STRUCT_STAT st;
1735 PyObject *opath;
1736 char *path;
1737 int res;
1738 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001739
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001740#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001741 PyUnicodeObject *po;
1742 if (PyArg_ParseTuple(args, wformat, &po)) {
1743 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001744
Victor Stinner8c62be82010-05-06 00:08:46 +00001745 Py_BEGIN_ALLOW_THREADS
1746 /* PyUnicode_AS_UNICODE result OK without
1747 thread lock as it is a simple dereference. */
1748 res = wstatfunc(wpath, &st);
1749 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001750
Victor Stinner8c62be82010-05-06 00:08:46 +00001751 if (res != 0)
1752 return win32_error_unicode("stat", wpath);
1753 return _pystat_fromstructstat(&st);
1754 }
1755 /* Drop the argument parsing error as narrow strings
1756 are also valid. */
1757 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001758#endif
1759
Victor Stinner8c62be82010-05-06 00:08:46 +00001760 if (!PyArg_ParseTuple(args, format,
1761 PyUnicode_FSConverter, &opath))
1762 return NULL;
1763 path = PyBytes_AsString(opath);
1764 Py_BEGIN_ALLOW_THREADS
1765 res = (*statfunc)(path, &st);
1766 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001767
Victor Stinner8c62be82010-05-06 00:08:46 +00001768 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001769#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001770 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001771#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001772 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001773#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001774 }
1775 else
1776 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001777
Victor Stinner8c62be82010-05-06 00:08:46 +00001778 Py_DECREF(opath);
1779 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001780}
1781
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001782/* POSIX methods */
1783
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001784PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001785"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001786Use the real uid/gid to test for access to a path. Note that most\n\
1787operations will use the effective uid/gid, therefore this routine can\n\
1788be used in a suid/sgid environment to test if the invoking user has the\n\
1789specified access to the path. The mode argument can be F_OK to test\n\
1790existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001791
1792static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001793posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001794{
Victor Stinner8c62be82010-05-06 00:08:46 +00001795 PyObject *opath;
1796 char *path;
1797 int mode;
1798
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001799#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001800 DWORD attr;
1801 PyUnicodeObject *po;
1802 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1803 Py_BEGIN_ALLOW_THREADS
1804 /* PyUnicode_AS_UNICODE OK without thread lock as
1805 it is a simple dereference. */
1806 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1807 Py_END_ALLOW_THREADS
1808 goto finish;
1809 }
1810 /* Drop the argument parsing error as narrow strings
1811 are also valid. */
1812 PyErr_Clear();
1813 if (!PyArg_ParseTuple(args, "O&i:access",
1814 PyUnicode_FSConverter, &opath, &mode))
1815 return NULL;
1816 path = PyBytes_AsString(opath);
1817 Py_BEGIN_ALLOW_THREADS
1818 attr = GetFileAttributesA(path);
1819 Py_END_ALLOW_THREADS
1820 Py_DECREF(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001821finish:
Victor Stinner8c62be82010-05-06 00:08:46 +00001822 if (attr == 0xFFFFFFFF)
1823 /* File does not exist, or cannot read attributes */
1824 return PyBool_FromLong(0);
1825 /* Access is possible if either write access wasn't requested, or
1826 the file isn't read-only, or if it's a directory, as there are
1827 no read-only directories on Windows. */
1828 return PyBool_FromLong(!(mode & 2)
1829 || !(attr & FILE_ATTRIBUTE_READONLY)
1830 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001831#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001832 int res;
1833 if (!PyArg_ParseTuple(args, "O&i:access",
1834 PyUnicode_FSConverter, &opath, &mode))
1835 return NULL;
1836 path = PyBytes_AsString(opath);
1837 Py_BEGIN_ALLOW_THREADS
1838 res = access(path, mode);
1839 Py_END_ALLOW_THREADS
1840 Py_DECREF(opath);
1841 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001842#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001843}
1844
Guido van Rossumd371ff11999-01-25 16:12:23 +00001845#ifndef F_OK
1846#define F_OK 0
1847#endif
1848#ifndef R_OK
1849#define R_OK 4
1850#endif
1851#ifndef W_OK
1852#define W_OK 2
1853#endif
1854#ifndef X_OK
1855#define X_OK 1
1856#endif
1857
1858#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001859PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001860"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001861Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001862
1863static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001864posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001865{
Victor Stinner8c62be82010-05-06 00:08:46 +00001866 int id;
1867 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001868
Victor Stinner8c62be82010-05-06 00:08:46 +00001869 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1870 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001871
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001872#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001873 /* file descriptor 0 only, the default input device (stdin) */
1874 if (id == 0) {
1875 ret = ttyname();
1876 }
1877 else {
1878 ret = NULL;
1879 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001880#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001881 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001882#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001883 if (ret == NULL)
1884 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001885 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001886}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001887#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001888
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001889#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001890PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001891"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001892Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001893
1894static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001895posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001896{
Victor Stinner8c62be82010-05-06 00:08:46 +00001897 char *ret;
1898 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001899
Greg Wardb48bc172000-03-01 21:51:56 +00001900#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00001901 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001902#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001903 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001904#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001905 if (ret == NULL)
1906 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001907 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001908}
1909#endif
1910
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001911PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001912"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001913Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001914
Barry Warsaw53699e91996-12-10 23:23:01 +00001915static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001916posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001917{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001918#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001919 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001920#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001921 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001922#elif defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001923 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001924#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001925 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001926#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001927}
1928
Fred Drake4d1e64b2002-04-15 19:40:07 +00001929#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001930PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001931"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001932Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001933opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001934
1935static PyObject *
1936posix_fchdir(PyObject *self, PyObject *fdobj)
1937{
Victor Stinner8c62be82010-05-06 00:08:46 +00001938 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001939}
1940#endif /* HAVE_FCHDIR */
1941
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001942
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001943PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001944"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001945Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001946
Barry Warsaw53699e91996-12-10 23:23:01 +00001947static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001948posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001949{
Victor Stinner8c62be82010-05-06 00:08:46 +00001950 PyObject *opath = NULL;
1951 char *path = NULL;
1952 int i;
1953 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001954#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001955 DWORD attr;
1956 PyUnicodeObject *po;
1957 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1958 Py_BEGIN_ALLOW_THREADS
1959 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1960 if (attr != 0xFFFFFFFF) {
1961 if (i & _S_IWRITE)
1962 attr &= ~FILE_ATTRIBUTE_READONLY;
1963 else
1964 attr |= FILE_ATTRIBUTE_READONLY;
1965 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1966 }
1967 else
1968 res = 0;
1969 Py_END_ALLOW_THREADS
1970 if (!res)
1971 return win32_error_unicode("chmod",
1972 PyUnicode_AS_UNICODE(po));
1973 Py_INCREF(Py_None);
1974 return Py_None;
1975 }
1976 /* Drop the argument parsing error as narrow strings
1977 are also valid. */
1978 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001979
Victor Stinner8c62be82010-05-06 00:08:46 +00001980 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1981 &opath, &i))
1982 return NULL;
1983 path = PyBytes_AsString(opath);
1984 Py_BEGIN_ALLOW_THREADS
1985 attr = GetFileAttributesA(path);
1986 if (attr != 0xFFFFFFFF) {
1987 if (i & _S_IWRITE)
1988 attr &= ~FILE_ATTRIBUTE_READONLY;
1989 else
1990 attr |= FILE_ATTRIBUTE_READONLY;
1991 res = SetFileAttributesA(path, attr);
1992 }
1993 else
1994 res = 0;
1995 Py_END_ALLOW_THREADS
1996 if (!res) {
1997 win32_error("chmod", path);
1998 Py_DECREF(opath);
1999 return NULL;
2000 }
2001 Py_DECREF(opath);
2002 Py_INCREF(Py_None);
2003 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002004#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00002005 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
2006 &opath, &i))
2007 return NULL;
2008 path = PyBytes_AsString(opath);
2009 Py_BEGIN_ALLOW_THREADS
2010 res = chmod(path, i);
2011 Py_END_ALLOW_THREADS
2012 if (res < 0)
2013 return posix_error_with_allocated_filename(opath);
2014 Py_DECREF(opath);
2015 Py_INCREF(Py_None);
2016 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002017#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002018}
2019
Christian Heimes4e30a842007-11-30 22:12:06 +00002020#ifdef HAVE_FCHMOD
2021PyDoc_STRVAR(posix_fchmod__doc__,
2022"fchmod(fd, mode)\n\n\
2023Change the access permissions of the file given by file\n\
2024descriptor fd.");
2025
2026static PyObject *
2027posix_fchmod(PyObject *self, PyObject *args)
2028{
Victor Stinner8c62be82010-05-06 00:08:46 +00002029 int fd, mode, res;
2030 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2031 return NULL;
2032 Py_BEGIN_ALLOW_THREADS
2033 res = fchmod(fd, mode);
2034 Py_END_ALLOW_THREADS
2035 if (res < 0)
2036 return posix_error();
2037 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002038}
2039#endif /* HAVE_FCHMOD */
2040
2041#ifdef HAVE_LCHMOD
2042PyDoc_STRVAR(posix_lchmod__doc__,
2043"lchmod(path, mode)\n\n\
2044Change the access permissions of a file. If path is a symlink, this\n\
2045affects the link itself rather than the target.");
2046
2047static PyObject *
2048posix_lchmod(PyObject *self, PyObject *args)
2049{
Victor Stinner8c62be82010-05-06 00:08:46 +00002050 PyObject *opath;
2051 char *path;
2052 int i;
2053 int res;
2054 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2055 &opath, &i))
2056 return NULL;
2057 path = PyBytes_AsString(opath);
2058 Py_BEGIN_ALLOW_THREADS
2059 res = lchmod(path, i);
2060 Py_END_ALLOW_THREADS
2061 if (res < 0)
2062 return posix_error_with_allocated_filename(opath);
2063 Py_DECREF(opath);
2064 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002065}
2066#endif /* HAVE_LCHMOD */
2067
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002068
Thomas Wouterscf297e42007-02-23 15:07:44 +00002069#ifdef HAVE_CHFLAGS
2070PyDoc_STRVAR(posix_chflags__doc__,
2071"chflags(path, flags)\n\n\
2072Set file flags.");
2073
2074static PyObject *
2075posix_chflags(PyObject *self, PyObject *args)
2076{
Victor Stinner8c62be82010-05-06 00:08:46 +00002077 PyObject *opath;
2078 char *path;
2079 unsigned long flags;
2080 int res;
2081 if (!PyArg_ParseTuple(args, "O&k:chflags",
2082 PyUnicode_FSConverter, &opath, &flags))
2083 return NULL;
2084 path = PyBytes_AsString(opath);
2085 Py_BEGIN_ALLOW_THREADS
2086 res = chflags(path, flags);
2087 Py_END_ALLOW_THREADS
2088 if (res < 0)
2089 return posix_error_with_allocated_filename(opath);
2090 Py_DECREF(opath);
2091 Py_INCREF(Py_None);
2092 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002093}
2094#endif /* HAVE_CHFLAGS */
2095
2096#ifdef HAVE_LCHFLAGS
2097PyDoc_STRVAR(posix_lchflags__doc__,
2098"lchflags(path, flags)\n\n\
2099Set file flags.\n\
2100This function will not follow symbolic links.");
2101
2102static PyObject *
2103posix_lchflags(PyObject *self, PyObject *args)
2104{
Victor Stinner8c62be82010-05-06 00:08:46 +00002105 PyObject *opath;
2106 char *path;
2107 unsigned long flags;
2108 int res;
2109 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2110 PyUnicode_FSConverter, &opath, &flags))
2111 return NULL;
2112 path = PyBytes_AsString(opath);
2113 Py_BEGIN_ALLOW_THREADS
2114 res = lchflags(path, flags);
2115 Py_END_ALLOW_THREADS
2116 if (res < 0)
2117 return posix_error_with_allocated_filename(opath);
2118 Py_DECREF(opath);
2119 Py_INCREF(Py_None);
2120 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002121}
2122#endif /* HAVE_LCHFLAGS */
2123
Martin v. Löwis244edc82001-10-04 22:44:26 +00002124#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002125PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002126"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002127Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002128
2129static PyObject *
2130posix_chroot(PyObject *self, PyObject *args)
2131{
Victor Stinner8c62be82010-05-06 00:08:46 +00002132 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002133}
2134#endif
2135
Guido van Rossum21142a01999-01-08 21:05:37 +00002136#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002137PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002138"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002139force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002140
2141static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002142posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002143{
Stefan Krah0e803b32010-11-26 16:16:47 +00002144 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002145}
2146#endif /* HAVE_FSYNC */
2147
2148#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002149
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002150#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002151extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2152#endif
2153
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002154PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002155"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002156force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002157 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002158
2159static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002160posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002161{
Stefan Krah0e803b32010-11-26 16:16:47 +00002162 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002163}
2164#endif /* HAVE_FDATASYNC */
2165
2166
Fredrik Lundh10723342000-07-10 16:38:09 +00002167#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002168PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002169"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002170Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002171
Barry Warsaw53699e91996-12-10 23:23:01 +00002172static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002173posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002174{
Victor Stinner8c62be82010-05-06 00:08:46 +00002175 PyObject *opath;
2176 char *path;
2177 long uid, gid;
2178 int res;
2179 if (!PyArg_ParseTuple(args, "O&ll:chown",
2180 PyUnicode_FSConverter, &opath,
2181 &uid, &gid))
2182 return NULL;
2183 path = PyBytes_AsString(opath);
2184 Py_BEGIN_ALLOW_THREADS
2185 res = chown(path, (uid_t) uid, (gid_t) gid);
2186 Py_END_ALLOW_THREADS
2187 if (res < 0)
2188 return posix_error_with_allocated_filename(opath);
2189 Py_DECREF(opath);
2190 Py_INCREF(Py_None);
2191 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002192}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002193#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002194
Christian Heimes4e30a842007-11-30 22:12:06 +00002195#ifdef HAVE_FCHOWN
2196PyDoc_STRVAR(posix_fchown__doc__,
2197"fchown(fd, uid, gid)\n\n\
2198Change the owner and group id of the file given by file descriptor\n\
2199fd to the numeric uid and gid.");
2200
2201static PyObject *
2202posix_fchown(PyObject *self, PyObject *args)
2203{
Victor Stinner8c62be82010-05-06 00:08:46 +00002204 int fd;
2205 long uid, gid;
2206 int res;
2207 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
2208 return NULL;
2209 Py_BEGIN_ALLOW_THREADS
2210 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2211 Py_END_ALLOW_THREADS
2212 if (res < 0)
2213 return posix_error();
2214 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002215}
2216#endif /* HAVE_FCHOWN */
2217
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002218#ifdef HAVE_LCHOWN
2219PyDoc_STRVAR(posix_lchown__doc__,
2220"lchown(path, uid, gid)\n\n\
2221Change the owner and group id of path to the numeric uid and gid.\n\
2222This function will not follow symbolic links.");
2223
2224static PyObject *
2225posix_lchown(PyObject *self, PyObject *args)
2226{
Victor Stinner8c62be82010-05-06 00:08:46 +00002227 PyObject *opath;
2228 char *path;
2229 long uid, gid;
2230 int res;
2231 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2232 PyUnicode_FSConverter, &opath,
2233 &uid, &gid))
2234 return NULL;
2235 path = PyBytes_AsString(opath);
2236 Py_BEGIN_ALLOW_THREADS
2237 res = lchown(path, (uid_t) uid, (gid_t) gid);
2238 Py_END_ALLOW_THREADS
2239 if (res < 0)
2240 return posix_error_with_allocated_filename(opath);
2241 Py_DECREF(opath);
2242 Py_INCREF(Py_None);
2243 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002244}
2245#endif /* HAVE_LCHOWN */
2246
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002247
Guido van Rossum36bc6801995-06-14 22:54:23 +00002248#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002249static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002250posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002251{
Victor Stinner8c62be82010-05-06 00:08:46 +00002252 char buf[1026];
2253 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002254
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002255#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002256 if (!use_bytes) {
2257 wchar_t wbuf[1026];
2258 wchar_t *wbuf2 = wbuf;
2259 PyObject *resobj;
2260 DWORD len;
2261 Py_BEGIN_ALLOW_THREADS
2262 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2263 /* If the buffer is large enough, len does not include the
2264 terminating \0. If the buffer is too small, len includes
2265 the space needed for the terminator. */
2266 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2267 wbuf2 = malloc(len * sizeof(wchar_t));
2268 if (wbuf2)
2269 len = GetCurrentDirectoryW(len, wbuf2);
2270 }
2271 Py_END_ALLOW_THREADS
2272 if (!wbuf2) {
2273 PyErr_NoMemory();
2274 return NULL;
2275 }
2276 if (!len) {
2277 if (wbuf2 != wbuf) free(wbuf2);
2278 return win32_error("getcwdu", NULL);
2279 }
2280 resobj = PyUnicode_FromWideChar(wbuf2, len);
2281 if (wbuf2 != wbuf) free(wbuf2);
2282 return resobj;
2283 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002284#endif
2285
Victor Stinner8c62be82010-05-06 00:08:46 +00002286 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002287#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002288 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002289#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002290 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002291#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002292 Py_END_ALLOW_THREADS
2293 if (res == NULL)
2294 return posix_error();
2295 if (use_bytes)
2296 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002297 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002298}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002299
2300PyDoc_STRVAR(posix_getcwd__doc__,
2301"getcwd() -> path\n\n\
2302Return a unicode string representing the current working directory.");
2303
2304static PyObject *
2305posix_getcwd_unicode(PyObject *self)
2306{
2307 return posix_getcwd(0);
2308}
2309
2310PyDoc_STRVAR(posix_getcwdb__doc__,
2311"getcwdb() -> path\n\n\
2312Return a bytes string representing the current working directory.");
2313
2314static PyObject *
2315posix_getcwd_bytes(PyObject *self)
2316{
2317 return posix_getcwd(1);
2318}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002319#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002320
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002321
Guido van Rossumb6775db1994-08-01 11:34:53 +00002322#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002323PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002324"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002325Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002326
Barry Warsaw53699e91996-12-10 23:23:01 +00002327static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002328posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002329{
Victor Stinner8c62be82010-05-06 00:08:46 +00002330 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002331}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002332#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002333
Brian Curtin1b9df392010-11-24 20:24:31 +00002334#ifdef MS_WINDOWS
2335PyDoc_STRVAR(win32_link__doc__,
2336"link(src, dst)\n\n\
2337Create a hard link to a file.");
2338
2339static PyObject *
2340win32_link(PyObject *self, PyObject *args)
2341{
2342 PyObject *osrc, *odst;
2343 char *src, *dst;
2344 BOOL rslt;
2345
Brian Curtinfc889c42010-11-28 23:59:46 +00002346 PyUnicodeObject *usrc, *udst;
2347 if (PyArg_ParseTuple(args, "UU:link", &usrc, &udst)) {
2348 Py_BEGIN_ALLOW_THREADS
2349 rslt = CreateHardLinkW(PyUnicode_AS_UNICODE(udst),
2350 PyUnicode_AS_UNICODE(usrc), NULL);
2351 Py_END_ALLOW_THREADS
2352
2353 if (rslt == 0)
2354 return win32_error("link", NULL);
2355
2356 Py_RETURN_NONE;
2357 }
2358
2359 /* Narrow strings also valid. */
2360 PyErr_Clear();
2361
Brian Curtin1b9df392010-11-24 20:24:31 +00002362 if (!PyArg_ParseTuple(args, "O&O&:link", PyUnicode_FSConverter, &osrc,
2363 PyUnicode_FSConverter, &odst))
2364 return NULL;
2365
2366 src = PyBytes_AsString(osrc);
2367 dst = PyBytes_AsString(odst);
2368
2369 Py_BEGIN_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00002370 rslt = CreateHardLinkA(dst, src, NULL);
Brian Curtin1b9df392010-11-24 20:24:31 +00002371 Py_END_ALLOW_THREADS
2372
Stefan Krah30b341f2010-11-27 11:44:18 +00002373 Py_DECREF(osrc);
2374 Py_DECREF(odst);
Brian Curtin1b9df392010-11-24 20:24:31 +00002375 if (rslt == 0)
Brian Curtinfc889c42010-11-28 23:59:46 +00002376 return win32_error("link", NULL);
Brian Curtin1b9df392010-11-24 20:24:31 +00002377
2378 Py_RETURN_NONE;
2379}
2380#endif /* MS_WINDOWS */
2381
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002382
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002383PyDoc_STRVAR(posix_listdir__doc__,
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002384"listdir([path]) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002385Return a list containing the names of the entries in the directory.\n\
2386\n\
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002387 path: path of directory to list (default: '.')\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002388\n\
2389The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002390entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002391
Barry Warsaw53699e91996-12-10 23:23:01 +00002392static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002393posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002394{
Victor Stinner8c62be82010-05-06 00:08:46 +00002395 /* XXX Should redo this putting the (now four) versions of opendir
2396 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002397#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002398
Victor Stinner8c62be82010-05-06 00:08:46 +00002399 PyObject *d, *v;
2400 HANDLE hFindFile;
2401 BOOL result;
2402 WIN32_FIND_DATA FileData;
2403 PyObject *opath;
2404 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2405 char *bufptr = namebuf;
2406 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002407
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002408 PyObject *po = NULL;
2409 if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002410 WIN32_FIND_DATAW wFileData;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002411 Py_UNICODE *wnamebuf, *po_wchars;
2412
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002413 if (po == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002414 po_wchars = L".";
2415 len = 1;
2416 } else {
2417 po_wchars = PyUnicode_AS_UNICODE(po);
2418 len = PyUnicode_GET_SIZE(po);
2419 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002420 /* Overallocate for \\*.*\0 */
Victor Stinner8c62be82010-05-06 00:08:46 +00002421 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2422 if (!wnamebuf) {
2423 PyErr_NoMemory();
2424 return NULL;
2425 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002426 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00002427 if (len > 0) {
2428 Py_UNICODE wch = wnamebuf[len-1];
2429 if (wch != L'/' && wch != L'\\' && wch != L':')
2430 wnamebuf[len++] = L'\\';
2431 wcscpy(wnamebuf + len, L"*.*");
2432 }
2433 if ((d = PyList_New(0)) == NULL) {
2434 free(wnamebuf);
2435 return NULL;
2436 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00002437 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002438 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002439 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002440 if (hFindFile == INVALID_HANDLE_VALUE) {
2441 int error = GetLastError();
2442 if (error == ERROR_FILE_NOT_FOUND) {
2443 free(wnamebuf);
2444 return d;
2445 }
2446 Py_DECREF(d);
2447 win32_error_unicode("FindFirstFileW", wnamebuf);
2448 free(wnamebuf);
2449 return NULL;
2450 }
2451 do {
2452 /* Skip over . and .. */
2453 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2454 wcscmp(wFileData.cFileName, L"..") != 0) {
2455 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2456 if (v == NULL) {
2457 Py_DECREF(d);
2458 d = NULL;
2459 break;
2460 }
2461 if (PyList_Append(d, v) != 0) {
2462 Py_DECREF(v);
2463 Py_DECREF(d);
2464 d = NULL;
2465 break;
2466 }
2467 Py_DECREF(v);
2468 }
2469 Py_BEGIN_ALLOW_THREADS
2470 result = FindNextFileW(hFindFile, &wFileData);
2471 Py_END_ALLOW_THREADS
2472 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2473 it got to the end of the directory. */
2474 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2475 Py_DECREF(d);
2476 win32_error_unicode("FindNextFileW", wnamebuf);
2477 FindClose(hFindFile);
2478 free(wnamebuf);
2479 return NULL;
2480 }
2481 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002482
Victor Stinner8c62be82010-05-06 00:08:46 +00002483 if (FindClose(hFindFile) == FALSE) {
2484 Py_DECREF(d);
2485 win32_error_unicode("FindClose", wnamebuf);
2486 free(wnamebuf);
2487 return NULL;
2488 }
2489 free(wnamebuf);
2490 return d;
2491 }
2492 /* Drop the argument parsing error as narrow strings
2493 are also valid. */
2494 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002495
Victor Stinner8c62be82010-05-06 00:08:46 +00002496 if (!PyArg_ParseTuple(args, "O&:listdir",
2497 PyUnicode_FSConverter, &opath))
2498 return NULL;
2499 if (PyBytes_GET_SIZE(opath)+1 > MAX_PATH) {
2500 PyErr_SetString(PyExc_ValueError, "path too long");
2501 Py_DECREF(opath);
2502 return NULL;
2503 }
2504 strcpy(namebuf, PyBytes_AsString(opath));
2505 len = PyObject_Size(opath);
Stefan Krah2a7feee2010-11-27 22:06:49 +00002506 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00002507 if (len > 0) {
2508 char ch = namebuf[len-1];
2509 if (ch != SEP && ch != ALTSEP && ch != ':')
2510 namebuf[len++] = '/';
2511 strcpy(namebuf + len, "*.*");
2512 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002513
Victor Stinner8c62be82010-05-06 00:08:46 +00002514 if ((d = PyList_New(0)) == NULL)
2515 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002516
Antoine Pitroub73caab2010-08-09 23:39:31 +00002517 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002518 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002519 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002520 if (hFindFile == INVALID_HANDLE_VALUE) {
2521 int error = GetLastError();
2522 if (error == ERROR_FILE_NOT_FOUND)
2523 return d;
2524 Py_DECREF(d);
2525 return win32_error("FindFirstFile", namebuf);
2526 }
2527 do {
2528 /* Skip over . and .. */
2529 if (strcmp(FileData.cFileName, ".") != 0 &&
2530 strcmp(FileData.cFileName, "..") != 0) {
2531 v = PyBytes_FromString(FileData.cFileName);
2532 if (v == NULL) {
2533 Py_DECREF(d);
2534 d = NULL;
2535 break;
2536 }
2537 if (PyList_Append(d, v) != 0) {
2538 Py_DECREF(v);
2539 Py_DECREF(d);
2540 d = NULL;
2541 break;
2542 }
2543 Py_DECREF(v);
2544 }
2545 Py_BEGIN_ALLOW_THREADS
2546 result = FindNextFile(hFindFile, &FileData);
2547 Py_END_ALLOW_THREADS
2548 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2549 it got to the end of the directory. */
2550 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2551 Py_DECREF(d);
2552 win32_error("FindNextFile", namebuf);
2553 FindClose(hFindFile);
2554 return NULL;
2555 }
2556 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002557
Victor Stinner8c62be82010-05-06 00:08:46 +00002558 if (FindClose(hFindFile) == FALSE) {
2559 Py_DECREF(d);
2560 return win32_error("FindClose", namebuf);
2561 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002562
Victor Stinner8c62be82010-05-06 00:08:46 +00002563 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002564
Tim Peters0bb44a42000-09-15 07:44:49 +00002565#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002566
2567#ifndef MAX_PATH
2568#define MAX_PATH CCHMAXPATH
2569#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002570 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002571 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002572 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002573 PyObject *d, *v;
2574 char namebuf[MAX_PATH+5];
2575 HDIR hdir = 1;
2576 ULONG srchcnt = 1;
2577 FILEFINDBUF3 ep;
2578 APIRET rc;
2579
Victor Stinner8c62be82010-05-06 00:08:46 +00002580 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002581 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002582 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002583 name = PyBytes_AsString(oname);
2584 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002585 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002586 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002587 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002588 return NULL;
2589 }
2590 strcpy(namebuf, name);
2591 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002592 if (*pt == ALTSEP)
2593 *pt = SEP;
2594 if (namebuf[len-1] != SEP)
2595 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002596 strcpy(namebuf + len, "*.*");
2597
Neal Norwitz6c913782007-10-14 03:23:09 +00002598 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002599 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002600 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002601 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002602
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002603 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2604 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002605 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002606 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2607 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2608 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002609
2610 if (rc != NO_ERROR) {
2611 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002612 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002613 }
2614
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002615 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002616 do {
2617 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002618 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002619 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002620
2621 strcpy(namebuf, ep.achName);
2622
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002623 /* Leave Case of Name Alone -- In Native Form */
2624 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002625
Christian Heimes72b710a2008-05-26 13:28:38 +00002626 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002627 if (v == NULL) {
2628 Py_DECREF(d);
2629 d = NULL;
2630 break;
2631 }
2632 if (PyList_Append(d, v) != 0) {
2633 Py_DECREF(v);
2634 Py_DECREF(d);
2635 d = NULL;
2636 break;
2637 }
2638 Py_DECREF(v);
2639 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2640 }
2641
Victor Stinnerdcb24032010-04-22 12:08:36 +00002642 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002643 return d;
2644#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002645 PyObject *oname;
2646 char *name;
2647 PyObject *d, *v;
2648 DIR *dirp;
2649 struct dirent *ep;
2650 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002651
Victor Stinner8c62be82010-05-06 00:08:46 +00002652 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002653 /* v is never read, so it does not need to be initialized yet. */
2654 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002655 arg_is_unicode = 0;
2656 PyErr_Clear();
2657 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002658 oname = NULL;
2659 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
Victor Stinner8c62be82010-05-06 00:08:46 +00002660 return NULL;
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002661 if (oname == NULL) { /* Default arg: "." */
Stefan Krah0e803b32010-11-26 16:16:47 +00002662 oname = PyBytes_FromString(".");
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002663 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002664 name = PyBytes_AsString(oname);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002665 Py_BEGIN_ALLOW_THREADS
2666 dirp = opendir(name);
2667 Py_END_ALLOW_THREADS
2668 if (dirp == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002669 return posix_error_with_allocated_filename(oname);
2670 }
2671 if ((d = PyList_New(0)) == NULL) {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002672 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002673 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002674 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002675 Py_DECREF(oname);
2676 return NULL;
2677 }
2678 for (;;) {
2679 errno = 0;
2680 Py_BEGIN_ALLOW_THREADS
2681 ep = readdir(dirp);
2682 Py_END_ALLOW_THREADS
2683 if (ep == NULL) {
2684 if (errno == 0) {
2685 break;
2686 } else {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002687 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002688 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002689 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002690 Py_DECREF(d);
2691 return posix_error_with_allocated_filename(oname);
2692 }
2693 }
2694 if (ep->d_name[0] == '.' &&
2695 (NAMLEN(ep) == 1 ||
2696 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2697 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002698 if (arg_is_unicode)
2699 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2700 else
2701 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002702 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002703 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002704 break;
2705 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002706 if (PyList_Append(d, v) != 0) {
2707 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002708 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002709 break;
2710 }
2711 Py_DECREF(v);
2712 }
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002713 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002714 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002715 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002716 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002717
Victor Stinner8c62be82010-05-06 00:08:46 +00002718 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002719
Tim Peters0bb44a42000-09-15 07:44:49 +00002720#endif /* which OS */
2721} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002722
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002723#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002724/* A helper function for abspath on win32 */
2725static PyObject *
2726posix__getfullpathname(PyObject *self, PyObject *args)
2727{
Victor Stinner8c62be82010-05-06 00:08:46 +00002728 PyObject *opath;
2729 char *path;
2730 char outbuf[MAX_PATH*2];
2731 char *temp;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002732#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002733 PyUnicodeObject *po;
2734 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2735 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2736 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2737 Py_UNICODE *wtemp;
2738 DWORD result;
2739 PyObject *v;
2740 result = GetFullPathNameW(wpath,
2741 sizeof(woutbuf)/sizeof(woutbuf[0]),
2742 woutbuf, &wtemp);
2743 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2744 woutbufp = malloc(result * sizeof(Py_UNICODE));
2745 if (!woutbufp)
2746 return PyErr_NoMemory();
2747 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2748 }
2749 if (result)
2750 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2751 else
2752 v = win32_error_unicode("GetFullPathNameW", wpath);
2753 if (woutbufp != woutbuf)
2754 free(woutbufp);
2755 return v;
2756 }
2757 /* Drop the argument parsing error as narrow strings
2758 are also valid. */
2759 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002760
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002761#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002762 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2763 PyUnicode_FSConverter, &opath))
2764 return NULL;
2765 path = PyBytes_AsString(opath);
2766 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2767 outbuf, &temp)) {
2768 win32_error("GetFullPathName", path);
2769 Py_DECREF(opath);
2770 return NULL;
2771 }
2772 Py_DECREF(opath);
2773 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2774 return PyUnicode_Decode(outbuf, strlen(outbuf),
2775 Py_FileSystemDefaultEncoding, NULL);
2776 }
2777 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002778} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00002779
Brian Curtind25aef52011-06-13 15:16:04 -05002780
Brian Curtinf5e76d02010-11-24 13:14:05 +00002781
Brian Curtind40e6f72010-07-08 21:39:08 +00002782/* A helper function for samepath on windows */
2783static PyObject *
2784posix__getfinalpathname(PyObject *self, PyObject *args)
2785{
2786 HANDLE hFile;
2787 int buf_size;
2788 wchar_t *target_path;
2789 int result_length;
2790 PyObject *result;
2791 wchar_t *path;
2792
Brian Curtin94622b02010-09-24 00:03:39 +00002793 if (!PyArg_ParseTuple(args, "u|:_getfinalpathname", &path)) {
Brian Curtind40e6f72010-07-08 21:39:08 +00002794 return NULL;
2795 }
2796
2797 if(!check_GetFinalPathNameByHandle()) {
2798 /* If the OS doesn't have GetFinalPathNameByHandle, return a
2799 NotImplementedError. */
2800 return PyErr_Format(PyExc_NotImplementedError,
2801 "GetFinalPathNameByHandle not available on this platform");
2802 }
2803
2804 hFile = CreateFileW(
2805 path,
2806 0, /* desired access */
2807 0, /* share mode */
2808 NULL, /* security attributes */
2809 OPEN_EXISTING,
2810 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
2811 FILE_FLAG_BACKUP_SEMANTICS,
2812 NULL);
2813
2814 if(hFile == INVALID_HANDLE_VALUE) {
2815 return win32_error_unicode("GetFinalPathNamyByHandle", path);
Brian Curtin74e45612010-07-09 15:58:59 +00002816 return PyErr_Format(PyExc_RuntimeError,
2817 "Could not get a handle to file.");
Brian Curtind40e6f72010-07-08 21:39:08 +00002818 }
2819
2820 /* We have a good handle to the target, use it to determine the
2821 target path name. */
2822 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
2823
2824 if(!buf_size)
2825 return win32_error_unicode("GetFinalPathNameByHandle", path);
2826
2827 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
2828 if(!target_path)
2829 return PyErr_NoMemory();
2830
2831 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
2832 buf_size, VOLUME_NAME_DOS);
2833 if(!result_length)
2834 return win32_error_unicode("GetFinalPathNamyByHandle", path);
2835
2836 if(!CloseHandle(hFile))
2837 return win32_error_unicode("GetFinalPathNameByHandle", path);
2838
2839 target_path[result_length] = 0;
2840 result = PyUnicode_FromUnicode(target_path, result_length);
2841 free(target_path);
2842 return result;
2843
2844} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00002845
2846static PyObject *
2847posix__getfileinformation(PyObject *self, PyObject *args)
2848{
2849 HANDLE hFile;
2850 BY_HANDLE_FILE_INFORMATION info;
2851 int fd;
2852
2853 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
2854 return NULL;
2855
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00002856 if (!_PyVerify_fd(fd))
2857 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00002858
2859 hFile = (HANDLE)_get_osfhandle(fd);
2860 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00002861 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00002862
2863 if (!GetFileInformationByHandle(hFile, &info))
2864 return win32_error("_getfileinformation", NULL);
2865
2866 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
2867 info.nFileIndexHigh,
2868 info.nFileIndexLow);
2869}
Brian Curtin9c669cc2011-06-08 18:17:18 -05002870
Brian Curtin95d028f2011-06-09 09:10:38 -05002871PyDoc_STRVAR(posix__isdir__doc__,
2872"Return true if the pathname refers to an existing directory.");
2873
Brian Curtin9c669cc2011-06-08 18:17:18 -05002874static PyObject *
2875posix__isdir(PyObject *self, PyObject *args)
2876{
2877 PyObject *opath;
2878 char *path;
2879 PyUnicodeObject *po;
2880 DWORD attributes;
2881
2882 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
2883 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2884
2885 attributes = GetFileAttributesW(wpath);
2886 if (attributes == INVALID_FILE_ATTRIBUTES)
2887 Py_RETURN_FALSE;
2888 goto check;
2889 }
2890 /* Drop the argument parsing error as narrow strings
2891 are also valid. */
2892 PyErr_Clear();
2893
2894 if (!PyArg_ParseTuple(args, "O&:_isdir",
2895 PyUnicode_FSConverter, &opath))
2896 return NULL;
2897
2898 path = PyBytes_AsString(opath);
2899 attributes = GetFileAttributesA(path);
2900 if (attributes == INVALID_FILE_ATTRIBUTES)
2901 Py_RETURN_FALSE;
2902
2903check:
2904 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
2905 Py_RETURN_TRUE;
2906 else
2907 Py_RETURN_FALSE;
2908}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002909#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002910
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002911PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002912"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002913Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002914
Barry Warsaw53699e91996-12-10 23:23:01 +00002915static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002916posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002917{
Victor Stinner8c62be82010-05-06 00:08:46 +00002918 int res;
2919 PyObject *opath;
2920 char *path;
2921 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002922
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002923#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002924 PyUnicodeObject *po;
2925 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2926 Py_BEGIN_ALLOW_THREADS
2927 /* PyUnicode_AS_UNICODE OK without thread lock as
2928 it is a simple dereference. */
2929 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2930 Py_END_ALLOW_THREADS
2931 if (!res)
2932 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2933 Py_INCREF(Py_None);
2934 return Py_None;
2935 }
2936 /* Drop the argument parsing error as narrow strings
2937 are also valid. */
2938 PyErr_Clear();
2939 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2940 PyUnicode_FSConverter, &opath, &mode))
2941 return NULL;
2942 path = PyBytes_AsString(opath);
2943 Py_BEGIN_ALLOW_THREADS
2944 /* PyUnicode_AS_UNICODE OK without thread lock as
2945 it is a simple dereference. */
2946 res = CreateDirectoryA(path, NULL);
2947 Py_END_ALLOW_THREADS
2948 if (!res) {
2949 win32_error("mkdir", path);
2950 Py_DECREF(opath);
2951 return NULL;
2952 }
2953 Py_DECREF(opath);
2954 Py_INCREF(Py_None);
2955 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002956#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002957
Victor Stinner8c62be82010-05-06 00:08:46 +00002958 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2959 PyUnicode_FSConverter, &opath, &mode))
2960 return NULL;
2961 path = PyBytes_AsString(opath);
2962 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002963#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00002964 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002965#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002966 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002967#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002968 Py_END_ALLOW_THREADS
2969 if (res < 0)
2970 return posix_error_with_allocated_filename(opath);
2971 Py_DECREF(opath);
2972 Py_INCREF(Py_None);
2973 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002974#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002975}
2976
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002977
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002978/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2979#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002980#include <sys/resource.h>
2981#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002982
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002983
2984#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002985PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002986"nice(inc) -> new_priority\n\n\
2987Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002988
Barry Warsaw53699e91996-12-10 23:23:01 +00002989static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002990posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002991{
Victor Stinner8c62be82010-05-06 00:08:46 +00002992 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002993
Victor Stinner8c62be82010-05-06 00:08:46 +00002994 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2995 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002996
Victor Stinner8c62be82010-05-06 00:08:46 +00002997 /* There are two flavours of 'nice': one that returns the new
2998 priority (as required by almost all standards out there) and the
2999 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3000 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003001
Victor Stinner8c62be82010-05-06 00:08:46 +00003002 If we are of the nice family that returns the new priority, we
3003 need to clear errno before the call, and check if errno is filled
3004 before calling posix_error() on a returnvalue of -1, because the
3005 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003006
Victor Stinner8c62be82010-05-06 00:08:46 +00003007 errno = 0;
3008 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003009#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003010 if (value == 0)
3011 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003012#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003013 if (value == -1 && errno != 0)
3014 /* either nice() or getpriority() returned an error */
3015 return posix_error();
3016 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003017}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003018#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003019
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003020PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003021"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003022Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003023
Barry Warsaw53699e91996-12-10 23:23:01 +00003024static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003025posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003026{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003027#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003028 PyObject *o1, *o2;
3029 char *p1, *p2;
3030 BOOL result;
3031 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
3032 goto error;
3033 if (!convert_to_unicode(&o1))
3034 goto error;
3035 if (!convert_to_unicode(&o2)) {
3036 Py_DECREF(o1);
3037 goto error;
3038 }
3039 Py_BEGIN_ALLOW_THREADS
3040 result = MoveFileW(PyUnicode_AsUnicode(o1),
3041 PyUnicode_AsUnicode(o2));
3042 Py_END_ALLOW_THREADS
3043 Py_DECREF(o1);
3044 Py_DECREF(o2);
3045 if (!result)
3046 return win32_error("rename", NULL);
3047 Py_INCREF(Py_None);
3048 return Py_None;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003049error:
Victor Stinner8c62be82010-05-06 00:08:46 +00003050 PyErr_Clear();
3051 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
3052 return NULL;
3053 Py_BEGIN_ALLOW_THREADS
3054 result = MoveFileA(p1, p2);
3055 Py_END_ALLOW_THREADS
3056 if (!result)
3057 return win32_error("rename", NULL);
3058 Py_INCREF(Py_None);
3059 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003060#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003061 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003062#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003063}
3064
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003065
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003066PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003067"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003068Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003069
Barry Warsaw53699e91996-12-10 23:23:01 +00003070static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003071posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003072{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003073#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003074 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003075#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003076 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003077#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003078}
3079
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003080
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003081PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003082"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003083Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003084
Barry Warsaw53699e91996-12-10 23:23:01 +00003085static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003086posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003087{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003088#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00003089 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003090#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003091 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003092#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003093}
3094
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003095
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003096#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003097PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003098"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003099Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003100
Barry Warsaw53699e91996-12-10 23:23:01 +00003101static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003102posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003103{
Victor Stinner8c62be82010-05-06 00:08:46 +00003104 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00003105#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003106 wchar_t *command;
3107 if (!PyArg_ParseTuple(args, "u:system", &command))
3108 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003109
Victor Stinner8c62be82010-05-06 00:08:46 +00003110 Py_BEGIN_ALLOW_THREADS
3111 sts = _wsystem(command);
3112 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00003113#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003114 PyObject *command_obj;
3115 char *command;
3116 if (!PyArg_ParseTuple(args, "O&:system",
3117 PyUnicode_FSConverter, &command_obj))
3118 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003119
Victor Stinner8c62be82010-05-06 00:08:46 +00003120 command = PyBytes_AsString(command_obj);
3121 Py_BEGIN_ALLOW_THREADS
3122 sts = system(command);
3123 Py_END_ALLOW_THREADS
3124 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00003125#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003126 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003127}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003128#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003129
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003130
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003131PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003132"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003133Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003134
Barry Warsaw53699e91996-12-10 23:23:01 +00003135static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003136posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003137{
Victor Stinner8c62be82010-05-06 00:08:46 +00003138 int i;
3139 if (!PyArg_ParseTuple(args, "i:umask", &i))
3140 return NULL;
3141 i = (int)umask(i);
3142 if (i < 0)
3143 return posix_error();
3144 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003145}
3146
Brian Curtind40e6f72010-07-08 21:39:08 +00003147#ifdef MS_WINDOWS
3148
3149/* override the default DeleteFileW behavior so that directory
3150symlinks can be removed with this function, the same as with
3151Unix symlinks */
3152BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
3153{
3154 WIN32_FILE_ATTRIBUTE_DATA info;
3155 WIN32_FIND_DATAW find_data;
3156 HANDLE find_data_handle;
3157 int is_directory = 0;
3158 int is_link = 0;
3159
3160 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3161 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
3162
3163 /* Get WIN32_FIND_DATA structure for the path to determine if
3164 it is a symlink */
3165 if(is_directory &&
3166 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3167 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3168
3169 if(find_data_handle != INVALID_HANDLE_VALUE) {
3170 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3171 FindClose(find_data_handle);
3172 }
3173 }
3174 }
3175
3176 if (is_directory && is_link)
3177 return RemoveDirectoryW(lpFileName);
3178
3179 return DeleteFileW(lpFileName);
3180}
3181#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003182
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003183PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003184"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003185Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003186
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003187PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003188"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003189Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003190
Barry Warsaw53699e91996-12-10 23:23:01 +00003191static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003192posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003193{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003194#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003195 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3196 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003197#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003198 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003199#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003200}
3201
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003202
Guido van Rossumb6775db1994-08-01 11:34:53 +00003203#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003204PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003205"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003206Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003207
Barry Warsaw53699e91996-12-10 23:23:01 +00003208static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003209posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003210{
Victor Stinner8c62be82010-05-06 00:08:46 +00003211 struct utsname u;
3212 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003213
Victor Stinner8c62be82010-05-06 00:08:46 +00003214 Py_BEGIN_ALLOW_THREADS
3215 res = uname(&u);
3216 Py_END_ALLOW_THREADS
3217 if (res < 0)
3218 return posix_error();
3219 return Py_BuildValue("(sssss)",
3220 u.sysname,
3221 u.nodename,
3222 u.release,
3223 u.version,
3224 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003225}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003226#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003227
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003228static int
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003229extract_time(PyObject *t, time_t* sec, long* usec)
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003230{
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003231 time_t intval;
Victor Stinner8c62be82010-05-06 00:08:46 +00003232 if (PyFloat_Check(t)) {
3233 double tval = PyFloat_AsDouble(t);
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003234 PyObject *intobj = PyNumber_Long(t);
Victor Stinner8c62be82010-05-06 00:08:46 +00003235 if (!intobj)
3236 return -1;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003237#if SIZEOF_TIME_T > SIZEOF_LONG
3238 intval = PyLong_AsUnsignedLongLongMask(intobj);
3239#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003240 intval = PyLong_AsLong(intobj);
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003241#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003242 Py_DECREF(intobj);
3243 if (intval == -1 && PyErr_Occurred())
3244 return -1;
3245 *sec = intval;
3246 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
3247 if (*usec < 0)
3248 /* If rounding gave us a negative number,
3249 truncate. */
3250 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00003251 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003252 }
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003253#if SIZEOF_TIME_T > SIZEOF_LONG
3254 intval = PyLong_AsUnsignedLongLongMask(t);
3255#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003256 intval = PyLong_AsLong(t);
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003257#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003258 if (intval == -1 && PyErr_Occurred())
3259 return -1;
3260 *sec = intval;
3261 *usec = 0;
3262 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003263}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003264
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003265PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00003266"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00003267utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00003268Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003269second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003270
Barry Warsaw53699e91996-12-10 23:23:01 +00003271static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003272posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003273{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003274#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003275 PyObject *arg;
3276 PyUnicodeObject *obwpath;
3277 wchar_t *wpath = NULL;
3278 PyObject *oapath;
3279 char *apath;
3280 HANDLE hFile;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003281 time_t atimesec, mtimesec;
3282 long ausec, musec;
Victor Stinner8c62be82010-05-06 00:08:46 +00003283 FILETIME atime, mtime;
3284 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003285
Victor Stinner8c62be82010-05-06 00:08:46 +00003286 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
3287 wpath = PyUnicode_AS_UNICODE(obwpath);
3288 Py_BEGIN_ALLOW_THREADS
3289 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3290 NULL, OPEN_EXISTING,
3291 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3292 Py_END_ALLOW_THREADS
3293 if (hFile == INVALID_HANDLE_VALUE)
3294 return win32_error_unicode("utime", wpath);
3295 } else
3296 /* Drop the argument parsing error as narrow strings
3297 are also valid. */
3298 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003299
Victor Stinner8c62be82010-05-06 00:08:46 +00003300 if (!wpath) {
3301 if (!PyArg_ParseTuple(args, "O&O:utime",
3302 PyUnicode_FSConverter, &oapath, &arg))
3303 return NULL;
3304 apath = PyBytes_AsString(oapath);
3305 Py_BEGIN_ALLOW_THREADS
3306 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3307 NULL, OPEN_EXISTING,
3308 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3309 Py_END_ALLOW_THREADS
3310 if (hFile == INVALID_HANDLE_VALUE) {
3311 win32_error("utime", apath);
3312 Py_DECREF(oapath);
3313 return NULL;
3314 }
3315 Py_DECREF(oapath);
3316 }
3317
3318 if (arg == Py_None) {
3319 SYSTEMTIME now;
3320 GetSystemTime(&now);
3321 if (!SystemTimeToFileTime(&now, &mtime) ||
3322 !SystemTimeToFileTime(&now, &atime)) {
3323 win32_error("utime", NULL);
3324 goto done;
Stefan Krah0e803b32010-11-26 16:16:47 +00003325 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003326 }
3327 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3328 PyErr_SetString(PyExc_TypeError,
3329 "utime() arg 2 must be a tuple (atime, mtime)");
3330 goto done;
3331 }
3332 else {
3333 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3334 &atimesec, &ausec) == -1)
3335 goto done;
3336 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3337 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3338 &mtimesec, &musec) == -1)
3339 goto done;
3340 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3341 }
3342 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3343 /* Avoid putting the file name into the error here,
3344 as that may confuse the user into believing that
3345 something is wrong with the file, when it also
3346 could be the time stamp that gives a problem. */
3347 win32_error("utime", NULL);
Antoine Pitroue85da7a2011-01-06 18:25:55 +00003348 goto done;
Victor Stinner8c62be82010-05-06 00:08:46 +00003349 }
3350 Py_INCREF(Py_None);
3351 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003352done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003353 CloseHandle(hFile);
3354 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003355#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003356
Victor Stinner8c62be82010-05-06 00:08:46 +00003357 PyObject *opath;
3358 char *path;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003359 time_t atime, mtime;
3360 long ausec, musec;
Victor Stinner8c62be82010-05-06 00:08:46 +00003361 int res;
3362 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003363
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003364#if defined(HAVE_UTIMES)
Victor Stinner8c62be82010-05-06 00:08:46 +00003365 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003366#define ATIME buf[0].tv_sec
3367#define MTIME buf[1].tv_sec
3368#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003369/* XXX should define struct utimbuf instead, above */
Victor Stinner8c62be82010-05-06 00:08:46 +00003370 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003371#define ATIME buf.actime
3372#define MTIME buf.modtime
3373#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003374#else /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003375 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003376#define ATIME buf[0]
3377#define MTIME buf[1]
3378#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003379#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003380
Mark Hammond817c9292003-12-03 01:22:38 +00003381
Victor Stinner8c62be82010-05-06 00:08:46 +00003382 if (!PyArg_ParseTuple(args, "O&O:utime",
3383 PyUnicode_FSConverter, &opath, &arg))
3384 return NULL;
3385 path = PyBytes_AsString(opath);
3386 if (arg == Py_None) {
3387 /* optional time values not given */
3388 Py_BEGIN_ALLOW_THREADS
3389 res = utime(path, NULL);
3390 Py_END_ALLOW_THREADS
3391 }
3392 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3393 PyErr_SetString(PyExc_TypeError,
3394 "utime() arg 2 must be a tuple (atime, mtime)");
3395 Py_DECREF(opath);
3396 return NULL;
3397 }
3398 else {
3399 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3400 &atime, &ausec) == -1) {
3401 Py_DECREF(opath);
3402 return NULL;
3403 }
3404 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3405 &mtime, &musec) == -1) {
3406 Py_DECREF(opath);
3407 return NULL;
3408 }
3409 ATIME = atime;
3410 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003411#ifdef HAVE_UTIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00003412 buf[0].tv_usec = ausec;
3413 buf[1].tv_usec = musec;
3414 Py_BEGIN_ALLOW_THREADS
3415 res = utimes(path, buf);
3416 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003417#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003418 Py_BEGIN_ALLOW_THREADS
3419 res = utime(path, UTIME_ARG);
3420 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003421#endif /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003422 }
3423 if (res < 0) {
3424 return posix_error_with_allocated_filename(opath);
3425 }
3426 Py_DECREF(opath);
3427 Py_INCREF(Py_None);
3428 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003429#undef UTIME_ARG
3430#undef ATIME
3431#undef MTIME
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003432#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003433}
3434
Guido van Rossum85e3b011991-06-03 12:42:10 +00003435
Guido van Rossum3b066191991-06-04 19:40:25 +00003436/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003437
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003438PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003439"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003440Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003441
Barry Warsaw53699e91996-12-10 23:23:01 +00003442static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003443posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003444{
Victor Stinner8c62be82010-05-06 00:08:46 +00003445 int sts;
3446 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3447 return NULL;
3448 _exit(sts);
3449 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003450}
3451
Martin v. Löwis114619e2002-10-07 06:44:21 +00003452#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3453static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003454free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003455{
Victor Stinner8c62be82010-05-06 00:08:46 +00003456 Py_ssize_t i;
3457 for (i = 0; i < count; i++)
3458 PyMem_Free(array[i]);
3459 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003460}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003461
Antoine Pitrou69f71142009-05-24 21:25:49 +00003462static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003463int fsconvert_strdup(PyObject *o, char**out)
3464{
Victor Stinner8c62be82010-05-06 00:08:46 +00003465 PyObject *bytes;
3466 Py_ssize_t size;
3467 if (!PyUnicode_FSConverter(o, &bytes))
3468 return 0;
3469 size = PyBytes_GET_SIZE(bytes);
3470 *out = PyMem_Malloc(size+1);
3471 if (!*out)
3472 return 0;
3473 memcpy(*out, PyBytes_AsString(bytes), size+1);
3474 Py_DECREF(bytes);
3475 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003476}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003477#endif
3478
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003479
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003480#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003481PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003482"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003483Execute an executable path with arguments, replacing current process.\n\
3484\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003485 path: path of executable file\n\
3486 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003487
Barry Warsaw53699e91996-12-10 23:23:01 +00003488static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003489posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003490{
Victor Stinner8c62be82010-05-06 00:08:46 +00003491 PyObject *opath;
3492 char *path;
3493 PyObject *argv;
3494 char **argvlist;
3495 Py_ssize_t i, argc;
3496 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003497
Victor Stinner8c62be82010-05-06 00:08:46 +00003498 /* execv has two arguments: (path, argv), where
3499 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003500
Victor Stinner8c62be82010-05-06 00:08:46 +00003501 if (!PyArg_ParseTuple(args, "O&O:execv",
3502 PyUnicode_FSConverter,
3503 &opath, &argv))
3504 return NULL;
3505 path = PyBytes_AsString(opath);
3506 if (PyList_Check(argv)) {
3507 argc = PyList_Size(argv);
3508 getitem = PyList_GetItem;
3509 }
3510 else if (PyTuple_Check(argv)) {
3511 argc = PyTuple_Size(argv);
3512 getitem = PyTuple_GetItem;
3513 }
3514 else {
3515 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3516 Py_DECREF(opath);
3517 return NULL;
3518 }
3519 if (argc < 1) {
3520 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3521 Py_DECREF(opath);
3522 return NULL;
3523 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003524
Victor Stinner8c62be82010-05-06 00:08:46 +00003525 argvlist = PyMem_NEW(char *, argc+1);
3526 if (argvlist == NULL) {
3527 Py_DECREF(opath);
3528 return PyErr_NoMemory();
3529 }
3530 for (i = 0; i < argc; i++) {
3531 if (!fsconvert_strdup((*getitem)(argv, i),
3532 &argvlist[i])) {
3533 free_string_array(argvlist, i);
3534 PyErr_SetString(PyExc_TypeError,
3535 "execv() arg 2 must contain only strings");
3536 Py_DECREF(opath);
3537 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003538
Victor Stinner8c62be82010-05-06 00:08:46 +00003539 }
3540 }
3541 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003542
Victor Stinner8c62be82010-05-06 00:08:46 +00003543 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003544
Victor Stinner8c62be82010-05-06 00:08:46 +00003545 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003546
Victor Stinner8c62be82010-05-06 00:08:46 +00003547 free_string_array(argvlist, argc);
3548 Py_DECREF(opath);
3549 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003550}
3551
Victor Stinner13bb71c2010-04-23 21:41:56 +00003552static char**
3553parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3554{
Victor Stinner8c62be82010-05-06 00:08:46 +00003555 char **envlist;
3556 Py_ssize_t i, pos, envc;
3557 PyObject *keys=NULL, *vals=NULL;
3558 PyObject *key, *val, *key2, *val2;
3559 char *p, *k, *v;
3560 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003561
Victor Stinner8c62be82010-05-06 00:08:46 +00003562 i = PyMapping_Size(env);
3563 if (i < 0)
3564 return NULL;
3565 envlist = PyMem_NEW(char *, i + 1);
3566 if (envlist == NULL) {
3567 PyErr_NoMemory();
3568 return NULL;
3569 }
3570 envc = 0;
3571 keys = PyMapping_Keys(env);
3572 vals = PyMapping_Values(env);
3573 if (!keys || !vals)
3574 goto error;
3575 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3576 PyErr_Format(PyExc_TypeError,
3577 "env.keys() or env.values() is not a list");
3578 goto error;
3579 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003580
Victor Stinner8c62be82010-05-06 00:08:46 +00003581 for (pos = 0; pos < i; pos++) {
3582 key = PyList_GetItem(keys, pos);
3583 val = PyList_GetItem(vals, pos);
3584 if (!key || !val)
3585 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003586
Victor Stinner8c62be82010-05-06 00:08:46 +00003587 if (PyUnicode_FSConverter(key, &key2) == 0)
3588 goto error;
3589 if (PyUnicode_FSConverter(val, &val2) == 0) {
3590 Py_DECREF(key2);
3591 goto error;
3592 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003593
3594#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003595 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3596 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00003597#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003598 k = PyBytes_AsString(key2);
3599 v = PyBytes_AsString(val2);
3600 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003601
Victor Stinner8c62be82010-05-06 00:08:46 +00003602 p = PyMem_NEW(char, len);
3603 if (p == NULL) {
3604 PyErr_NoMemory();
3605 Py_DECREF(key2);
3606 Py_DECREF(val2);
3607 goto error;
3608 }
3609 PyOS_snprintf(p, len, "%s=%s", k, v);
3610 envlist[envc++] = p;
3611 Py_DECREF(key2);
3612 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003613#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003614 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003615#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003616 }
3617 Py_DECREF(vals);
3618 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003619
Victor Stinner8c62be82010-05-06 00:08:46 +00003620 envlist[envc] = 0;
3621 *envc_ptr = envc;
3622 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003623
3624error:
Victor Stinner8c62be82010-05-06 00:08:46 +00003625 Py_XDECREF(keys);
3626 Py_XDECREF(vals);
3627 while (--envc >= 0)
3628 PyMem_DEL(envlist[envc]);
3629 PyMem_DEL(envlist);
3630 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003631}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003632
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003633PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003634"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003635Execute a path with arguments and environment, replacing current process.\n\
3636\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003637 path: path of executable file\n\
3638 args: tuple or list of arguments\n\
3639 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003640
Barry Warsaw53699e91996-12-10 23:23:01 +00003641static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003642posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003643{
Victor Stinner8c62be82010-05-06 00:08:46 +00003644 PyObject *opath;
3645 char *path;
3646 PyObject *argv, *env;
3647 char **argvlist;
3648 char **envlist;
3649 Py_ssize_t i, argc, envc;
3650 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3651 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003652
Victor Stinner8c62be82010-05-06 00:08:46 +00003653 /* execve has three arguments: (path, argv, env), where
3654 argv is a list or tuple of strings and env is a dictionary
3655 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003656
Victor Stinner8c62be82010-05-06 00:08:46 +00003657 if (!PyArg_ParseTuple(args, "O&OO:execve",
3658 PyUnicode_FSConverter,
3659 &opath, &argv, &env))
3660 return NULL;
3661 path = PyBytes_AsString(opath);
3662 if (PyList_Check(argv)) {
3663 argc = PyList_Size(argv);
3664 getitem = PyList_GetItem;
3665 }
3666 else if (PyTuple_Check(argv)) {
3667 argc = PyTuple_Size(argv);
3668 getitem = PyTuple_GetItem;
3669 }
3670 else {
3671 PyErr_SetString(PyExc_TypeError,
3672 "execve() arg 2 must be a tuple or list");
3673 goto fail_0;
3674 }
3675 if (!PyMapping_Check(env)) {
3676 PyErr_SetString(PyExc_TypeError,
3677 "execve() arg 3 must be a mapping object");
3678 goto fail_0;
3679 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003680
Victor Stinner8c62be82010-05-06 00:08:46 +00003681 argvlist = PyMem_NEW(char *, argc+1);
3682 if (argvlist == NULL) {
3683 PyErr_NoMemory();
3684 goto fail_0;
3685 }
3686 for (i = 0; i < argc; i++) {
3687 if (!fsconvert_strdup((*getitem)(argv, i),
3688 &argvlist[i]))
3689 {
3690 lastarg = i;
3691 goto fail_1;
3692 }
3693 }
3694 lastarg = argc;
3695 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003696
Victor Stinner8c62be82010-05-06 00:08:46 +00003697 envlist = parse_envlist(env, &envc);
3698 if (envlist == NULL)
3699 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003700
Victor Stinner8c62be82010-05-06 00:08:46 +00003701 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003702
Victor Stinner8c62be82010-05-06 00:08:46 +00003703 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003704
Victor Stinner8c62be82010-05-06 00:08:46 +00003705 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003706
Victor Stinner8c62be82010-05-06 00:08:46 +00003707 while (--envc >= 0)
3708 PyMem_DEL(envlist[envc]);
3709 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003710 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003711 free_string_array(argvlist, lastarg);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003712 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003713 Py_DECREF(opath);
3714 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003715}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003716#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003717
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003718
Guido van Rossuma1065681999-01-25 23:20:23 +00003719#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003720PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003721"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003722Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003723\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003724 mode: mode of process creation\n\
3725 path: path of executable file\n\
3726 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003727
3728static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003729posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003730{
Victor Stinner8c62be82010-05-06 00:08:46 +00003731 PyObject *opath;
3732 char *path;
3733 PyObject *argv;
3734 char **argvlist;
3735 int mode, i;
3736 Py_ssize_t argc;
3737 Py_intptr_t spawnval;
3738 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003739
Victor Stinner8c62be82010-05-06 00:08:46 +00003740 /* spawnv has three arguments: (mode, path, argv), where
3741 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003742
Victor Stinner8c62be82010-05-06 00:08:46 +00003743 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3744 PyUnicode_FSConverter,
3745 &opath, &argv))
3746 return NULL;
3747 path = PyBytes_AsString(opath);
3748 if (PyList_Check(argv)) {
3749 argc = PyList_Size(argv);
3750 getitem = PyList_GetItem;
3751 }
3752 else if (PyTuple_Check(argv)) {
3753 argc = PyTuple_Size(argv);
3754 getitem = PyTuple_GetItem;
3755 }
3756 else {
3757 PyErr_SetString(PyExc_TypeError,
3758 "spawnv() arg 2 must be a tuple or list");
3759 Py_DECREF(opath);
3760 return NULL;
3761 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003762
Victor Stinner8c62be82010-05-06 00:08:46 +00003763 argvlist = PyMem_NEW(char *, argc+1);
3764 if (argvlist == NULL) {
3765 Py_DECREF(opath);
3766 return PyErr_NoMemory();
3767 }
3768 for (i = 0; i < argc; i++) {
3769 if (!fsconvert_strdup((*getitem)(argv, i),
3770 &argvlist[i])) {
3771 free_string_array(argvlist, i);
3772 PyErr_SetString(
3773 PyExc_TypeError,
3774 "spawnv() arg 2 must contain only strings");
3775 Py_DECREF(opath);
3776 return NULL;
3777 }
3778 }
3779 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003780
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003781#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003782 Py_BEGIN_ALLOW_THREADS
3783 spawnval = spawnv(mode, path, argvlist);
3784 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003785#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003786 if (mode == _OLD_P_OVERLAY)
3787 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003788
Victor Stinner8c62be82010-05-06 00:08:46 +00003789 Py_BEGIN_ALLOW_THREADS
3790 spawnval = _spawnv(mode, path, argvlist);
3791 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003792#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003793
Victor Stinner8c62be82010-05-06 00:08:46 +00003794 free_string_array(argvlist, argc);
3795 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003796
Victor Stinner8c62be82010-05-06 00:08:46 +00003797 if (spawnval == -1)
3798 return posix_error();
3799 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003800#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003801 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003802#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003803 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003804#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003805}
3806
3807
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003808PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003809"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003810Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003811\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003812 mode: mode of process creation\n\
3813 path: path of executable file\n\
3814 args: tuple or list of arguments\n\
3815 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003816
3817static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003818posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003819{
Victor Stinner8c62be82010-05-06 00:08:46 +00003820 PyObject *opath;
3821 char *path;
3822 PyObject *argv, *env;
3823 char **argvlist;
3824 char **envlist;
3825 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003826 int mode;
3827 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003828 Py_intptr_t spawnval;
3829 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3830 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003831
Victor Stinner8c62be82010-05-06 00:08:46 +00003832 /* spawnve has four arguments: (mode, path, argv, env), where
3833 argv is a list or tuple of strings and env is a dictionary
3834 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003835
Victor Stinner8c62be82010-05-06 00:08:46 +00003836 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3837 PyUnicode_FSConverter,
3838 &opath, &argv, &env))
3839 return NULL;
3840 path = PyBytes_AsString(opath);
3841 if (PyList_Check(argv)) {
3842 argc = PyList_Size(argv);
3843 getitem = PyList_GetItem;
3844 }
3845 else if (PyTuple_Check(argv)) {
3846 argc = PyTuple_Size(argv);
3847 getitem = PyTuple_GetItem;
3848 }
3849 else {
3850 PyErr_SetString(PyExc_TypeError,
3851 "spawnve() arg 2 must be a tuple or list");
3852 goto fail_0;
3853 }
3854 if (!PyMapping_Check(env)) {
3855 PyErr_SetString(PyExc_TypeError,
3856 "spawnve() arg 3 must be a mapping object");
3857 goto fail_0;
3858 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003859
Victor Stinner8c62be82010-05-06 00:08:46 +00003860 argvlist = PyMem_NEW(char *, argc+1);
3861 if (argvlist == NULL) {
3862 PyErr_NoMemory();
3863 goto fail_0;
3864 }
3865 for (i = 0; i < argc; i++) {
3866 if (!fsconvert_strdup((*getitem)(argv, i),
3867 &argvlist[i]))
3868 {
3869 lastarg = i;
3870 goto fail_1;
3871 }
3872 }
3873 lastarg = argc;
3874 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003875
Victor Stinner8c62be82010-05-06 00:08:46 +00003876 envlist = parse_envlist(env, &envc);
3877 if (envlist == NULL)
3878 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003879
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003880#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003881 Py_BEGIN_ALLOW_THREADS
3882 spawnval = spawnve(mode, path, argvlist, envlist);
3883 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003884#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003885 if (mode == _OLD_P_OVERLAY)
3886 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003887
Victor Stinner8c62be82010-05-06 00:08:46 +00003888 Py_BEGIN_ALLOW_THREADS
3889 spawnval = _spawnve(mode, path, argvlist, envlist);
3890 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003891#endif
Tim Peters25059d32001-12-07 20:35:43 +00003892
Victor Stinner8c62be82010-05-06 00:08:46 +00003893 if (spawnval == -1)
3894 (void) posix_error();
3895 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003896#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003897 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003898#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003899 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003900#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003901
Victor Stinner8c62be82010-05-06 00:08:46 +00003902 while (--envc >= 0)
3903 PyMem_DEL(envlist[envc]);
3904 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003905 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003906 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003907 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003908 Py_DECREF(opath);
3909 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003910}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003911
3912/* OS/2 supports spawnvp & spawnvpe natively */
3913#if defined(PYOS_OS2)
3914PyDoc_STRVAR(posix_spawnvp__doc__,
3915"spawnvp(mode, file, args)\n\n\
3916Execute the program 'file' in a new process, using the environment\n\
3917search path to find the file.\n\
3918\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003919 mode: mode of process creation\n\
3920 file: executable file name\n\
3921 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003922
3923static PyObject *
3924posix_spawnvp(PyObject *self, PyObject *args)
3925{
Victor Stinner8c62be82010-05-06 00:08:46 +00003926 PyObject *opath;
3927 char *path;
3928 PyObject *argv;
3929 char **argvlist;
3930 int mode, i, argc;
3931 Py_intptr_t spawnval;
3932 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003933
Victor Stinner8c62be82010-05-06 00:08:46 +00003934 /* spawnvp has three arguments: (mode, path, argv), where
3935 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003936
Victor Stinner8c62be82010-05-06 00:08:46 +00003937 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3938 PyUnicode_FSConverter,
3939 &opath, &argv))
3940 return NULL;
3941 path = PyBytes_AsString(opath);
3942 if (PyList_Check(argv)) {
3943 argc = PyList_Size(argv);
3944 getitem = PyList_GetItem;
3945 }
3946 else if (PyTuple_Check(argv)) {
3947 argc = PyTuple_Size(argv);
3948 getitem = PyTuple_GetItem;
3949 }
3950 else {
3951 PyErr_SetString(PyExc_TypeError,
3952 "spawnvp() arg 2 must be a tuple or list");
3953 Py_DECREF(opath);
3954 return NULL;
3955 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003956
Victor Stinner8c62be82010-05-06 00:08:46 +00003957 argvlist = PyMem_NEW(char *, argc+1);
3958 if (argvlist == NULL) {
3959 Py_DECREF(opath);
3960 return PyErr_NoMemory();
3961 }
3962 for (i = 0; i < argc; i++) {
3963 if (!fsconvert_strdup((*getitem)(argv, i),
3964 &argvlist[i])) {
3965 free_string_array(argvlist, i);
3966 PyErr_SetString(
3967 PyExc_TypeError,
3968 "spawnvp() arg 2 must contain only strings");
3969 Py_DECREF(opath);
3970 return NULL;
3971 }
3972 }
3973 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003974
Victor Stinner8c62be82010-05-06 00:08:46 +00003975 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003976#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003977 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003978#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003979 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003980#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003981 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003982
Victor Stinner8c62be82010-05-06 00:08:46 +00003983 free_string_array(argvlist, argc);
3984 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003985
Victor Stinner8c62be82010-05-06 00:08:46 +00003986 if (spawnval == -1)
3987 return posix_error();
3988 else
3989 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003990}
3991
3992
3993PyDoc_STRVAR(posix_spawnvpe__doc__,
3994"spawnvpe(mode, file, args, env)\n\n\
3995Execute the program 'file' in a new process, using the environment\n\
3996search path to find the file.\n\
3997\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003998 mode: mode of process creation\n\
3999 file: executable file name\n\
4000 args: tuple or list of arguments\n\
4001 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004002
4003static PyObject *
4004posix_spawnvpe(PyObject *self, PyObject *args)
4005{
Victor Stinner8c62be82010-05-06 00:08:46 +00004006 PyObject *opath
4007 char *path;
4008 PyObject *argv, *env;
4009 char **argvlist;
4010 char **envlist;
4011 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004012 int mode;
4013 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004014 Py_intptr_t spawnval;
4015 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4016 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004017
Victor Stinner8c62be82010-05-06 00:08:46 +00004018 /* spawnvpe has four arguments: (mode, path, argv, env), where
4019 argv is a list or tuple of strings and env is a dictionary
4020 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004021
Victor Stinner8c62be82010-05-06 00:08:46 +00004022 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
4023 PyUnicode_FSConverter,
4024 &opath, &argv, &env))
4025 return NULL;
4026 path = PyBytes_AsString(opath);
4027 if (PyList_Check(argv)) {
4028 argc = PyList_Size(argv);
4029 getitem = PyList_GetItem;
4030 }
4031 else if (PyTuple_Check(argv)) {
4032 argc = PyTuple_Size(argv);
4033 getitem = PyTuple_GetItem;
4034 }
4035 else {
4036 PyErr_SetString(PyExc_TypeError,
4037 "spawnvpe() arg 2 must be a tuple or list");
4038 goto fail_0;
4039 }
4040 if (!PyMapping_Check(env)) {
4041 PyErr_SetString(PyExc_TypeError,
4042 "spawnvpe() arg 3 must be a mapping object");
4043 goto fail_0;
4044 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004045
Victor Stinner8c62be82010-05-06 00:08:46 +00004046 argvlist = PyMem_NEW(char *, argc+1);
4047 if (argvlist == NULL) {
4048 PyErr_NoMemory();
4049 goto fail_0;
4050 }
4051 for (i = 0; i < argc; i++) {
4052 if (!fsconvert_strdup((*getitem)(argv, i),
4053 &argvlist[i]))
4054 {
4055 lastarg = i;
4056 goto fail_1;
4057 }
4058 }
4059 lastarg = argc;
4060 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004061
Victor Stinner8c62be82010-05-06 00:08:46 +00004062 envlist = parse_envlist(env, &envc);
4063 if (envlist == NULL)
4064 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004065
Victor Stinner8c62be82010-05-06 00:08:46 +00004066 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004067#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004068 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004069#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004070 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004071#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004072 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004073
Victor Stinner8c62be82010-05-06 00:08:46 +00004074 if (spawnval == -1)
4075 (void) posix_error();
4076 else
4077 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004078
Victor Stinner8c62be82010-05-06 00:08:46 +00004079 while (--envc >= 0)
4080 PyMem_DEL(envlist[envc]);
4081 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004082 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004083 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004084 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004085 Py_DECREF(opath);
4086 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004087}
4088#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00004089#endif /* HAVE_SPAWNV */
4090
4091
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004092#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004093PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004094"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004095Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
4096\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004097Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004098
4099static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004100posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004101{
Victor Stinner8c62be82010-05-06 00:08:46 +00004102 pid_t pid;
4103 int result = 0;
4104 _PyImport_AcquireLock();
4105 pid = fork1();
4106 if (pid == 0) {
4107 /* child: this clobbers and resets the import lock. */
4108 PyOS_AfterFork();
4109 } else {
4110 /* parent: release the import lock. */
4111 result = _PyImport_ReleaseLock();
4112 }
4113 if (pid == -1)
4114 return posix_error();
4115 if (result < 0) {
4116 /* Don't clobber the OSError if the fork failed. */
4117 PyErr_SetString(PyExc_RuntimeError,
4118 "not holding the import lock");
4119 return NULL;
4120 }
4121 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004122}
4123#endif
4124
4125
Guido van Rossumad0ee831995-03-01 10:34:45 +00004126#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004127PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004128"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004129Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004130Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004131
Barry Warsaw53699e91996-12-10 23:23:01 +00004132static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004133posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004134{
Victor Stinner8c62be82010-05-06 00:08:46 +00004135 pid_t pid;
4136 int result = 0;
4137 _PyImport_AcquireLock();
4138 pid = fork();
4139 if (pid == 0) {
4140 /* child: this clobbers and resets the import lock. */
4141 PyOS_AfterFork();
4142 } else {
4143 /* parent: release the import lock. */
4144 result = _PyImport_ReleaseLock();
4145 }
4146 if (pid == -1)
4147 return posix_error();
4148 if (result < 0) {
4149 /* Don't clobber the OSError if the fork failed. */
4150 PyErr_SetString(PyExc_RuntimeError,
4151 "not holding the import lock");
4152 return NULL;
4153 }
4154 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00004155}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004156#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004157
Neal Norwitzb59798b2003-03-21 01:43:31 +00004158/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00004159/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
4160#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00004161#define DEV_PTY_FILE "/dev/ptc"
4162#define HAVE_DEV_PTMX
4163#else
4164#define DEV_PTY_FILE "/dev/ptmx"
4165#endif
4166
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004167#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004168#ifdef HAVE_PTY_H
4169#include <pty.h>
4170#else
4171#ifdef HAVE_LIBUTIL_H
4172#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00004173#else
4174#ifdef HAVE_UTIL_H
4175#include <util.h>
4176#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004177#endif /* HAVE_LIBUTIL_H */
4178#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00004179#ifdef HAVE_STROPTS_H
4180#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004181#endif
4182#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004183
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004184#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004185PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004186"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004187Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004188
4189static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004190posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004191{
Victor Stinner8c62be82010-05-06 00:08:46 +00004192 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004193#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004194 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004195#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004196#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004197 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004198#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00004199 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004200#endif
4201#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00004202
Thomas Wouters70c21a12000-07-14 14:28:33 +00004203#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004204 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
4205 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004206#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004207 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
4208 if (slave_name == NULL)
4209 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00004210
Victor Stinner8c62be82010-05-06 00:08:46 +00004211 slave_fd = open(slave_name, O_RDWR);
4212 if (slave_fd < 0)
4213 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004214#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004215 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
4216 if (master_fd < 0)
4217 return posix_error();
4218 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
4219 /* change permission of slave */
4220 if (grantpt(master_fd) < 0) {
4221 PyOS_setsig(SIGCHLD, sig_saved);
4222 return posix_error();
4223 }
4224 /* unlock slave */
4225 if (unlockpt(master_fd) < 0) {
4226 PyOS_setsig(SIGCHLD, sig_saved);
4227 return posix_error();
4228 }
4229 PyOS_setsig(SIGCHLD, sig_saved);
4230 slave_name = ptsname(master_fd); /* get name of slave */
4231 if (slave_name == NULL)
4232 return posix_error();
4233 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
4234 if (slave_fd < 0)
4235 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004236#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004237 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
4238 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00004239#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00004240 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00004241#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004242#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00004243#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00004244
Victor Stinner8c62be82010-05-06 00:08:46 +00004245 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00004246
Fred Drake8cef4cf2000-06-28 16:40:38 +00004247}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004248#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004249
4250#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004251PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004252"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00004253Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
4254Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004255To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004256
4257static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004258posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004259{
Victor Stinner8c62be82010-05-06 00:08:46 +00004260 int master_fd = -1, result = 0;
4261 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00004262
Victor Stinner8c62be82010-05-06 00:08:46 +00004263 _PyImport_AcquireLock();
4264 pid = forkpty(&master_fd, NULL, NULL, NULL);
4265 if (pid == 0) {
4266 /* child: this clobbers and resets the import lock. */
4267 PyOS_AfterFork();
4268 } else {
4269 /* parent: release the import lock. */
4270 result = _PyImport_ReleaseLock();
4271 }
4272 if (pid == -1)
4273 return posix_error();
4274 if (result < 0) {
4275 /* Don't clobber the OSError if the fork failed. */
4276 PyErr_SetString(PyExc_RuntimeError,
4277 "not holding the import lock");
4278 return NULL;
4279 }
4280 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004281}
4282#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004283
Guido van Rossumad0ee831995-03-01 10:34:45 +00004284#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004285PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004286"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004287Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004288
Barry Warsaw53699e91996-12-10 23:23:01 +00004289static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004290posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004291{
Victor Stinner8c62be82010-05-06 00:08:46 +00004292 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004293}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004294#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004295
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004296
Guido van Rossumad0ee831995-03-01 10:34:45 +00004297#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004298PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004299"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004300Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004301
Barry Warsaw53699e91996-12-10 23:23:01 +00004302static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004303posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004304{
Victor Stinner8c62be82010-05-06 00:08:46 +00004305 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004306}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004307#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004308
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004309
Guido van Rossumad0ee831995-03-01 10:34:45 +00004310#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004311PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004312"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004313Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004314
Barry Warsaw53699e91996-12-10 23:23:01 +00004315static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004316posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004317{
Victor Stinner8c62be82010-05-06 00:08:46 +00004318 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004319}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004320#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004321
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004322
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004323PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004324"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004325Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004326
Barry Warsaw53699e91996-12-10 23:23:01 +00004327static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004328posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004329{
Victor Stinner8c62be82010-05-06 00:08:46 +00004330 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004331}
4332
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004333
Fred Drakec9680921999-12-13 16:37:25 +00004334#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004335PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004336"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004337Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004338
4339static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004340posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004341{
4342 PyObject *result = NULL;
4343
Fred Drakec9680921999-12-13 16:37:25 +00004344#ifdef NGROUPS_MAX
4345#define MAX_GROUPS NGROUPS_MAX
4346#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004347 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004348#define MAX_GROUPS 64
4349#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004350 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004351
4352 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
4353 * This is a helper variable to store the intermediate result when
4354 * that happens.
4355 *
4356 * To keep the code readable the OSX behaviour is unconditional,
4357 * according to the POSIX spec this should be safe on all unix-y
4358 * systems.
4359 */
4360 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00004361 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004362
Victor Stinner8c62be82010-05-06 00:08:46 +00004363 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004364 if (n < 0) {
4365 if (errno == EINVAL) {
4366 n = getgroups(0, NULL);
4367 if (n == -1) {
4368 return posix_error();
4369 }
4370 if (n == 0) {
4371 /* Avoid malloc(0) */
4372 alt_grouplist = grouplist;
4373 } else {
4374 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4375 if (alt_grouplist == NULL) {
4376 errno = EINVAL;
4377 return posix_error();
4378 }
4379 n = getgroups(n, alt_grouplist);
4380 if (n == -1) {
4381 PyMem_Free(alt_grouplist);
4382 return posix_error();
4383 }
4384 }
4385 } else {
4386 return posix_error();
4387 }
4388 }
4389 result = PyList_New(n);
4390 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004391 int i;
4392 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004393 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00004394 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00004395 Py_DECREF(result);
4396 result = NULL;
4397 break;
Fred Drakec9680921999-12-13 16:37:25 +00004398 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004399 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004400 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004401 }
4402
4403 if (alt_grouplist != grouplist) {
4404 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00004405 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004406
Fred Drakec9680921999-12-13 16:37:25 +00004407 return result;
4408}
4409#endif
4410
Antoine Pitroub7572f02009-12-02 20:46:48 +00004411#ifdef HAVE_INITGROUPS
4412PyDoc_STRVAR(posix_initgroups__doc__,
4413"initgroups(username, gid) -> None\n\n\
4414Call the system initgroups() to initialize the group access list with all of\n\
4415the groups of which the specified username is a member, plus the specified\n\
4416group id.");
4417
4418static PyObject *
4419posix_initgroups(PyObject *self, PyObject *args)
4420{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004421 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00004422 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004423 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00004424 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004425
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004426 if (!PyArg_ParseTuple(args, "O&l:initgroups",
4427 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00004428 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004429 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004430
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004431 res = initgroups(username, (gid_t) gid);
4432 Py_DECREF(oname);
4433 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00004434 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004435
Victor Stinner8c62be82010-05-06 00:08:46 +00004436 Py_INCREF(Py_None);
4437 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004438}
4439#endif
4440
Martin v. Löwis606edc12002-06-13 21:09:11 +00004441#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004442PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004443"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004444Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004445
4446static PyObject *
4447posix_getpgid(PyObject *self, PyObject *args)
4448{
Victor Stinner8c62be82010-05-06 00:08:46 +00004449 pid_t pid, pgid;
4450 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
4451 return NULL;
4452 pgid = getpgid(pid);
4453 if (pgid < 0)
4454 return posix_error();
4455 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004456}
4457#endif /* HAVE_GETPGID */
4458
4459
Guido van Rossumb6775db1994-08-01 11:34:53 +00004460#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004461PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004462"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004463Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004464
Barry Warsaw53699e91996-12-10 23:23:01 +00004465static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004466posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004467{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004468#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004469 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004470#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004471 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004472#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004473}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004474#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004475
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004476
Guido van Rossumb6775db1994-08-01 11:34:53 +00004477#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004478PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004479"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00004480Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004481
Barry Warsaw53699e91996-12-10 23:23:01 +00004482static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004483posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004484{
Guido van Rossum64933891994-10-20 21:56:42 +00004485#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004486 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004487#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004488 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004489#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004490 return posix_error();
4491 Py_INCREF(Py_None);
4492 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004493}
4494
Guido van Rossumb6775db1994-08-01 11:34:53 +00004495#endif /* HAVE_SETPGRP */
4496
Guido van Rossumad0ee831995-03-01 10:34:45 +00004497#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004498
4499#ifdef MS_WINDOWS
4500#include <tlhelp32.h>
4501
4502static PyObject*
4503win32_getppid()
4504{
4505 HANDLE snapshot;
4506 pid_t mypid;
4507 PyObject* result = NULL;
4508 BOOL have_record;
4509 PROCESSENTRY32 pe;
4510
4511 mypid = getpid(); /* This function never fails */
4512
4513 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
4514 if (snapshot == INVALID_HANDLE_VALUE)
4515 return PyErr_SetFromWindowsErr(GetLastError());
4516
4517 pe.dwSize = sizeof(pe);
4518 have_record = Process32First(snapshot, &pe);
4519 while (have_record) {
4520 if (mypid == (pid_t)pe.th32ProcessID) {
4521 /* We could cache the ulong value in a static variable. */
4522 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
4523 break;
4524 }
4525
4526 have_record = Process32Next(snapshot, &pe);
4527 }
4528
4529 /* If our loop exits and our pid was not found (result will be NULL)
4530 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
4531 * error anyway, so let's raise it. */
4532 if (!result)
4533 result = PyErr_SetFromWindowsErr(GetLastError());
4534
4535 CloseHandle(snapshot);
4536
4537 return result;
4538}
4539#endif /*MS_WINDOWS*/
4540
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004541PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004542"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004543Return the parent's process id. If the parent process has already exited,\n\
4544Windows machines will still return its id; others systems will return the id\n\
4545of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004546
Barry Warsaw53699e91996-12-10 23:23:01 +00004547static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004548posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004549{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004550#ifdef MS_WINDOWS
4551 return win32_getppid();
4552#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004553 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00004554#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004555}
4556#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004557
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004558
Fred Drake12c6e2d1999-12-14 21:25:03 +00004559#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004560PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004561"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004562Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004563
4564static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004565posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004566{
Victor Stinner8c62be82010-05-06 00:08:46 +00004567 PyObject *result = NULL;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004568#ifdef MS_WINDOWS
4569 wchar_t user_name[UNLEN + 1];
4570 DWORD num_chars = sizeof(user_name)/sizeof(user_name[0]);
4571
4572 if (GetUserNameW(user_name, &num_chars)) {
4573 /* num_chars is the number of unicode chars plus null terminator */
4574 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
4575 }
4576 else
4577 result = PyErr_SetFromWindowsErr(GetLastError());
4578#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004579 char *name;
4580 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004581
Victor Stinner8c62be82010-05-06 00:08:46 +00004582 errno = 0;
4583 name = getlogin();
4584 if (name == NULL) {
4585 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00004586 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004587 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004588 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00004589 }
4590 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004591 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00004592 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004593#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00004594 return result;
4595}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004596#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00004597
Guido van Rossumad0ee831995-03-01 10:34:45 +00004598#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004599PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004600"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004601Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004602
Barry Warsaw53699e91996-12-10 23:23:01 +00004603static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004604posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004605{
Victor Stinner8c62be82010-05-06 00:08:46 +00004606 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004607}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004608#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004609
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004610
Guido van Rossumad0ee831995-03-01 10:34:45 +00004611#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004612PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004613"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004614Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004615
Barry Warsaw53699e91996-12-10 23:23:01 +00004616static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004617posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004618{
Victor Stinner8c62be82010-05-06 00:08:46 +00004619 pid_t pid;
4620 int sig;
4621 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
4622 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004623#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004624 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4625 APIRET rc;
4626 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004627 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004628
4629 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4630 APIRET rc;
4631 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004632 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004633
4634 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004635 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004636#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004637 if (kill(pid, sig) == -1)
4638 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004639#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004640 Py_INCREF(Py_None);
4641 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004642}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004643#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004644
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004645#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004646PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004647"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004648Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004649
4650static PyObject *
4651posix_killpg(PyObject *self, PyObject *args)
4652{
Victor Stinner8c62be82010-05-06 00:08:46 +00004653 int sig;
4654 pid_t pgid;
4655 /* XXX some man pages make the `pgid` parameter an int, others
4656 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4657 take the same type. Moreover, pid_t is always at least as wide as
4658 int (else compilation of this module fails), which is safe. */
4659 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
4660 return NULL;
4661 if (killpg(pgid, sig) == -1)
4662 return posix_error();
4663 Py_INCREF(Py_None);
4664 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004665}
4666#endif
4667
Brian Curtineb24d742010-04-12 17:16:38 +00004668#ifdef MS_WINDOWS
4669PyDoc_STRVAR(win32_kill__doc__,
4670"kill(pid, sig)\n\n\
4671Kill a process with a signal.");
4672
4673static PyObject *
4674win32_kill(PyObject *self, PyObject *args)
4675{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00004676 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004677 DWORD pid, sig, err;
4678 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00004679
Victor Stinner8c62be82010-05-06 00:08:46 +00004680 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4681 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00004682
Victor Stinner8c62be82010-05-06 00:08:46 +00004683 /* Console processes which share a common console can be sent CTRL+C or
4684 CTRL+BREAK events, provided they handle said events. */
4685 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4686 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4687 err = GetLastError();
4688 PyErr_SetFromWindowsErr(err);
4689 }
4690 else
4691 Py_RETURN_NONE;
4692 }
Brian Curtineb24d742010-04-12 17:16:38 +00004693
Victor Stinner8c62be82010-05-06 00:08:46 +00004694 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4695 attempt to open and terminate the process. */
4696 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4697 if (handle == NULL) {
4698 err = GetLastError();
4699 return PyErr_SetFromWindowsErr(err);
4700 }
Brian Curtineb24d742010-04-12 17:16:38 +00004701
Victor Stinner8c62be82010-05-06 00:08:46 +00004702 if (TerminateProcess(handle, sig) == 0) {
4703 err = GetLastError();
4704 result = PyErr_SetFromWindowsErr(err);
4705 } else {
4706 Py_INCREF(Py_None);
4707 result = Py_None;
4708 }
Brian Curtineb24d742010-04-12 17:16:38 +00004709
Victor Stinner8c62be82010-05-06 00:08:46 +00004710 CloseHandle(handle);
4711 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00004712}
4713#endif /* MS_WINDOWS */
4714
Guido van Rossumc0125471996-06-28 18:55:32 +00004715#ifdef HAVE_PLOCK
4716
4717#ifdef HAVE_SYS_LOCK_H
4718#include <sys/lock.h>
4719#endif
4720
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004721PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004722"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004723Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004724
Barry Warsaw53699e91996-12-10 23:23:01 +00004725static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004726posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004727{
Victor Stinner8c62be82010-05-06 00:08:46 +00004728 int op;
4729 if (!PyArg_ParseTuple(args, "i:plock", &op))
4730 return NULL;
4731 if (plock(op) == -1)
4732 return posix_error();
4733 Py_INCREF(Py_None);
4734 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004735}
4736#endif
4737
Guido van Rossumb6775db1994-08-01 11:34:53 +00004738#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004739PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004740"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004741Set the current process's user id.");
4742
Barry Warsaw53699e91996-12-10 23:23:01 +00004743static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004744posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004745{
Victor Stinner8c62be82010-05-06 00:08:46 +00004746 long uid_arg;
4747 uid_t uid;
4748 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
4749 return NULL;
4750 uid = uid_arg;
4751 if (uid != uid_arg) {
4752 PyErr_SetString(PyExc_OverflowError, "user id too big");
4753 return NULL;
4754 }
4755 if (setuid(uid) < 0)
4756 return posix_error();
4757 Py_INCREF(Py_None);
4758 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004759}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004760#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004761
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004762
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004763#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004764PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004765"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004766Set the current process's effective user id.");
4767
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004768static PyObject *
4769posix_seteuid (PyObject *self, PyObject *args)
4770{
Victor Stinner8c62be82010-05-06 00:08:46 +00004771 long euid_arg;
4772 uid_t euid;
4773 if (!PyArg_ParseTuple(args, "l", &euid_arg))
4774 return NULL;
4775 euid = euid_arg;
4776 if (euid != euid_arg) {
4777 PyErr_SetString(PyExc_OverflowError, "user id too big");
4778 return NULL;
4779 }
4780 if (seteuid(euid) < 0) {
4781 return posix_error();
4782 } else {
4783 Py_INCREF(Py_None);
4784 return Py_None;
4785 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004786}
4787#endif /* HAVE_SETEUID */
4788
4789#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004790PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004791"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004792Set the current process's effective group id.");
4793
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004794static PyObject *
4795posix_setegid (PyObject *self, PyObject *args)
4796{
Victor Stinner8c62be82010-05-06 00:08:46 +00004797 long egid_arg;
4798 gid_t egid;
4799 if (!PyArg_ParseTuple(args, "l", &egid_arg))
4800 return NULL;
4801 egid = egid_arg;
4802 if (egid != egid_arg) {
4803 PyErr_SetString(PyExc_OverflowError, "group id too big");
4804 return NULL;
4805 }
4806 if (setegid(egid) < 0) {
4807 return posix_error();
4808 } else {
4809 Py_INCREF(Py_None);
4810 return Py_None;
4811 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004812}
4813#endif /* HAVE_SETEGID */
4814
4815#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004816PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004817"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004818Set the current process's real and effective user ids.");
4819
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004820static PyObject *
4821posix_setreuid (PyObject *self, PyObject *args)
4822{
Victor Stinner8c62be82010-05-06 00:08:46 +00004823 long ruid_arg, euid_arg;
4824 uid_t ruid, euid;
4825 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
4826 return NULL;
4827 if (ruid_arg == -1)
4828 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
4829 else
4830 ruid = ruid_arg; /* otherwise, assign from our long */
4831 if (euid_arg == -1)
4832 euid = (uid_t)-1;
4833 else
4834 euid = euid_arg;
4835 if ((euid_arg != -1 && euid != euid_arg) ||
4836 (ruid_arg != -1 && ruid != ruid_arg)) {
4837 PyErr_SetString(PyExc_OverflowError, "user id too big");
4838 return NULL;
4839 }
4840 if (setreuid(ruid, euid) < 0) {
4841 return posix_error();
4842 } else {
4843 Py_INCREF(Py_None);
4844 return Py_None;
4845 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004846}
4847#endif /* HAVE_SETREUID */
4848
4849#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004850PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004851"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004852Set the current process's real and effective group ids.");
4853
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004854static PyObject *
4855posix_setregid (PyObject *self, PyObject *args)
4856{
Victor Stinner8c62be82010-05-06 00:08:46 +00004857 long rgid_arg, egid_arg;
4858 gid_t rgid, egid;
4859 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
4860 return NULL;
4861 if (rgid_arg == -1)
4862 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
4863 else
4864 rgid = rgid_arg; /* otherwise, assign from our long */
4865 if (egid_arg == -1)
4866 egid = (gid_t)-1;
4867 else
4868 egid = egid_arg;
4869 if ((egid_arg != -1 && egid != egid_arg) ||
4870 (rgid_arg != -1 && rgid != rgid_arg)) {
4871 PyErr_SetString(PyExc_OverflowError, "group id too big");
4872 return NULL;
4873 }
4874 if (setregid(rgid, egid) < 0) {
4875 return posix_error();
4876 } else {
4877 Py_INCREF(Py_None);
4878 return Py_None;
4879 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004880}
4881#endif /* HAVE_SETREGID */
4882
Guido van Rossumb6775db1994-08-01 11:34:53 +00004883#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004884PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004885"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004886Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004887
Barry Warsaw53699e91996-12-10 23:23:01 +00004888static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004889posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004890{
Victor Stinner8c62be82010-05-06 00:08:46 +00004891 long gid_arg;
4892 gid_t gid;
4893 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
4894 return NULL;
4895 gid = gid_arg;
4896 if (gid != gid_arg) {
4897 PyErr_SetString(PyExc_OverflowError, "group id too big");
4898 return NULL;
4899 }
4900 if (setgid(gid) < 0)
4901 return posix_error();
4902 Py_INCREF(Py_None);
4903 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004904}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004905#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004906
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004907#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004908PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004909"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004910Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004911
4912static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004913posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004914{
Victor Stinner8c62be82010-05-06 00:08:46 +00004915 int i, len;
4916 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004917
Victor Stinner8c62be82010-05-06 00:08:46 +00004918 if (!PySequence_Check(groups)) {
4919 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4920 return NULL;
4921 }
4922 len = PySequence_Size(groups);
4923 if (len > MAX_GROUPS) {
4924 PyErr_SetString(PyExc_ValueError, "too many groups");
4925 return NULL;
4926 }
4927 for(i = 0; i < len; i++) {
4928 PyObject *elem;
4929 elem = PySequence_GetItem(groups, i);
4930 if (!elem)
4931 return NULL;
4932 if (!PyLong_Check(elem)) {
4933 PyErr_SetString(PyExc_TypeError,
4934 "groups must be integers");
4935 Py_DECREF(elem);
4936 return NULL;
4937 } else {
4938 unsigned long x = PyLong_AsUnsignedLong(elem);
4939 if (PyErr_Occurred()) {
4940 PyErr_SetString(PyExc_TypeError,
4941 "group id too big");
4942 Py_DECREF(elem);
4943 return NULL;
4944 }
4945 grouplist[i] = x;
4946 /* read back the value to see if it fitted in gid_t */
4947 if (grouplist[i] != x) {
4948 PyErr_SetString(PyExc_TypeError,
4949 "group id too big");
4950 Py_DECREF(elem);
4951 return NULL;
4952 }
4953 }
4954 Py_DECREF(elem);
4955 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004956
Victor Stinner8c62be82010-05-06 00:08:46 +00004957 if (setgroups(len, grouplist) < 0)
4958 return posix_error();
4959 Py_INCREF(Py_None);
4960 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004961}
4962#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004963
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004964#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4965static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004966wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004967{
Victor Stinner8c62be82010-05-06 00:08:46 +00004968 PyObject *result;
4969 static PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004970
Victor Stinner8c62be82010-05-06 00:08:46 +00004971 if (pid == -1)
4972 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004973
Victor Stinner8c62be82010-05-06 00:08:46 +00004974 if (struct_rusage == NULL) {
4975 PyObject *m = PyImport_ImportModuleNoBlock("resource");
4976 if (m == NULL)
4977 return NULL;
4978 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4979 Py_DECREF(m);
4980 if (struct_rusage == NULL)
4981 return NULL;
4982 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004983
Victor Stinner8c62be82010-05-06 00:08:46 +00004984 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4985 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4986 if (!result)
4987 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004988
4989#ifndef doubletime
4990#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4991#endif
4992
Victor Stinner8c62be82010-05-06 00:08:46 +00004993 PyStructSequence_SET_ITEM(result, 0,
4994 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4995 PyStructSequence_SET_ITEM(result, 1,
4996 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004997#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00004998 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
4999 SET_INT(result, 2, ru->ru_maxrss);
5000 SET_INT(result, 3, ru->ru_ixrss);
5001 SET_INT(result, 4, ru->ru_idrss);
5002 SET_INT(result, 5, ru->ru_isrss);
5003 SET_INT(result, 6, ru->ru_minflt);
5004 SET_INT(result, 7, ru->ru_majflt);
5005 SET_INT(result, 8, ru->ru_nswap);
5006 SET_INT(result, 9, ru->ru_inblock);
5007 SET_INT(result, 10, ru->ru_oublock);
5008 SET_INT(result, 11, ru->ru_msgsnd);
5009 SET_INT(result, 12, ru->ru_msgrcv);
5010 SET_INT(result, 13, ru->ru_nsignals);
5011 SET_INT(result, 14, ru->ru_nvcsw);
5012 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005013#undef SET_INT
5014
Victor Stinner8c62be82010-05-06 00:08:46 +00005015 if (PyErr_Occurred()) {
5016 Py_DECREF(result);
5017 return NULL;
5018 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005019
Victor Stinner8c62be82010-05-06 00:08:46 +00005020 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005021}
5022#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
5023
5024#ifdef HAVE_WAIT3
5025PyDoc_STRVAR(posix_wait3__doc__,
5026"wait3(options) -> (pid, status, rusage)\n\n\
5027Wait for completion of a child process.");
5028
5029static PyObject *
5030posix_wait3(PyObject *self, PyObject *args)
5031{
Victor Stinner8c62be82010-05-06 00:08:46 +00005032 pid_t pid;
5033 int options;
5034 struct rusage ru;
5035 WAIT_TYPE status;
5036 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005037
Victor Stinner8c62be82010-05-06 00:08:46 +00005038 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5039 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005040
Victor Stinner8c62be82010-05-06 00:08:46 +00005041 Py_BEGIN_ALLOW_THREADS
5042 pid = wait3(&status, options, &ru);
5043 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005044
Victor Stinner8c62be82010-05-06 00:08:46 +00005045 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005046}
5047#endif /* HAVE_WAIT3 */
5048
5049#ifdef HAVE_WAIT4
5050PyDoc_STRVAR(posix_wait4__doc__,
5051"wait4(pid, options) -> (pid, status, rusage)\n\n\
5052Wait for completion of a given child process.");
5053
5054static PyObject *
5055posix_wait4(PyObject *self, PyObject *args)
5056{
Victor Stinner8c62be82010-05-06 00:08:46 +00005057 pid_t pid;
5058 int options;
5059 struct rusage ru;
5060 WAIT_TYPE status;
5061 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005062
Victor Stinner8c62be82010-05-06 00:08:46 +00005063 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
5064 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005065
Victor Stinner8c62be82010-05-06 00:08:46 +00005066 Py_BEGIN_ALLOW_THREADS
5067 pid = wait4(pid, &status, options, &ru);
5068 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005069
Victor Stinner8c62be82010-05-06 00:08:46 +00005070 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005071}
5072#endif /* HAVE_WAIT4 */
5073
Guido van Rossumb6775db1994-08-01 11:34:53 +00005074#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005075PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005076"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005077Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005078
Barry Warsaw53699e91996-12-10 23:23:01 +00005079static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005080posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005081{
Victor Stinner8c62be82010-05-06 00:08:46 +00005082 pid_t pid;
5083 int options;
5084 WAIT_TYPE status;
5085 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005086
Victor Stinner8c62be82010-05-06 00:08:46 +00005087 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
5088 return NULL;
5089 Py_BEGIN_ALLOW_THREADS
5090 pid = waitpid(pid, &status, options);
5091 Py_END_ALLOW_THREADS
5092 if (pid == -1)
5093 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005094
Victor Stinner8c62be82010-05-06 00:08:46 +00005095 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005096}
5097
Tim Petersab034fa2002-02-01 11:27:43 +00005098#elif defined(HAVE_CWAIT)
5099
5100/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005101PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005102"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005103"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005104
5105static PyObject *
5106posix_waitpid(PyObject *self, PyObject *args)
5107{
Victor Stinner8c62be82010-05-06 00:08:46 +00005108 Py_intptr_t pid;
5109 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005110
Victor Stinner8c62be82010-05-06 00:08:46 +00005111 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
5112 return NULL;
5113 Py_BEGIN_ALLOW_THREADS
5114 pid = _cwait(&status, pid, options);
5115 Py_END_ALLOW_THREADS
5116 if (pid == -1)
5117 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005118
Victor Stinner8c62be82010-05-06 00:08:46 +00005119 /* shift the status left a byte so this is more like the POSIX waitpid */
5120 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005121}
5122#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005123
Guido van Rossumad0ee831995-03-01 10:34:45 +00005124#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005125PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005126"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005127Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005128
Barry Warsaw53699e91996-12-10 23:23:01 +00005129static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005130posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005131{
Victor Stinner8c62be82010-05-06 00:08:46 +00005132 pid_t pid;
5133 WAIT_TYPE status;
5134 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005135
Victor Stinner8c62be82010-05-06 00:08:46 +00005136 Py_BEGIN_ALLOW_THREADS
5137 pid = wait(&status);
5138 Py_END_ALLOW_THREADS
5139 if (pid == -1)
5140 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005141
Victor Stinner8c62be82010-05-06 00:08:46 +00005142 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005143}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005144#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005145
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005146
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005147PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005148"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005149Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005150
Barry Warsaw53699e91996-12-10 23:23:01 +00005151static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005152posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005153{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005154#ifdef HAVE_LSTAT
Victor Stinner8c62be82010-05-06 00:08:46 +00005155 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005156#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005157#ifdef MS_WINDOWS
Brian Curtind25aef52011-06-13 15:16:04 -05005158 return posix_do_stat(self, args, "O&:lstat", win32_lstat, "U:lstat",
Brian Curtind40e6f72010-07-08 21:39:08 +00005159 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005160#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005161 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005162#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005163#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005164}
5165
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005166
Guido van Rossumb6775db1994-08-01 11:34:53 +00005167#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005168PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005169"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005170Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005171
Barry Warsaw53699e91996-12-10 23:23:01 +00005172static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005173posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005174{
Victor Stinner8c62be82010-05-06 00:08:46 +00005175 PyObject* v;
5176 char buf[MAXPATHLEN];
5177 PyObject *opath;
5178 char *path;
5179 int n;
5180 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00005181
Victor Stinner8c62be82010-05-06 00:08:46 +00005182 if (!PyArg_ParseTuple(args, "O&:readlink",
5183 PyUnicode_FSConverter, &opath))
5184 return NULL;
5185 path = PyBytes_AsString(opath);
5186 v = PySequence_GetItem(args, 0);
5187 if (v == NULL) {
5188 Py_DECREF(opath);
5189 return NULL;
5190 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00005191
Victor Stinner8c62be82010-05-06 00:08:46 +00005192 if (PyUnicode_Check(v)) {
5193 arg_is_unicode = 1;
5194 }
5195 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005196
Victor Stinner8c62be82010-05-06 00:08:46 +00005197 Py_BEGIN_ALLOW_THREADS
5198 n = readlink(path, buf, (int) sizeof buf);
5199 Py_END_ALLOW_THREADS
5200 if (n < 0)
5201 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005202
Victor Stinner8c62be82010-05-06 00:08:46 +00005203 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00005204 if (arg_is_unicode)
5205 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
5206 else
5207 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005208}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005209#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005210
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005211
Brian Curtin52173d42010-12-02 18:29:18 +00005212#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005213PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005214"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005215Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005216
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005217static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005218posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005219{
Victor Stinner8c62be82010-05-06 00:08:46 +00005220 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005221}
5222#endif /* HAVE_SYMLINK */
5223
Brian Curtind40e6f72010-07-08 21:39:08 +00005224#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
5225
5226PyDoc_STRVAR(win_readlink__doc__,
5227"readlink(path) -> path\n\n\
5228Return a string representing the path to which the symbolic link points.");
5229
Brian Curtind40e6f72010-07-08 21:39:08 +00005230/* Windows readlink implementation */
5231static PyObject *
5232win_readlink(PyObject *self, PyObject *args)
5233{
5234 wchar_t *path;
5235 DWORD n_bytes_returned;
5236 DWORD io_result;
5237 PyObject *result;
5238 HANDLE reparse_point_handle;
5239
5240 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
5241 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
5242 wchar_t *print_name;
5243
5244 if (!PyArg_ParseTuple(args,
5245 "u:readlink",
5246 &path))
5247 return NULL;
5248
5249 /* First get a handle to the reparse point */
5250 Py_BEGIN_ALLOW_THREADS
5251 reparse_point_handle = CreateFileW(
5252 path,
5253 0,
5254 0,
5255 0,
5256 OPEN_EXISTING,
5257 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
5258 0);
5259 Py_END_ALLOW_THREADS
5260
5261 if (reparse_point_handle==INVALID_HANDLE_VALUE)
5262 {
5263 return win32_error_unicode("readlink", path);
5264 }
5265
5266 Py_BEGIN_ALLOW_THREADS
5267 /* New call DeviceIoControl to read the reparse point */
5268 io_result = DeviceIoControl(
5269 reparse_point_handle,
5270 FSCTL_GET_REPARSE_POINT,
5271 0, 0, /* in buffer */
5272 target_buffer, sizeof(target_buffer),
5273 &n_bytes_returned,
5274 0 /* we're not using OVERLAPPED_IO */
5275 );
5276 CloseHandle(reparse_point_handle);
5277 Py_END_ALLOW_THREADS
5278
5279 if (io_result==0)
5280 {
5281 return win32_error_unicode("readlink", path);
5282 }
5283
5284 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
5285 {
5286 PyErr_SetString(PyExc_ValueError,
5287 "not a symbolic link");
5288 return NULL;
5289 }
Brian Curtin74e45612010-07-09 15:58:59 +00005290 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
5291 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
5292
5293 result = PyUnicode_FromWideChar(print_name,
5294 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00005295 return result;
5296}
5297
5298#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
5299
Brian Curtin52173d42010-12-02 18:29:18 +00005300#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtind40e6f72010-07-08 21:39:08 +00005301
5302/* Grab CreateSymbolicLinkW dynamically from kernel32 */
5303static int has_CreateSymbolicLinkW = 0;
5304static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
5305static int
5306check_CreateSymbolicLinkW()
5307{
5308 HINSTANCE hKernel32;
5309 /* only recheck */
5310 if (has_CreateSymbolicLinkW)
5311 return has_CreateSymbolicLinkW;
5312 hKernel32 = GetModuleHandle("KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00005313 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
5314 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00005315 if (Py_CreateSymbolicLinkW)
5316 has_CreateSymbolicLinkW = 1;
5317 return has_CreateSymbolicLinkW;
5318}
5319
5320PyDoc_STRVAR(win_symlink__doc__,
5321"symlink(src, dst, target_is_directory=False)\n\n\
5322Create a symbolic link pointing to src named dst.\n\
5323target_is_directory is required if the target is to be interpreted as\n\
5324a directory.\n\
5325This function requires Windows 6.0 or greater, and raises a\n\
5326NotImplementedError otherwise.");
5327
5328static PyObject *
5329win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
5330{
5331 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
5332 PyObject *src, *dest;
5333 int target_is_directory = 0;
5334 DWORD res;
5335 WIN32_FILE_ATTRIBUTE_DATA src_info;
5336
5337 if (!check_CreateSymbolicLinkW())
5338 {
5339 /* raise NotImplementedError */
5340 return PyErr_Format(PyExc_NotImplementedError,
5341 "CreateSymbolicLinkW not found");
5342 }
5343 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:symlink",
5344 kwlist, &src, &dest, &target_is_directory))
5345 return NULL;
Brian Curtin3b4499c2010-12-28 14:31:47 +00005346
5347 if (win32_can_symlink == 0)
5348 return PyErr_Format(PyExc_OSError, "symbolic link privilege not held");
5349
Brian Curtind40e6f72010-07-08 21:39:08 +00005350 if (!convert_to_unicode(&src)) { return NULL; }
5351 if (!convert_to_unicode(&dest)) {
5352 Py_DECREF(src);
5353 return NULL;
5354 }
5355
5356 /* if src is a directory, ensure target_is_directory==1 */
5357 if(
5358 GetFileAttributesExW(
5359 PyUnicode_AsUnicode(src), GetFileExInfoStandard, &src_info
5360 ))
5361 {
5362 target_is_directory = target_is_directory ||
5363 (src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
5364 }
5365
5366 Py_BEGIN_ALLOW_THREADS
5367 res = Py_CreateSymbolicLinkW(
5368 PyUnicode_AsUnicode(dest),
5369 PyUnicode_AsUnicode(src),
5370 target_is_directory);
5371 Py_END_ALLOW_THREADS
5372 Py_DECREF(src);
5373 Py_DECREF(dest);
5374 if (!res)
5375 {
5376 return win32_error_unicode("symlink", PyUnicode_AsUnicode(src));
5377 }
5378
5379 Py_INCREF(Py_None);
5380 return Py_None;
5381}
Brian Curtin52173d42010-12-02 18:29:18 +00005382#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005383
5384#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00005385#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5386static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005387system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005388{
5389 ULONG value = 0;
5390
5391 Py_BEGIN_ALLOW_THREADS
5392 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5393 Py_END_ALLOW_THREADS
5394
5395 return value;
5396}
5397
5398static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005399posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005400{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005401 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00005402 return Py_BuildValue("ddddd",
5403 (double)0 /* t.tms_utime / HZ */,
5404 (double)0 /* t.tms_stime / HZ */,
5405 (double)0 /* t.tms_cutime / HZ */,
5406 (double)0 /* t.tms_cstime / HZ */,
5407 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005408}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005409#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00005410#define NEED_TICKS_PER_SECOND
5411static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00005412static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005413posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005414{
Victor Stinner8c62be82010-05-06 00:08:46 +00005415 struct tms t;
5416 clock_t c;
5417 errno = 0;
5418 c = times(&t);
5419 if (c == (clock_t) -1)
5420 return posix_error();
5421 return Py_BuildValue("ddddd",
5422 (double)t.tms_utime / ticks_per_second,
5423 (double)t.tms_stime / ticks_per_second,
5424 (double)t.tms_cutime / ticks_per_second,
5425 (double)t.tms_cstime / ticks_per_second,
5426 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005427}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005428#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005429#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005430
5431
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005432#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005433#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005434static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005435posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005436{
Victor Stinner8c62be82010-05-06 00:08:46 +00005437 FILETIME create, exit, kernel, user;
5438 HANDLE hProc;
5439 hProc = GetCurrentProcess();
5440 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5441 /* The fields of a FILETIME structure are the hi and lo part
5442 of a 64-bit value expressed in 100 nanosecond units.
5443 1e7 is one second in such units; 1e-7 the inverse.
5444 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5445 */
5446 return Py_BuildValue(
5447 "ddddd",
5448 (double)(user.dwHighDateTime*429.4967296 +
5449 user.dwLowDateTime*1e-7),
5450 (double)(kernel.dwHighDateTime*429.4967296 +
5451 kernel.dwLowDateTime*1e-7),
5452 (double)0,
5453 (double)0,
5454 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005455}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005456#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005457
5458#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005459PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005460"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005461Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005462#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005463
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005464
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005465#ifdef HAVE_GETSID
5466PyDoc_STRVAR(posix_getsid__doc__,
5467"getsid(pid) -> sid\n\n\
5468Call the system call getsid().");
5469
5470static PyObject *
5471posix_getsid(PyObject *self, PyObject *args)
5472{
Victor Stinner8c62be82010-05-06 00:08:46 +00005473 pid_t pid;
5474 int sid;
5475 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
5476 return NULL;
5477 sid = getsid(pid);
5478 if (sid < 0)
5479 return posix_error();
5480 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005481}
5482#endif /* HAVE_GETSID */
5483
5484
Guido van Rossumb6775db1994-08-01 11:34:53 +00005485#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005486PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005487"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005488Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005489
Barry Warsaw53699e91996-12-10 23:23:01 +00005490static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005491posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005492{
Victor Stinner8c62be82010-05-06 00:08:46 +00005493 if (setsid() < 0)
5494 return posix_error();
5495 Py_INCREF(Py_None);
5496 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005497}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005498#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005499
Guido van Rossumb6775db1994-08-01 11:34:53 +00005500#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005501PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005502"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005503Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005504
Barry Warsaw53699e91996-12-10 23:23:01 +00005505static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005506posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005507{
Victor Stinner8c62be82010-05-06 00:08:46 +00005508 pid_t pid;
5509 int pgrp;
5510 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
5511 return NULL;
5512 if (setpgid(pid, pgrp) < 0)
5513 return posix_error();
5514 Py_INCREF(Py_None);
5515 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005516}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005517#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005518
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005519
Guido van Rossumb6775db1994-08-01 11:34:53 +00005520#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005521PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005522"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005523Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005524
Barry Warsaw53699e91996-12-10 23:23:01 +00005525static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005526posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005527{
Victor Stinner8c62be82010-05-06 00:08:46 +00005528 int fd;
5529 pid_t pgid;
5530 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
5531 return NULL;
5532 pgid = tcgetpgrp(fd);
5533 if (pgid < 0)
5534 return posix_error();
5535 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005536}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005537#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005538
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005539
Guido van Rossumb6775db1994-08-01 11:34:53 +00005540#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005541PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005542"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005543Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005544
Barry Warsaw53699e91996-12-10 23:23:01 +00005545static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005546posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005547{
Victor Stinner8c62be82010-05-06 00:08:46 +00005548 int fd;
5549 pid_t pgid;
5550 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
5551 return NULL;
5552 if (tcsetpgrp(fd, pgid) < 0)
5553 return posix_error();
5554 Py_INCREF(Py_None);
5555 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005556}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005557#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005558
Guido van Rossum687dd131993-05-17 08:34:16 +00005559/* Functions acting on file descriptors */
5560
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005561PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005562"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005563Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005564
Barry Warsaw53699e91996-12-10 23:23:01 +00005565static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005566posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005567{
Victor Stinner8c62be82010-05-06 00:08:46 +00005568 PyObject *ofile;
5569 char *file;
5570 int flag;
5571 int mode = 0777;
5572 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005573
5574#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005575 PyUnicodeObject *po;
5576 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5577 Py_BEGIN_ALLOW_THREADS
5578 /* PyUnicode_AS_UNICODE OK without thread
5579 lock as it is a simple dereference. */
5580 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5581 Py_END_ALLOW_THREADS
5582 if (fd < 0)
5583 return posix_error();
5584 return PyLong_FromLong((long)fd);
5585 }
5586 /* Drop the argument parsing error as narrow strings
5587 are also valid. */
5588 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005589#endif
5590
Victor Stinner8c62be82010-05-06 00:08:46 +00005591 if (!PyArg_ParseTuple(args, "O&i|i",
5592 PyUnicode_FSConverter, &ofile,
5593 &flag, &mode))
5594 return NULL;
5595 file = PyBytes_AsString(ofile);
5596 Py_BEGIN_ALLOW_THREADS
5597 fd = open(file, flag, mode);
5598 Py_END_ALLOW_THREADS
5599 if (fd < 0)
5600 return posix_error_with_allocated_filename(ofile);
5601 Py_DECREF(ofile);
5602 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005603}
5604
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005605
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005606PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005607"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005608Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005609
Barry Warsaw53699e91996-12-10 23:23:01 +00005610static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005611posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005612{
Victor Stinner8c62be82010-05-06 00:08:46 +00005613 int fd, res;
5614 if (!PyArg_ParseTuple(args, "i:close", &fd))
5615 return NULL;
5616 if (!_PyVerify_fd(fd))
5617 return posix_error();
5618 Py_BEGIN_ALLOW_THREADS
5619 res = close(fd);
5620 Py_END_ALLOW_THREADS
5621 if (res < 0)
5622 return posix_error();
5623 Py_INCREF(Py_None);
5624 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005625}
5626
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005627
Victor Stinner8c62be82010-05-06 00:08:46 +00005628PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00005629"closerange(fd_low, fd_high)\n\n\
5630Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
5631
5632static PyObject *
5633posix_closerange(PyObject *self, PyObject *args)
5634{
Victor Stinner8c62be82010-05-06 00:08:46 +00005635 int fd_from, fd_to, i;
5636 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
5637 return NULL;
5638 Py_BEGIN_ALLOW_THREADS
5639 for (i = fd_from; i < fd_to; i++)
5640 if (_PyVerify_fd(i))
5641 close(i);
5642 Py_END_ALLOW_THREADS
5643 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00005644}
5645
5646
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005647PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005648"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005649Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005650
Barry Warsaw53699e91996-12-10 23:23:01 +00005651static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005652posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005653{
Victor Stinner8c62be82010-05-06 00:08:46 +00005654 int fd;
5655 if (!PyArg_ParseTuple(args, "i:dup", &fd))
5656 return NULL;
5657 if (!_PyVerify_fd(fd))
5658 return posix_error();
5659 Py_BEGIN_ALLOW_THREADS
5660 fd = dup(fd);
5661 Py_END_ALLOW_THREADS
5662 if (fd < 0)
5663 return posix_error();
5664 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005665}
5666
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005667
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005668PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005669"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005670Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005671
Barry Warsaw53699e91996-12-10 23:23:01 +00005672static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005673posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005674{
Victor Stinner8c62be82010-05-06 00:08:46 +00005675 int fd, fd2, res;
5676 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5677 return NULL;
5678 if (!_PyVerify_fd_dup2(fd, fd2))
5679 return posix_error();
5680 Py_BEGIN_ALLOW_THREADS
5681 res = dup2(fd, fd2);
5682 Py_END_ALLOW_THREADS
5683 if (res < 0)
5684 return posix_error();
5685 Py_INCREF(Py_None);
5686 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005687}
5688
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005689
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005690PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005691"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005692Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005693
Barry Warsaw53699e91996-12-10 23:23:01 +00005694static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005695posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005696{
Victor Stinner8c62be82010-05-06 00:08:46 +00005697 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005698#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005699 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005700#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005701 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005702#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005703 PyObject *posobj;
5704 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5705 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005706#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00005707 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5708 switch (how) {
5709 case 0: how = SEEK_SET; break;
5710 case 1: how = SEEK_CUR; break;
5711 case 2: how = SEEK_END; break;
5712 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005713#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005714
5715#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005716 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005717#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005718 pos = PyLong_Check(posobj) ?
5719 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005720#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005721 if (PyErr_Occurred())
5722 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005723
Victor Stinner8c62be82010-05-06 00:08:46 +00005724 if (!_PyVerify_fd(fd))
5725 return posix_error();
5726 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005727#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005728 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005729#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005730 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005731#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005732 Py_END_ALLOW_THREADS
5733 if (res < 0)
5734 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005735
5736#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005737 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005738#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005739 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005740#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005741}
5742
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005743
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005744PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005745"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005746Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005747
Barry Warsaw53699e91996-12-10 23:23:01 +00005748static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005749posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005750{
Victor Stinner8c62be82010-05-06 00:08:46 +00005751 int fd, size;
5752 Py_ssize_t n;
5753 PyObject *buffer;
5754 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5755 return NULL;
5756 if (size < 0) {
5757 errno = EINVAL;
5758 return posix_error();
5759 }
5760 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
5761 if (buffer == NULL)
5762 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00005763 if (!_PyVerify_fd(fd)) {
5764 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00005765 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00005766 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005767 Py_BEGIN_ALLOW_THREADS
5768 n = read(fd, PyBytes_AS_STRING(buffer), size);
5769 Py_END_ALLOW_THREADS
5770 if (n < 0) {
5771 Py_DECREF(buffer);
5772 return posix_error();
5773 }
5774 if (n != size)
5775 _PyBytes_Resize(&buffer, n);
5776 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00005777}
5778
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005779
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005780PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005781"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005782Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005783
Barry Warsaw53699e91996-12-10 23:23:01 +00005784static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005785posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005786{
Victor Stinner8c62be82010-05-06 00:08:46 +00005787 Py_buffer pbuf;
5788 int fd;
Victor Stinnere6edec22011-01-04 00:29:35 +00005789 Py_ssize_t size, len;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005790
Victor Stinner8c62be82010-05-06 00:08:46 +00005791 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
5792 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00005793 if (!_PyVerify_fd(fd)) {
5794 PyBuffer_Release(&pbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00005795 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00005796 }
Victor Stinnere6edec22011-01-04 00:29:35 +00005797 len = pbuf.len;
Victor Stinner8c62be82010-05-06 00:08:46 +00005798 Py_BEGIN_ALLOW_THREADS
Victor Stinnere6edec22011-01-04 00:29:35 +00005799#if defined(MS_WIN64) || defined(MS_WINDOWS)
5800 if (len > INT_MAX)
5801 len = INT_MAX;
5802 size = write(fd, pbuf.buf, (int)len);
5803#else
Victor Stinner72344792011-01-11 00:04:12 +00005804 size = write(fd, pbuf.buf, len);
Victor Stinnere6edec22011-01-04 00:29:35 +00005805#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005806 Py_END_ALLOW_THREADS
Stefan Krah99439262010-11-26 12:58:05 +00005807 PyBuffer_Release(&pbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00005808 if (size < 0)
5809 return posix_error();
5810 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005811}
5812
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005813
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005814PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005815"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005816Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005817
Barry Warsaw53699e91996-12-10 23:23:01 +00005818static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005819posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005820{
Victor Stinner8c62be82010-05-06 00:08:46 +00005821 int fd;
5822 STRUCT_STAT st;
5823 int res;
5824 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5825 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005826#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00005827 /* on OpenVMS we must ensure that all bytes are written to the file */
5828 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005829#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005830 if (!_PyVerify_fd(fd))
5831 return posix_error();
5832 Py_BEGIN_ALLOW_THREADS
5833 res = FSTAT(fd, &st);
5834 Py_END_ALLOW_THREADS
5835 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00005836#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005837 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00005838#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005839 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005840#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005841 }
Tim Peters5aa91602002-01-30 05:46:57 +00005842
Victor Stinner8c62be82010-05-06 00:08:46 +00005843 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005844}
5845
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005846PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005847"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005848Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005849connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005850
5851static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005852posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005853{
Victor Stinner8c62be82010-05-06 00:08:46 +00005854 int fd;
5855 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5856 return NULL;
5857 if (!_PyVerify_fd(fd))
5858 return PyBool_FromLong(0);
5859 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005860}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005861
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005862#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005863PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005864"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005865Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005866
Barry Warsaw53699e91996-12-10 23:23:01 +00005867static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005868posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005869{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005870#if defined(PYOS_OS2)
5871 HFILE read, write;
5872 APIRET rc;
5873
Victor Stinner8c62be82010-05-06 00:08:46 +00005874 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005875 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinner8c62be82010-05-06 00:08:46 +00005876 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005877 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005878 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005879
5880 return Py_BuildValue("(ii)", read, write);
5881#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005882#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005883 int fds[2];
5884 int res;
5885 Py_BEGIN_ALLOW_THREADS
5886 res = pipe(fds);
5887 Py_END_ALLOW_THREADS
5888 if (res != 0)
5889 return posix_error();
5890 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005891#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00005892 HANDLE read, write;
5893 int read_fd, write_fd;
5894 BOOL ok;
5895 Py_BEGIN_ALLOW_THREADS
5896 ok = CreatePipe(&read, &write, NULL, 0);
5897 Py_END_ALLOW_THREADS
5898 if (!ok)
5899 return win32_error("CreatePipe", NULL);
5900 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5901 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5902 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005903#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005904#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005905}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005906#endif /* HAVE_PIPE */
5907
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005908
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005909#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005910PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005911"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005912Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005913
Barry Warsaw53699e91996-12-10 23:23:01 +00005914static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005915posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005916{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005917 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005918 char *filename;
5919 int mode = 0666;
5920 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005921 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
5922 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00005923 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005924 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005925 Py_BEGIN_ALLOW_THREADS
5926 res = mkfifo(filename, mode);
5927 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005928 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005929 if (res < 0)
5930 return posix_error();
5931 Py_INCREF(Py_None);
5932 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005933}
5934#endif
5935
5936
Neal Norwitz11690112002-07-30 01:08:28 +00005937#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005938PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005939"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005940Create a filesystem node (file, device special file or named pipe)\n\
5941named filename. mode specifies both the permissions to use and the\n\
5942type of node to be created, being combined (bitwise OR) with one of\n\
5943S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005944device defines the newly created device special file (probably using\n\
5945os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005946
5947
5948static PyObject *
5949posix_mknod(PyObject *self, PyObject *args)
5950{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005951 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005952 char *filename;
5953 int mode = 0600;
5954 int device = 0;
5955 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005956 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
5957 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00005958 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005959 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005960 Py_BEGIN_ALLOW_THREADS
5961 res = mknod(filename, mode, device);
5962 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005963 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005964 if (res < 0)
5965 return posix_error();
5966 Py_INCREF(Py_None);
5967 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005968}
5969#endif
5970
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005971#ifdef HAVE_DEVICE_MACROS
5972PyDoc_STRVAR(posix_major__doc__,
5973"major(device) -> major number\n\
5974Extracts a device major number from a raw device number.");
5975
5976static PyObject *
5977posix_major(PyObject *self, PyObject *args)
5978{
Victor Stinner8c62be82010-05-06 00:08:46 +00005979 int device;
5980 if (!PyArg_ParseTuple(args, "i:major", &device))
5981 return NULL;
5982 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005983}
5984
5985PyDoc_STRVAR(posix_minor__doc__,
5986"minor(device) -> minor number\n\
5987Extracts a device minor number from a raw device number.");
5988
5989static PyObject *
5990posix_minor(PyObject *self, PyObject *args)
5991{
Victor Stinner8c62be82010-05-06 00:08:46 +00005992 int device;
5993 if (!PyArg_ParseTuple(args, "i:minor", &device))
5994 return NULL;
5995 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005996}
5997
5998PyDoc_STRVAR(posix_makedev__doc__,
5999"makedev(major, minor) -> device number\n\
6000Composes a raw device number from the major and minor device numbers.");
6001
6002static PyObject *
6003posix_makedev(PyObject *self, PyObject *args)
6004{
Victor Stinner8c62be82010-05-06 00:08:46 +00006005 int major, minor;
6006 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6007 return NULL;
6008 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006009}
6010#endif /* device macros */
6011
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006012
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006013#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006014PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006015"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006016Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006017
Barry Warsaw53699e91996-12-10 23:23:01 +00006018static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006019posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006020{
Victor Stinner8c62be82010-05-06 00:08:46 +00006021 int fd;
6022 off_t length;
6023 int res;
6024 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006025
Victor Stinner8c62be82010-05-06 00:08:46 +00006026 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
6027 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006028
6029#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006030 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006031#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006032 length = PyLong_Check(lenobj) ?
6033 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006034#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006035 if (PyErr_Occurred())
6036 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006037
Victor Stinner8c62be82010-05-06 00:08:46 +00006038 Py_BEGIN_ALLOW_THREADS
6039 res = ftruncate(fd, length);
6040 Py_END_ALLOW_THREADS
6041 if (res < 0)
6042 return posix_error();
6043 Py_INCREF(Py_None);
6044 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006045}
6046#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006047
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006048#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006049PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006050"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006051Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006052
Fred Drake762e2061999-08-26 17:23:54 +00006053/* Save putenv() parameters as values here, so we can collect them when they
6054 * get re-set with another call for the same key. */
6055static PyObject *posix_putenv_garbage;
6056
Tim Peters5aa91602002-01-30 05:46:57 +00006057static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006058posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006059{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006060#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006061 wchar_t *s1, *s2;
6062 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006063#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006064 PyObject *os1, *os2;
6065 char *s1, *s2;
6066 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006067#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006068 PyObject *newstr = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006069 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006070
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006071#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006072 if (!PyArg_ParseTuple(args,
6073 "uu:putenv",
6074 &s1, &s2))
6075 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00006076#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006077 if (!PyArg_ParseTuple(args,
6078 "O&O&:putenv",
6079 PyUnicode_FSConverter, &os1,
6080 PyUnicode_FSConverter, &os2))
6081 return NULL;
6082 s1 = PyBytes_AsString(os1);
6083 s2 = PyBytes_AsString(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00006084#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00006085
6086#if defined(PYOS_OS2)
6087 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6088 APIRET rc;
6089
Guido van Rossumd48f2521997-12-05 22:19:34 +00006090 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00006091 if (rc != NO_ERROR) {
6092 os2_error(rc);
6093 goto error;
6094 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006095
6096 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6097 APIRET rc;
6098
Guido van Rossumd48f2521997-12-05 22:19:34 +00006099 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00006100 if (rc != NO_ERROR) {
6101 os2_error(rc);
6102 goto error;
6103 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006104 } else {
6105#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006106 /* XXX This can leak memory -- not easy to fix :-( */
6107 /* len includes space for a trailing \0; the size arg to
6108 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006109#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006110 len = wcslen(s1) + wcslen(s2) + 2;
6111 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006112#else
Victor Stinner84ae1182010-05-06 22:05:07 +00006113 len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2;
Victor Stinner8c62be82010-05-06 00:08:46 +00006114 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006115#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006116 if (newstr == NULL) {
6117 PyErr_NoMemory();
6118 goto error;
6119 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006120#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006121 newenv = PyUnicode_AsUnicode(newstr);
6122 _snwprintf(newenv, len, L"%s=%s", s1, s2);
6123 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006124 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00006125 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006126 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006127#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006128 newenv = PyBytes_AS_STRING(newstr);
6129 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6130 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006131 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00006132 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006133 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006134#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006135
Victor Stinner8c62be82010-05-06 00:08:46 +00006136 /* Install the first arg and newstr in posix_putenv_garbage;
6137 * this will cause previous value to be collected. This has to
6138 * happen after the real putenv() call because the old value
6139 * was still accessible until then. */
6140 if (PyDict_SetItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00006141#ifdef MS_WINDOWS
6142 PyTuple_GET_ITEM(args, 0),
6143#else
6144 os1,
6145#endif
6146 newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006147 /* really not much we can do; just leak */
6148 PyErr_Clear();
6149 }
6150 else {
6151 Py_DECREF(newstr);
6152 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006153
6154#if defined(PYOS_OS2)
6155 }
6156#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006157
Martin v. Löwis011e8422009-05-05 04:43:17 +00006158#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006159 Py_DECREF(os1);
6160 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00006161#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006162 Py_RETURN_NONE;
6163
6164error:
6165#ifndef MS_WINDOWS
6166 Py_DECREF(os1);
6167 Py_DECREF(os2);
6168#endif
6169 Py_XDECREF(newstr);
6170 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006171}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006172#endif /* putenv */
6173
Guido van Rossumc524d952001-10-19 01:31:59 +00006174#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006175PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006176"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006177Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006178
6179static PyObject *
6180posix_unsetenv(PyObject *self, PyObject *args)
6181{
Victor Stinner84ae1182010-05-06 22:05:07 +00006182#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006183 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00006184
Victor Stinner8c62be82010-05-06 00:08:46 +00006185 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6186 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00006187#else
6188 PyObject *os1;
6189 char *s1;
6190
6191 if (!PyArg_ParseTuple(args, "O&:unsetenv",
6192 PyUnicode_FSConverter, &os1))
6193 return NULL;
6194 s1 = PyBytes_AsString(os1);
6195#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006196
Victor Stinner8c62be82010-05-06 00:08:46 +00006197 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00006198
Victor Stinner8c62be82010-05-06 00:08:46 +00006199 /* Remove the key from posix_putenv_garbage;
6200 * this will cause it to be collected. This has to
6201 * happen after the real unsetenv() call because the
6202 * old value was still accessible until then.
6203 */
6204 if (PyDict_DelItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00006205#ifdef MS_WINDOWS
6206 PyTuple_GET_ITEM(args, 0)
6207#else
6208 os1
6209#endif
6210 )) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006211 /* really not much we can do; just leak */
6212 PyErr_Clear();
6213 }
Guido van Rossumc524d952001-10-19 01:31:59 +00006214
Victor Stinner84ae1182010-05-06 22:05:07 +00006215#ifndef MS_WINDOWS
6216 Py_DECREF(os1);
6217#endif
6218 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00006219}
6220#endif /* unsetenv */
6221
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006222PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006223"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006224Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006225
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006226static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006227posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006228{
Victor Stinner8c62be82010-05-06 00:08:46 +00006229 int code;
6230 char *message;
6231 if (!PyArg_ParseTuple(args, "i:strerror", &code))
6232 return NULL;
6233 message = strerror(code);
6234 if (message == NULL) {
6235 PyErr_SetString(PyExc_ValueError,
6236 "strerror() argument out of range");
6237 return NULL;
6238 }
6239 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006240}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006241
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006242
Guido van Rossumc9641791998-08-04 15:26:23 +00006243#ifdef HAVE_SYS_WAIT_H
6244
Fred Drake106c1a02002-04-23 15:58:02 +00006245#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006246PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006247"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006248Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006249
6250static PyObject *
6251posix_WCOREDUMP(PyObject *self, PyObject *args)
6252{
Victor Stinner8c62be82010-05-06 00:08:46 +00006253 WAIT_TYPE status;
6254 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006255
Victor Stinner8c62be82010-05-06 00:08:46 +00006256 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
6257 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006258
Victor Stinner8c62be82010-05-06 00:08:46 +00006259 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006260}
6261#endif /* WCOREDUMP */
6262
6263#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006264PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006265"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006266Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006267job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006268
6269static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006270posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006271{
Victor Stinner8c62be82010-05-06 00:08:46 +00006272 WAIT_TYPE status;
6273 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006274
Victor Stinner8c62be82010-05-06 00:08:46 +00006275 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
6276 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006277
Victor Stinner8c62be82010-05-06 00:08:46 +00006278 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006279}
6280#endif /* WIFCONTINUED */
6281
Guido van Rossumc9641791998-08-04 15:26:23 +00006282#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006283PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006284"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006285Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006286
6287static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006288posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006289{
Victor Stinner8c62be82010-05-06 00:08:46 +00006290 WAIT_TYPE status;
6291 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006292
Victor Stinner8c62be82010-05-06 00:08:46 +00006293 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
6294 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006295
Victor Stinner8c62be82010-05-06 00:08:46 +00006296 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006297}
6298#endif /* WIFSTOPPED */
6299
6300#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006301PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006302"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006303Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006304
6305static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006306posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006307{
Victor Stinner8c62be82010-05-06 00:08:46 +00006308 WAIT_TYPE status;
6309 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006310
Victor Stinner8c62be82010-05-06 00:08:46 +00006311 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
6312 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006313
Victor Stinner8c62be82010-05-06 00:08:46 +00006314 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006315}
6316#endif /* WIFSIGNALED */
6317
6318#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006319PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006320"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006321Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006322system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006323
6324static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006325posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006326{
Victor Stinner8c62be82010-05-06 00:08:46 +00006327 WAIT_TYPE status;
6328 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006329
Victor Stinner8c62be82010-05-06 00:08:46 +00006330 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
6331 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006332
Victor Stinner8c62be82010-05-06 00:08:46 +00006333 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006334}
6335#endif /* WIFEXITED */
6336
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006337#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006338PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006339"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006340Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006341
6342static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006343posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006344{
Victor Stinner8c62be82010-05-06 00:08:46 +00006345 WAIT_TYPE status;
6346 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006347
Victor Stinner8c62be82010-05-06 00:08:46 +00006348 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
6349 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006350
Victor Stinner8c62be82010-05-06 00:08:46 +00006351 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006352}
6353#endif /* WEXITSTATUS */
6354
6355#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006356PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006357"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006358Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006359value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006360
6361static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006362posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006363{
Victor Stinner8c62be82010-05-06 00:08:46 +00006364 WAIT_TYPE status;
6365 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006366
Victor Stinner8c62be82010-05-06 00:08:46 +00006367 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
6368 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006369
Victor Stinner8c62be82010-05-06 00:08:46 +00006370 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006371}
6372#endif /* WTERMSIG */
6373
6374#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006375PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006376"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006377Return the signal that stopped the process that provided\n\
6378the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006379
6380static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006381posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006382{
Victor Stinner8c62be82010-05-06 00:08:46 +00006383 WAIT_TYPE status;
6384 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006385
Victor Stinner8c62be82010-05-06 00:08:46 +00006386 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
6387 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006388
Victor Stinner8c62be82010-05-06 00:08:46 +00006389 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006390}
6391#endif /* WSTOPSIG */
6392
6393#endif /* HAVE_SYS_WAIT_H */
6394
6395
Thomas Wouters477c8d52006-05-27 19:21:47 +00006396#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006397#ifdef _SCO_DS
6398/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6399 needed definitions in sys/statvfs.h */
6400#define _SVID3
6401#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006402#include <sys/statvfs.h>
6403
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006404static PyObject*
6405_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006406 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6407 if (v == NULL)
6408 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006409
6410#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006411 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6412 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6413 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
6414 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
6415 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
6416 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
6417 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
6418 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
6419 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6420 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006421#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006422 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6423 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6424 PyStructSequence_SET_ITEM(v, 2,
6425 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
6426 PyStructSequence_SET_ITEM(v, 3,
6427 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
6428 PyStructSequence_SET_ITEM(v, 4,
6429 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
6430 PyStructSequence_SET_ITEM(v, 5,
6431 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
6432 PyStructSequence_SET_ITEM(v, 6,
6433 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
6434 PyStructSequence_SET_ITEM(v, 7,
6435 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
6436 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6437 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006438#endif
6439
Victor Stinner8c62be82010-05-06 00:08:46 +00006440 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006441}
6442
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006443PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006444"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006445Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006446
6447static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006448posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006449{
Victor Stinner8c62be82010-05-06 00:08:46 +00006450 int fd, res;
6451 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006452
Victor Stinner8c62be82010-05-06 00:08:46 +00006453 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
6454 return NULL;
6455 Py_BEGIN_ALLOW_THREADS
6456 res = fstatvfs(fd, &st);
6457 Py_END_ALLOW_THREADS
6458 if (res != 0)
6459 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006460
Victor Stinner8c62be82010-05-06 00:08:46 +00006461 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006462}
Thomas Wouters477c8d52006-05-27 19:21:47 +00006463#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006464
6465
Thomas Wouters477c8d52006-05-27 19:21:47 +00006466#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006467#include <sys/statvfs.h>
6468
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006469PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006470"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006471Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006472
6473static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006474posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006475{
Victor Stinner8c62be82010-05-06 00:08:46 +00006476 char *path;
6477 int res;
6478 struct statvfs st;
6479 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
6480 return NULL;
6481 Py_BEGIN_ALLOW_THREADS
6482 res = statvfs(path, &st);
6483 Py_END_ALLOW_THREADS
6484 if (res != 0)
6485 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006486
Victor Stinner8c62be82010-05-06 00:08:46 +00006487 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006488}
6489#endif /* HAVE_STATVFS */
6490
Fred Drakec9680921999-12-13 16:37:25 +00006491/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6492 * It maps strings representing configuration variable names to
6493 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006494 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006495 * rarely-used constants. There are three separate tables that use
6496 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006497 *
6498 * This code is always included, even if none of the interfaces that
6499 * need it are included. The #if hackery needed to avoid it would be
6500 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006501 */
6502struct constdef {
6503 char *name;
6504 long value;
6505};
6506
Fred Drake12c6e2d1999-12-14 21:25:03 +00006507static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006508conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00006509 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006510{
Christian Heimes217cfd12007-12-02 14:31:20 +00006511 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006512 *valuep = PyLong_AS_LONG(arg);
6513 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006514 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00006515 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00006516 /* look up the value in the table using a binary search */
6517 size_t lo = 0;
6518 size_t mid;
6519 size_t hi = tablesize;
6520 int cmp;
6521 const char *confname;
6522 if (!PyUnicode_Check(arg)) {
6523 PyErr_SetString(PyExc_TypeError,
6524 "configuration names must be strings or integers");
6525 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006526 }
Stefan Krah0e803b32010-11-26 16:16:47 +00006527 confname = _PyUnicode_AsString(arg);
6528 if (confname == NULL)
6529 return 0;
6530 while (lo < hi) {
6531 mid = (lo + hi) / 2;
6532 cmp = strcmp(confname, table[mid].name);
6533 if (cmp < 0)
6534 hi = mid;
6535 else if (cmp > 0)
6536 lo = mid + 1;
6537 else {
6538 *valuep = table[mid].value;
6539 return 1;
6540 }
6541 }
6542 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6543 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006544 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00006545}
6546
6547
6548#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6549static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006550#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006551 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006552#endif
6553#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006554 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006555#endif
Fred Drakec9680921999-12-13 16:37:25 +00006556#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006557 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006558#endif
6559#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00006560 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00006561#endif
6562#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00006563 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00006564#endif
6565#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00006566 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00006567#endif
6568#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006569 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006570#endif
6571#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00006572 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00006573#endif
6574#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00006575 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00006576#endif
6577#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006578 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006579#endif
6580#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006581 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00006582#endif
6583#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006584 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006585#endif
6586#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006587 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00006588#endif
6589#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006590 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006591#endif
6592#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006593 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00006594#endif
6595#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006596 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006597#endif
6598#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00006599 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00006600#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00006601#ifdef _PC_ACL_ENABLED
6602 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
6603#endif
6604#ifdef _PC_MIN_HOLE_SIZE
6605 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
6606#endif
6607#ifdef _PC_ALLOC_SIZE_MIN
6608 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
6609#endif
6610#ifdef _PC_REC_INCR_XFER_SIZE
6611 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
6612#endif
6613#ifdef _PC_REC_MAX_XFER_SIZE
6614 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
6615#endif
6616#ifdef _PC_REC_MIN_XFER_SIZE
6617 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
6618#endif
6619#ifdef _PC_REC_XFER_ALIGN
6620 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
6621#endif
6622#ifdef _PC_SYMLINK_MAX
6623 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
6624#endif
6625#ifdef _PC_XATTR_ENABLED
6626 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
6627#endif
6628#ifdef _PC_XATTR_EXISTS
6629 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
6630#endif
6631#ifdef _PC_TIMESTAMP_RESOLUTION
6632 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
6633#endif
Fred Drakec9680921999-12-13 16:37:25 +00006634};
6635
Fred Drakec9680921999-12-13 16:37:25 +00006636static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006637conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006638{
6639 return conv_confname(arg, valuep, posix_constants_pathconf,
6640 sizeof(posix_constants_pathconf)
6641 / sizeof(struct constdef));
6642}
6643#endif
6644
6645#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006646PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006647"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006648Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006649If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006650
6651static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006652posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006653{
6654 PyObject *result = NULL;
6655 int name, fd;
6656
Fred Drake12c6e2d1999-12-14 21:25:03 +00006657 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6658 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006659 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006660
Stefan Krah0e803b32010-11-26 16:16:47 +00006661 errno = 0;
6662 limit = fpathconf(fd, name);
6663 if (limit == -1 && errno != 0)
6664 posix_error();
6665 else
6666 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006667 }
6668 return result;
6669}
6670#endif
6671
6672
6673#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006674PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006675"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006676Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006677If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006678
6679static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006680posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006681{
6682 PyObject *result = NULL;
6683 int name;
6684 char *path;
6685
6686 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6687 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006688 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006689
Victor Stinner8c62be82010-05-06 00:08:46 +00006690 errno = 0;
6691 limit = pathconf(path, name);
6692 if (limit == -1 && errno != 0) {
6693 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00006694 /* could be a path or name problem */
6695 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00006696 else
Stefan Krah99439262010-11-26 12:58:05 +00006697 posix_error_with_filename(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00006698 }
6699 else
6700 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006701 }
6702 return result;
6703}
6704#endif
6705
6706#ifdef HAVE_CONFSTR
6707static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006708#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00006709 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00006710#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00006711#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006712 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006713#endif
6714#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006715 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006716#endif
Fred Draked86ed291999-12-15 15:34:33 +00006717#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006718 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006719#endif
6720#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006721 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006722#endif
6723#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006724 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006725#endif
6726#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006727 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006728#endif
Fred Drakec9680921999-12-13 16:37:25 +00006729#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006730 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006731#endif
6732#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006733 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006734#endif
6735#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006736 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006737#endif
6738#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006739 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006740#endif
6741#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006742 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006743#endif
6744#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006745 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006746#endif
6747#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006748 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006749#endif
6750#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006751 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006752#endif
Fred Draked86ed291999-12-15 15:34:33 +00006753#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00006754 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00006755#endif
Fred Drakec9680921999-12-13 16:37:25 +00006756#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00006757 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00006758#endif
Fred Draked86ed291999-12-15 15:34:33 +00006759#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006760 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00006761#endif
6762#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006763 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00006764#endif
6765#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006766 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006767#endif
6768#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006769 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00006770#endif
Fred Drakec9680921999-12-13 16:37:25 +00006771#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006772 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006773#endif
6774#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006775 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006776#endif
6777#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006778 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006779#endif
6780#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006781 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006782#endif
6783#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006784 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006785#endif
6786#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006787 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006788#endif
6789#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006790 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006791#endif
6792#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006793 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006794#endif
6795#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006796 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006797#endif
6798#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006800#endif
6801#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006803#endif
6804#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006805 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006806#endif
6807#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006808 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006809#endif
6810#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006811 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006812#endif
6813#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006814 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006815#endif
6816#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006818#endif
Fred Draked86ed291999-12-15 15:34:33 +00006819#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006820 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006821#endif
6822#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006823 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00006824#endif
6825#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00006827#endif
6828#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006829 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006830#endif
6831#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006832 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006833#endif
6834#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00006835 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00006836#endif
6837#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006838 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00006839#endif
6840#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00006841 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00006842#endif
6843#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006844 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006845#endif
6846#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006847 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006848#endif
6849#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006850 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006851#endif
6852#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006853 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006854#endif
6855#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00006856 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00006857#endif
Fred Drakec9680921999-12-13 16:37:25 +00006858};
6859
6860static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006861conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006862{
6863 return conv_confname(arg, valuep, posix_constants_confstr,
6864 sizeof(posix_constants_confstr)
6865 / sizeof(struct constdef));
6866}
6867
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006868PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006869"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006870Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006871
6872static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006873posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006874{
6875 PyObject *result = NULL;
6876 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00006877 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00006878 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006879
Victor Stinnercb043522010-09-10 23:49:04 +00006880 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
6881 return NULL;
6882
6883 errno = 0;
6884 len = confstr(name, buffer, sizeof(buffer));
6885 if (len == 0) {
6886 if (errno) {
6887 posix_error();
6888 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00006889 }
6890 else {
Victor Stinnercb043522010-09-10 23:49:04 +00006891 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00006892 }
6893 }
Victor Stinnercb043522010-09-10 23:49:04 +00006894
6895 if ((unsigned int)len >= sizeof(buffer)) {
6896 char *buf = PyMem_Malloc(len);
6897 if (buf == NULL)
6898 return PyErr_NoMemory();
6899 confstr(name, buf, len);
6900 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
6901 PyMem_Free(buf);
6902 }
6903 else
6904 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006905 return result;
6906}
6907#endif
6908
6909
6910#ifdef HAVE_SYSCONF
6911static struct constdef posix_constants_sysconf[] = {
6912#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00006913 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00006914#endif
6915#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00006916 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00006917#endif
6918#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006919 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006920#endif
6921#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006922 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006923#endif
6924#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006925 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006926#endif
6927#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00006928 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00006929#endif
6930#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00006931 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00006932#endif
6933#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006934 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006935#endif
6936#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00006937 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00006938#endif
6939#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006940 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006941#endif
Fred Draked86ed291999-12-15 15:34:33 +00006942#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006943 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006944#endif
6945#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00006946 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00006947#endif
Fred Drakec9680921999-12-13 16:37:25 +00006948#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006949 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006950#endif
Fred Drakec9680921999-12-13 16:37:25 +00006951#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006952 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006953#endif
6954#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006955 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006956#endif
6957#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006958 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006959#endif
6960#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006961 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006962#endif
6963#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006964 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006965#endif
Fred Draked86ed291999-12-15 15:34:33 +00006966#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006967 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00006968#endif
Fred Drakec9680921999-12-13 16:37:25 +00006969#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00006970 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006971#endif
6972#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006973 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006974#endif
6975#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006976 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006977#endif
6978#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006979 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006980#endif
6981#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006982 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006983#endif
Fred Draked86ed291999-12-15 15:34:33 +00006984#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00006985 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00006986#endif
Fred Drakec9680921999-12-13 16:37:25 +00006987#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006988 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006989#endif
6990#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006991 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006992#endif
6993#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006994 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006995#endif
6996#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006997 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006998#endif
6999#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007000 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007001#endif
7002#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007003 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00007004#endif
7005#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007006 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007007#endif
7008#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007009 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007010#endif
7011#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00007012 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00007013#endif
7014#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007015 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007016#endif
7017#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007018 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00007019#endif
7020#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007021 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00007022#endif
7023#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007024 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007025#endif
7026#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007027 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007028#endif
7029#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007030 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007031#endif
7032#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007033 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007034#endif
7035#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007036 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00007037#endif
7038#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007039 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007040#endif
7041#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007042 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007043#endif
7044#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00007045 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00007046#endif
7047#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007048 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007049#endif
7050#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007051 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00007052#endif
7053#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007054 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00007055#endif
Fred Draked86ed291999-12-15 15:34:33 +00007056#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00007057 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00007058#endif
Fred Drakec9680921999-12-13 16:37:25 +00007059#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007060 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007061#endif
7062#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007063 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007064#endif
7065#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007066 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007067#endif
Fred Draked86ed291999-12-15 15:34:33 +00007068#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007069 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00007070#endif
Fred Drakec9680921999-12-13 16:37:25 +00007071#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00007072 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00007073#endif
Fred Draked86ed291999-12-15 15:34:33 +00007074#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00007075 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00007076#endif
7077#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00007078 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00007079#endif
Fred Drakec9680921999-12-13 16:37:25 +00007080#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007081 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007082#endif
7083#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007084 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007085#endif
7086#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007087 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007088#endif
7089#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007090 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007091#endif
Fred Draked86ed291999-12-15 15:34:33 +00007092#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00007093 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00007094#endif
Fred Drakec9680921999-12-13 16:37:25 +00007095#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00007096 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00007097#endif
7098#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00007099 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00007100#endif
7101#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007102 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007103#endif
7104#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007105 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00007106#endif
7107#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00007108 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00007109#endif
7110#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00007111 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00007112#endif
7113#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00007114 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00007115#endif
Fred Draked86ed291999-12-15 15:34:33 +00007116#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00007117 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00007118#endif
Fred Drakec9680921999-12-13 16:37:25 +00007119#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007120 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007121#endif
7122#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007123 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007124#endif
Fred Draked86ed291999-12-15 15:34:33 +00007125#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007126 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00007127#endif
Fred Drakec9680921999-12-13 16:37:25 +00007128#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007129 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007130#endif
7131#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007132 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007133#endif
7134#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007135 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007136#endif
7137#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007138 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007139#endif
7140#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007141 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007142#endif
7143#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007144 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007145#endif
7146#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007147 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007148#endif
7149#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007150 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00007151#endif
7152#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00007153 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00007154#endif
Fred Draked86ed291999-12-15 15:34:33 +00007155#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007156 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00007157#endif
7158#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00007159 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00007160#endif
Fred Drakec9680921999-12-13 16:37:25 +00007161#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00007162 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00007163#endif
7164#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007165 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007166#endif
7167#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007168 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007169#endif
7170#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007171 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007172#endif
7173#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007174 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007175#endif
7176#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00007177 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00007178#endif
7179#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00007180 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00007181#endif
7182#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00007183 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00007184#endif
7185#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00007186 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00007187#endif
7188#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00007189 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00007190#endif
7191#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00007192 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00007193#endif
7194#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007195 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00007196#endif
7197#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007198 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00007199#endif
7200#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00007201 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00007202#endif
7203#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00007204 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00007205#endif
7206#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00007207 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00007208#endif
7209#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00007210 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00007211#endif
7212#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007213 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007214#endif
7215#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007216 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007217#endif
7218#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00007219 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00007220#endif
7221#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007222 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007223#endif
7224#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007225 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007226#endif
7227#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00007228 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00007229#endif
7230#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007231 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007232#endif
7233#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007234 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007235#endif
7236#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007237 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00007238#endif
7239#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00007240 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00007241#endif
7242#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007243 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007244#endif
7245#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007246 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007247#endif
7248#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007249 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00007250#endif
7251#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007252 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007253#endif
7254#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007255 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007256#endif
7257#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007258 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007259#endif
7260#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007261 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007262#endif
7263#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007264 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007265#endif
Fred Draked86ed291999-12-15 15:34:33 +00007266#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00007267 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00007268#endif
Fred Drakec9680921999-12-13 16:37:25 +00007269#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00007270 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00007271#endif
7272#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007273 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007274#endif
7275#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00007276 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00007277#endif
7278#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007279 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007280#endif
7281#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007282 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007283#endif
7284#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007285 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007286#endif
7287#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00007288 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00007289#endif
7290#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007291 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007292#endif
7293#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007294 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007295#endif
7296#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007297 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007298#endif
7299#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007300 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007301#endif
7302#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007303 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00007304#endif
7305#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007306 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00007307#endif
7308#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00007309 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00007310#endif
7311#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007312 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007313#endif
7314#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007315 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007316#endif
7317#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007318 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007319#endif
7320#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00007321 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00007322#endif
7323#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007324 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007325#endif
7326#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007327 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007328#endif
7329#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007330 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007331#endif
7332#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007333 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007334#endif
7335#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007336 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007337#endif
7338#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007339 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007340#endif
7341#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00007342 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00007343#endif
7344#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007345 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007346#endif
7347#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007348 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007349#endif
7350#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007351 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007352#endif
7353#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007354 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007355#endif
7356#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00007357 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00007358#endif
7359#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007360 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007361#endif
7362#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00007363 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00007364#endif
7365#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007366 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007367#endif
7368#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00007369 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00007370#endif
7371#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00007372 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00007373#endif
7374#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00007375 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00007376#endif
7377#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00007378 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00007379#endif
7380#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007381 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007382#endif
7383#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00007384 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00007385#endif
7386#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00007387 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00007388#endif
7389#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007390 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007391#endif
7392#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007393 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007394#endif
7395#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00007396 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00007397#endif
7398#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00007399 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00007400#endif
7401#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00007402 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00007403#endif
7404};
7405
7406static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007407conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007408{
7409 return conv_confname(arg, valuep, posix_constants_sysconf,
7410 sizeof(posix_constants_sysconf)
7411 / sizeof(struct constdef));
7412}
7413
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007414PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007415"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007416Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007417
7418static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007419posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007420{
7421 PyObject *result = NULL;
7422 int name;
7423
7424 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7425 int value;
7426
7427 errno = 0;
7428 value = sysconf(name);
7429 if (value == -1 && errno != 0)
7430 posix_error();
7431 else
Christian Heimes217cfd12007-12-02 14:31:20 +00007432 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00007433 }
7434 return result;
7435}
7436#endif
7437
7438
Fred Drakebec628d1999-12-15 18:31:10 +00007439/* This code is used to ensure that the tables of configuration value names
7440 * are in sorted order as required by conv_confname(), and also to build the
7441 * the exported dictionaries that are used to publish information about the
7442 * names available on the host platform.
7443 *
7444 * Sorting the table at runtime ensures that the table is properly ordered
7445 * when used, even for platforms we're not able to test on. It also makes
7446 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007447 */
Fred Drakebec628d1999-12-15 18:31:10 +00007448
7449static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007450cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007451{
7452 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007453 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00007454 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007455 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00007456
7457 return strcmp(c1->name, c2->name);
7458}
7459
7460static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007461setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00007462 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007463{
Fred Drakebec628d1999-12-15 18:31:10 +00007464 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007465 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007466
7467 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7468 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007469 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00007470 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007471
Barry Warsaw3155db32000-04-13 15:20:40 +00007472 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007473 PyObject *o = PyLong_FromLong(table[i].value);
7474 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7475 Py_XDECREF(o);
7476 Py_DECREF(d);
7477 return -1;
7478 }
7479 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007480 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007481 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007482}
7483
Fred Drakebec628d1999-12-15 18:31:10 +00007484/* Return -1 on failure, 0 on success. */
7485static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007486setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007487{
7488#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007489 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007490 sizeof(posix_constants_pathconf)
7491 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007492 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00007493 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007494#endif
7495#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007496 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007497 sizeof(posix_constants_confstr)
7498 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007499 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00007500 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007501#endif
7502#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007503 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007504 sizeof(posix_constants_sysconf)
7505 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007506 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00007507 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007508#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007509 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007510}
Fred Draked86ed291999-12-15 15:34:33 +00007511
7512
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007513PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007514"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007515Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007516in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007517
7518static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007519posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007520{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007521 abort();
7522 /*NOTREACHED*/
7523 Py_FatalError("abort() called from Python code didn't abort!");
7524 return NULL;
7525}
Fred Drakebec628d1999-12-15 18:31:10 +00007526
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007527#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007528PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007529"startfile(filepath [, operation]) - Start a file with its associated\n\
7530application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007531\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007532When \"operation\" is not specified or \"open\", this acts like\n\
7533double-clicking the file in Explorer, or giving the file name as an\n\
7534argument to the DOS \"start\" command: the file is opened with whatever\n\
7535application (if any) its extension is associated.\n\
7536When another \"operation\" is given, it specifies what should be done with\n\
7537the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007538\n\
7539startfile returns as soon as the associated application is launched.\n\
7540There is no option to wait for the application to close, and no way\n\
7541to retrieve the application's exit status.\n\
7542\n\
7543The filepath is relative to the current directory. If you want to use\n\
7544an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007545the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007546
7547static PyObject *
7548win32_startfile(PyObject *self, PyObject *args)
7549{
Victor Stinner8c62be82010-05-06 00:08:46 +00007550 PyObject *ofilepath;
7551 char *filepath;
7552 char *operation = NULL;
7553 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00007554
Victor Stinner8c62be82010-05-06 00:08:46 +00007555 PyObject *unipath, *woperation = NULL;
7556 if (!PyArg_ParseTuple(args, "U|s:startfile",
7557 &unipath, &operation)) {
7558 PyErr_Clear();
7559 goto normal;
7560 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007561
Victor Stinner8c62be82010-05-06 00:08:46 +00007562 if (operation) {
7563 woperation = PyUnicode_DecodeASCII(operation,
7564 strlen(operation), NULL);
7565 if (!woperation) {
7566 PyErr_Clear();
7567 operation = NULL;
7568 goto normal;
7569 }
7570 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007571
Victor Stinner8c62be82010-05-06 00:08:46 +00007572 Py_BEGIN_ALLOW_THREADS
7573 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
7574 PyUnicode_AS_UNICODE(unipath),
7575 NULL, NULL, SW_SHOWNORMAL);
7576 Py_END_ALLOW_THREADS
7577
7578 Py_XDECREF(woperation);
7579 if (rc <= (HINSTANCE)32) {
7580 PyObject *errval = win32_error_unicode("startfile",
7581 PyUnicode_AS_UNICODE(unipath));
7582 return errval;
7583 }
7584 Py_INCREF(Py_None);
7585 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007586
7587normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00007588 if (!PyArg_ParseTuple(args, "O&|s:startfile",
7589 PyUnicode_FSConverter, &ofilepath,
7590 &operation))
7591 return NULL;
7592 filepath = PyBytes_AsString(ofilepath);
7593 Py_BEGIN_ALLOW_THREADS
7594 rc = ShellExecute((HWND)0, operation, filepath,
7595 NULL, NULL, SW_SHOWNORMAL);
7596 Py_END_ALLOW_THREADS
7597 if (rc <= (HINSTANCE)32) {
7598 PyObject *errval = win32_error("startfile", filepath);
7599 Py_DECREF(ofilepath);
7600 return errval;
7601 }
7602 Py_DECREF(ofilepath);
7603 Py_INCREF(Py_None);
7604 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007605}
7606#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007607
Martin v. Löwis438b5342002-12-27 10:16:42 +00007608#ifdef HAVE_GETLOADAVG
7609PyDoc_STRVAR(posix_getloadavg__doc__,
7610"getloadavg() -> (float, float, float)\n\n\
7611Return the number of processes in the system run queue averaged over\n\
7612the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7613was unobtainable");
7614
7615static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007616posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007617{
7618 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007619 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00007620 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7621 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00007622 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00007623 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00007624}
7625#endif
7626
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007627#ifdef MS_WINDOWS
7628
7629PyDoc_STRVAR(win32_urandom__doc__,
7630"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007631Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007632
7633typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7634 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7635 DWORD dwFlags );
7636typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7637 BYTE *pbBuffer );
7638
7639static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00007640/* This handle is never explicitly released. Instead, the operating
7641 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007642static HCRYPTPROV hCryptProv = 0;
7643
Tim Peters4ad82172004-08-30 17:02:04 +00007644static PyObject*
7645win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007646{
Victor Stinner8c62be82010-05-06 00:08:46 +00007647 int howMany;
7648 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007649
Victor Stinner8c62be82010-05-06 00:08:46 +00007650 /* Read arguments */
7651 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7652 return NULL;
7653 if (howMany < 0)
7654 return PyErr_Format(PyExc_ValueError,
7655 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007656
Victor Stinner8c62be82010-05-06 00:08:46 +00007657 if (hCryptProv == 0) {
7658 HINSTANCE hAdvAPI32 = NULL;
7659 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007660
Victor Stinner8c62be82010-05-06 00:08:46 +00007661 /* Obtain handle to the DLL containing CryptoAPI
7662 This should not fail */
7663 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7664 if(hAdvAPI32 == NULL)
7665 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007666
Victor Stinner8c62be82010-05-06 00:08:46 +00007667 /* Obtain pointers to the CryptoAPI functions
7668 This will fail on some early versions of Win95 */
7669 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7670 hAdvAPI32,
7671 "CryptAcquireContextA");
7672 if (pCryptAcquireContext == NULL)
7673 return PyErr_Format(PyExc_NotImplementedError,
7674 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007675
Victor Stinner8c62be82010-05-06 00:08:46 +00007676 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7677 hAdvAPI32, "CryptGenRandom");
7678 if (pCryptGenRandom == NULL)
7679 return PyErr_Format(PyExc_NotImplementedError,
7680 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007681
Victor Stinner8c62be82010-05-06 00:08:46 +00007682 /* Acquire context */
7683 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7684 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7685 return win32_error("CryptAcquireContext", NULL);
7686 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007687
Victor Stinner8c62be82010-05-06 00:08:46 +00007688 /* Allocate bytes */
7689 result = PyBytes_FromStringAndSize(NULL, howMany);
7690 if (result != NULL) {
7691 /* Get random data */
7692 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
7693 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7694 PyBytes_AS_STRING(result))) {
7695 Py_DECREF(result);
7696 return win32_error("CryptGenRandom", NULL);
7697 }
7698 }
7699 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007700}
7701#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007702
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007703PyDoc_STRVAR(device_encoding__doc__,
7704"device_encoding(fd) -> str\n\n\
7705Return a string describing the encoding of the device\n\
7706if the output is a terminal; else return None.");
7707
7708static PyObject *
7709device_encoding(PyObject *self, PyObject *args)
7710{
Victor Stinner8c62be82010-05-06 00:08:46 +00007711 int fd;
7712 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
7713 return NULL;
7714 if (!_PyVerify_fd(fd) || !isatty(fd)) {
7715 Py_INCREF(Py_None);
7716 return Py_None;
7717 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007718#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner8c62be82010-05-06 00:08:46 +00007719 if (fd == 0) {
7720 char buf[100];
7721 sprintf(buf, "cp%d", GetConsoleCP());
7722 return PyUnicode_FromString(buf);
7723 }
7724 if (fd == 1 || fd == 2) {
7725 char buf[100];
7726 sprintf(buf, "cp%d", GetConsoleOutputCP());
7727 return PyUnicode_FromString(buf);
7728 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007729#elif defined(CODESET)
Victor Stinner8c62be82010-05-06 00:08:46 +00007730 {
7731 char *codeset = nl_langinfo(CODESET);
7732 if (codeset != NULL && codeset[0] != 0)
7733 return PyUnicode_FromString(codeset);
7734 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007735#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007736 Py_INCREF(Py_None);
7737 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007738}
7739
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007740#ifdef __VMS
7741/* Use openssl random routine */
7742#include <openssl/rand.h>
7743PyDoc_STRVAR(vms_urandom__doc__,
7744"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007745Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007746
7747static PyObject*
7748vms_urandom(PyObject *self, PyObject *args)
7749{
Victor Stinner8c62be82010-05-06 00:08:46 +00007750 int howMany;
7751 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007752
Victor Stinner8c62be82010-05-06 00:08:46 +00007753 /* Read arguments */
7754 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7755 return NULL;
7756 if (howMany < 0)
7757 return PyErr_Format(PyExc_ValueError,
7758 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007759
Victor Stinner8c62be82010-05-06 00:08:46 +00007760 /* Allocate bytes */
7761 result = PyBytes_FromStringAndSize(NULL, howMany);
7762 if (result != NULL) {
7763 /* Get random data */
7764 if (RAND_pseudo_bytes((unsigned char*)
7765 PyBytes_AS_STRING(result),
7766 howMany) < 0) {
7767 Py_DECREF(result);
7768 return PyErr_Format(PyExc_ValueError,
7769 "RAND_pseudo_bytes");
7770 }
7771 }
7772 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007773}
7774#endif
7775
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007776#ifdef HAVE_SETRESUID
7777PyDoc_STRVAR(posix_setresuid__doc__,
7778"setresuid(ruid, euid, suid)\n\n\
7779Set the current process's real, effective, and saved user ids.");
7780
7781static PyObject*
7782posix_setresuid (PyObject *self, PyObject *args)
7783{
Victor Stinner8c62be82010-05-06 00:08:46 +00007784 /* We assume uid_t is no larger than a long. */
7785 long ruid, euid, suid;
7786 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
7787 return NULL;
7788 if (setresuid(ruid, euid, suid) < 0)
7789 return posix_error();
7790 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007791}
7792#endif
7793
7794#ifdef HAVE_SETRESGID
7795PyDoc_STRVAR(posix_setresgid__doc__,
7796"setresgid(rgid, egid, sgid)\n\n\
7797Set the current process's real, effective, and saved group ids.");
7798
7799static PyObject*
7800posix_setresgid (PyObject *self, PyObject *args)
7801{
Victor Stinner8c62be82010-05-06 00:08:46 +00007802 /* We assume uid_t is no larger than a long. */
7803 long rgid, egid, sgid;
7804 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
7805 return NULL;
7806 if (setresgid(rgid, egid, sgid) < 0)
7807 return posix_error();
7808 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007809}
7810#endif
7811
7812#ifdef HAVE_GETRESUID
7813PyDoc_STRVAR(posix_getresuid__doc__,
7814"getresuid() -> (ruid, euid, suid)\n\n\
7815Get tuple of the current process's real, effective, and saved user ids.");
7816
7817static PyObject*
7818posix_getresuid (PyObject *self, PyObject *noargs)
7819{
Victor Stinner8c62be82010-05-06 00:08:46 +00007820 uid_t ruid, euid, suid;
7821 long l_ruid, l_euid, l_suid;
7822 if (getresuid(&ruid, &euid, &suid) < 0)
7823 return posix_error();
7824 /* Force the values into long's as we don't know the size of uid_t. */
7825 l_ruid = ruid;
7826 l_euid = euid;
7827 l_suid = suid;
7828 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007829}
7830#endif
7831
7832#ifdef HAVE_GETRESGID
7833PyDoc_STRVAR(posix_getresgid__doc__,
7834"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00007835Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007836
7837static PyObject*
7838posix_getresgid (PyObject *self, PyObject *noargs)
7839{
Victor Stinner8c62be82010-05-06 00:08:46 +00007840 uid_t rgid, egid, sgid;
7841 long l_rgid, l_egid, l_sgid;
7842 if (getresgid(&rgid, &egid, &sgid) < 0)
7843 return posix_error();
7844 /* Force the values into long's as we don't know the size of uid_t. */
7845 l_rgid = rgid;
7846 l_egid = egid;
7847 l_sgid = sgid;
7848 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007849}
7850#endif
7851
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007852static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00007853 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007854#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007855 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007856#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007857 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007858#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007859 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007860#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007861 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007862#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007863 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007864#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007865#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007866 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007867#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00007868#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007869 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007870#endif /* HAVE_LCHMOD */
7871#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007872 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007873#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00007874#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007875 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007876#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007877#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007878 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007879#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007880#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +00007881 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00007882#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007883#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +00007884 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007885#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007886#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +00007887 {"getcwd", (PyCFunction)posix_getcwd_unicode,
7888 METH_NOARGS, posix_getcwd__doc__},
7889 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
7890 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007891#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007892#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007893 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007894#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +00007895 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7896 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7897 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007898#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +00007899 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007900#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007901#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007902 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007903#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007904#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007905 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007906#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007907 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7908 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7909 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +00007910 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Brian Curtin52173d42010-12-02 18:29:18 +00007911#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007912 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007913#endif /* HAVE_SYMLINK */
Brian Curtin52173d42010-12-02 18:29:18 +00007914#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +00007915 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
Brian Curtin52173d42010-12-02 18:29:18 +00007916 win_symlink__doc__},
7917#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007918#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +00007919 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007920#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007921 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007922#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007923 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007924#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +00007925 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7926 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7927 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007928#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00007929 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007930#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00007931 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007932#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +00007933 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7934 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007935#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007936#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +00007937 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7938 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007939#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00007940 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7941 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007942#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007943#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007944#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +00007945 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007946#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007947#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +00007948 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007949#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007950#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +00007951 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007952#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007953#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007954 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007955#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007956#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007957 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007958#endif /* HAVE_GETEGID */
7959#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007960 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007961#endif /* HAVE_GETEUID */
7962#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007963 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007964#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007965#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007966 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007967#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007968 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007969#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007970 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007971#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007972#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +00007973 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007974#endif /* HAVE_GETPPID */
7975#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007976 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007977#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007978#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007979 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007980#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007981#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +00007982 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007983#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007984#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +00007985 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007986#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007987#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007988 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007989#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007990#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007991 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7992 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Brian Curtin1b9df392010-11-24 20:24:31 +00007993 {"link", win32_link, METH_VARARGS, win32_link__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +00007994#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007995#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007996 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007997#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007998#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007999 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008000#endif /* HAVE_SETEUID */
8001#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008002 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008003#endif /* HAVE_SETEGID */
8004#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008005 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008006#endif /* HAVE_SETREUID */
8007#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008008 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008009#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008010#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008011 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008012#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008013#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00008014 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008015#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +00008016#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00008017 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +00008018#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008019#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008020 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00008021#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008022#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00008023 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008024#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008025#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008026 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008027#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008028#ifdef HAVE_WAIT3
Victor Stinner8c62be82010-05-06 00:08:46 +00008029 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008030#endif /* HAVE_WAIT3 */
8031#ifdef HAVE_WAIT4
Victor Stinner8c62be82010-05-06 00:08:46 +00008032 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008033#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008034#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008035 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008036#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008037#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00008038 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008039#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008040#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00008041 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008042#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008043#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008044 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008045#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008046#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00008047 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008048#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008049#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00008050 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008051#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +00008052 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8053 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8054 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
8055 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
8056 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8057 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8058 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8059 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8060 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8061 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8062 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008063#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +00008064 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008065#endif
8066#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +00008067 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008068#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008069#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +00008070 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008071#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008072#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +00008073 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8074 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8075 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008076#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008077#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +00008078 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008079#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008080#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00008081 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008082#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008083#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +00008084 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00008085#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008086 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008087#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +00008088 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008089#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008090#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008091 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008092#endif
8093#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008094 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008095#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008096#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008097#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +00008098 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00008099#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008100#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00008101 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008102#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008103#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +00008104 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008105#endif /* WIFSTOPPED */
8106#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +00008107 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008108#endif /* WIFSIGNALED */
8109#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +00008110 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008111#endif /* WIFEXITED */
8112#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +00008113 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008114#endif /* WEXITSTATUS */
8115#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008116 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008117#endif /* WTERMSIG */
8118#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008119 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008120#endif /* WSTOPSIG */
8121#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008122#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00008123 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008124#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00008125#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00008126 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008127#endif
Fred Drakec9680921999-12-13 16:37:25 +00008128#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +00008129 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008130#endif
8131#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008132 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008133#endif
8134#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008135 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008136#endif
8137#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008138 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008139#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008140 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008141#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008142 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +00008143 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +00008144 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -05008145 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00008146#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008147#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +00008148 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008149#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008150 #ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008151 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008152 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008153 #ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008154 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008155 #endif
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008156#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008157 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008158#endif
8159#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008160 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008161#endif
8162#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008163 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008164#endif
8165#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008166 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008167#endif
8168
Victor Stinner8c62be82010-05-06 00:08:46 +00008169 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008170};
8171
8172
Barry Warsaw4a342091996-12-19 23:50:02 +00008173static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008174ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008175{
Victor Stinner8c62be82010-05-06 00:08:46 +00008176 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008177}
8178
Guido van Rossumd48f2521997-12-05 22:19:34 +00008179#if defined(PYOS_OS2)
8180/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008181static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008182{
8183 APIRET rc;
8184 ULONG values[QSV_MAX+1];
8185 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008186 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008187
8188 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008189 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008190 Py_END_ALLOW_THREADS
8191
8192 if (rc != NO_ERROR) {
8193 os2_error(rc);
8194 return -1;
8195 }
8196
Fred Drake4d1e64b2002-04-15 19:40:07 +00008197 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8198 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8199 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8200 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8201 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8202 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8203 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008204
8205 switch (values[QSV_VERSION_MINOR]) {
8206 case 0: ver = "2.00"; break;
8207 case 10: ver = "2.10"; break;
8208 case 11: ver = "2.11"; break;
8209 case 30: ver = "3.00"; break;
8210 case 40: ver = "4.00"; break;
8211 case 50: ver = "5.00"; break;
8212 default:
Tim Peters885d4572001-11-28 20:27:42 +00008213 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +00008214 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00008215 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008216 ver = &tmp[0];
8217 }
8218
8219 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008220 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008221 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008222
8223 /* Add Indicator of Which Drive was Used to Boot the System */
8224 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8225 tmp[1] = ':';
8226 tmp[2] = '\0';
8227
Fred Drake4d1e64b2002-04-15 19:40:07 +00008228 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008229}
8230#endif
8231
Brian Curtin52173d42010-12-02 18:29:18 +00008232#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +00008233static int
Brian Curtin52173d42010-12-02 18:29:18 +00008234enable_symlink()
8235{
8236 HANDLE tok;
8237 TOKEN_PRIVILEGES tok_priv;
8238 LUID luid;
8239 int meth_idx = 0;
8240
8241 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +00008242 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +00008243
8244 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +00008245 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +00008246
8247 tok_priv.PrivilegeCount = 1;
8248 tok_priv.Privileges[0].Luid = luid;
8249 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
8250
8251 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
8252 sizeof(TOKEN_PRIVILEGES),
8253 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +00008254 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +00008255
Brian Curtin3b4499c2010-12-28 14:31:47 +00008256 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
8257 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +00008258}
8259#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
8260
Barry Warsaw4a342091996-12-19 23:50:02 +00008261static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008262all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008263{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008264#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008265 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008266#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008267#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008268 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008269#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008270#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008271 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008272#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008273#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008274 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008275#endif
Fred Drakec9680921999-12-13 16:37:25 +00008276#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008277 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00008278#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008279#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008280 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008281#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008282#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00008283 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008284#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008285#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +00008286 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008287#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008288#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +00008289 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008290#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008291#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008292 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008293#endif
8294#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008295 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008296#endif
8297#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +00008298 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008299#endif
8300#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +00008301 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008302#endif
8303#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008304 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008305#endif
8306#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +00008307 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008308#endif
8309#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008310 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008311#endif
8312#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008313 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008314#endif
8315#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008316 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008317#endif
8318#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +00008319 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008320#endif
8321#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008322 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008323#endif
8324#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +00008325 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008326#endif
8327#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008328 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008329#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008330#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008331 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008332#endif
8333#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +00008334 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008335#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008336#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008337 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008338#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008339#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008340 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008341#endif
8342#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008343 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008344#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008345
Tim Peters5aa91602002-01-30 05:46:57 +00008346/* MS Windows */
8347#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008348 /* Don't inherit in child processes. */
8349 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008350#endif
8351#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +00008352 /* Optimize for short life (keep in memory). */
8353 /* MS forgot to define this one with a non-underscore form too. */
8354 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008355#endif
8356#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008357 /* Automatically delete when last handle is closed. */
8358 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008359#endif
8360#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +00008361 /* Optimize for random access. */
8362 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008363#endif
8364#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008365 /* Optimize for sequential access. */
8366 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008367#endif
8368
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008369/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008370#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008371 /* Send a SIGIO signal whenever input or output
8372 becomes available on file descriptor */
8373 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008374#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008375#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008376 /* Direct disk access. */
8377 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008378#endif
8379#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +00008380 /* Must be a directory. */
8381 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008382#endif
8383#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +00008384 /* Do not follow links. */
8385 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008386#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008387#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +00008388 /* Do not update the access time. */
8389 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008390#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008391
Victor Stinner8c62be82010-05-06 00:08:46 +00008392 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008393#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008394 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008395#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008396#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008397 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008398#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008399#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008400 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008401#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008402#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008403 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008404#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008405#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +00008406 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008407#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008408#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +00008409 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008410#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008411#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008412 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008413#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008414#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +00008415 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008416#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008417#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008418 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008419#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008420#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008421 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008422#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008423#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008424 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008425#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008426#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008427 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008428#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008429#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +00008430 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008431#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008432#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +00008433 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008434#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008435#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008436 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008437#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008438#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008439 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008440#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008441#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +00008442 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008443#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008444
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008445 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008446#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008447 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008448#endif /* ST_RDONLY */
8449#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008450 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008451#endif /* ST_NOSUID */
8452
Guido van Rossum246bc171999-02-01 23:54:31 +00008453#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008454#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00008455 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8456 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8457 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8458 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8459 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8460 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8461 if (ins(d, "P_PM", (long)P_PM)) return -1;
8462 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8463 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8464 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8465 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8466 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8467 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8468 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8469 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8470 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8471 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8472 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8473 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8474 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008475#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008476 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8477 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8478 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8479 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8480 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008481#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008482#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008483
Guido van Rossumd48f2521997-12-05 22:19:34 +00008484#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00008485 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008486#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008487 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00008488}
8489
8490
Tim Peters5aa91602002-01-30 05:46:57 +00008491#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008492#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008493#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008494
8495#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008496#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008497#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008498
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008499#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00008500#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008501#define MODNAME "posix"
8502#endif
8503
Martin v. Löwis1a214512008-06-11 05:26:20 +00008504static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +00008505 PyModuleDef_HEAD_INIT,
8506 MODNAME,
8507 posix__doc__,
8508 -1,
8509 posix_methods,
8510 NULL,
8511 NULL,
8512 NULL,
8513 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00008514};
8515
8516
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008517PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008518INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008519{
Victor Stinner8c62be82010-05-06 00:08:46 +00008520 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008521
Brian Curtin52173d42010-12-02 18:29:18 +00008522#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +00008523 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +00008524#endif
8525
Victor Stinner8c62be82010-05-06 00:08:46 +00008526 m = PyModule_Create(&posixmodule);
8527 if (m == NULL)
8528 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008529
Victor Stinner8c62be82010-05-06 00:08:46 +00008530 /* Initialize environ dictionary */
8531 v = convertenviron();
8532 Py_XINCREF(v);
8533 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
8534 return NULL;
8535 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008536
Victor Stinner8c62be82010-05-06 00:08:46 +00008537 if (all_ins(m))
8538 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00008539
Victor Stinner8c62be82010-05-06 00:08:46 +00008540 if (setup_confname_tables(m))
8541 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00008542
Victor Stinner8c62be82010-05-06 00:08:46 +00008543 Py_INCREF(PyExc_OSError);
8544 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008545
Guido van Rossumb3d39562000-01-31 18:41:26 +00008546#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00008547 if (posix_putenv_garbage == NULL)
8548 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008549#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008550
Victor Stinner8c62be82010-05-06 00:08:46 +00008551 if (!initialized) {
8552 stat_result_desc.name = MODNAME ".stat_result";
8553 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8554 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8555 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8556 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8557 structseq_new = StatResultType.tp_new;
8558 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008559
Victor Stinner8c62be82010-05-06 00:08:46 +00008560 statvfs_result_desc.name = MODNAME ".statvfs_result";
8561 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008562#ifdef NEED_TICKS_PER_SECOND
8563# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +00008564 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008565# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +00008566 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008567# else
Victor Stinner8c62be82010-05-06 00:08:46 +00008568 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008569# endif
8570#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008571 }
8572 Py_INCREF((PyObject*) &StatResultType);
8573 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
8574 Py_INCREF((PyObject*) &StatVFSResultType);
8575 PyModule_AddObject(m, "statvfs_result",
8576 (PyObject*) &StatVFSResultType);
8577 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008578
8579#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +00008580 /*
8581 * Step 2 of weak-linking support on Mac OS X.
8582 *
8583 * The code below removes functions that are not available on the
8584 * currently active platform.
8585 *
8586 * This block allow one to use a python binary that was build on
8587 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8588 * OSX 10.4.
8589 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008590#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008591 if (fstatvfs == NULL) {
8592 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8593 return NULL;
8594 }
8595 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008596#endif /* HAVE_FSTATVFS */
8597
8598#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008599 if (statvfs == NULL) {
8600 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8601 return NULL;
8602 }
8603 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008604#endif /* HAVE_STATVFS */
8605
8606# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00008607 if (lchown == NULL) {
8608 if (PyObject_DelAttrString(m, "lchown") == -1) {
8609 return NULL;
8610 }
8611 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008612#endif /* HAVE_LCHOWN */
8613
8614
8615#endif /* __APPLE__ */
Victor Stinner8c62be82010-05-06 00:08:46 +00008616 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008617
Guido van Rossumb6775db1994-08-01 11:34:53 +00008618}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008619
8620#ifdef __cplusplus
8621}
8622#endif