blob: 7267eca1bac0078e103607b425e20981ec985075 [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 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000280#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281
Guido van Rossumd48f2521997-12-05 22:19:34 +0000282#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000283#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000284#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000285
Tim Petersbc2e10e2002-03-03 23:17:02 +0000286#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000287#if defined(PATH_MAX) && PATH_MAX > 1024
288#define MAXPATHLEN PATH_MAX
289#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000290#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000291#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000292#endif /* MAXPATHLEN */
293
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000294#ifdef UNION_WAIT
295/* Emulate some macros on systems that have a union instead of macros */
296
297#ifndef WIFEXITED
298#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
299#endif
300
301#ifndef WEXITSTATUS
302#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
303#endif
304
305#ifndef WTERMSIG
306#define WTERMSIG(u_wait) ((u_wait).w_termsig)
307#endif
308
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000309#define WAIT_TYPE union wait
310#define WAIT_STATUS_INT(s) (s.w_status)
311
312#else /* !UNION_WAIT */
313#define WAIT_TYPE int
314#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000315#endif /* UNION_WAIT */
316
Greg Wardb48bc172000-03-01 21:51:56 +0000317/* Don't use the "_r" form if we don't need it (also, won't have a
318 prototype for it, at least on Solaris -- maybe others as well?). */
319#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
320#define USE_CTERMID_R
321#endif
322
Fred Drake699f3522000-06-29 21:12:41 +0000323/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000324#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000325#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000326# define STAT win32_stat
327# define FSTAT win32_fstat
328# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000329#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000330# define STAT stat
331# define FSTAT fstat
332# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000333#endif
334
Tim Peters11b23062003-04-23 02:39:17 +0000335#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000336#include <sys/mkdev.h>
337#else
338#if defined(MAJOR_IN_SYSMACROS)
339#include <sys/sysmacros.h>
340#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000341#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
342#include <sys/mkdev.h>
343#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000344#endif
Fred Drake699f3522000-06-29 21:12:41 +0000345
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000346#if defined _MSC_VER && _MSC_VER >= 1400
347/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
348 * valid and throw an assertion if it isn't.
349 * Normally, an invalid fd is likely to be a C program error and therefore
350 * an assertion can be useful, but it does contradict the POSIX standard
351 * which for write(2) states:
352 * "Otherwise, -1 shall be returned and errno set to indicate the error."
353 * "[EBADF] The fildes argument is not a valid file descriptor open for
354 * writing."
355 * Furthermore, python allows the user to enter any old integer
356 * as a fd and should merely raise a python exception on error.
357 * The Microsoft CRT doesn't provide an official way to check for the
358 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000359 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000360 * internal structures involved.
361 * The structures below must be updated for each version of visual studio
362 * according to the file internal.h in the CRT source, until MS comes
363 * up with a less hacky way to do this.
364 * (all of this is to avoid globally modifying the CRT behaviour using
365 * _set_invalid_parameter_handler() and _CrtSetReportMode())
366 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000367/* The actual size of the structure is determined at runtime.
368 * Only the first items must be present.
369 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000370typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000371 intptr_t osfhnd;
372 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000373} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000374
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000375extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000376#define IOINFO_L2E 5
377#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
378#define IOINFO_ARRAYS 64
379#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
380#define FOPEN 0x01
381#define _NO_CONSOLE_FILENO (intptr_t)-2
382
383/* This function emulates what the windows CRT does to validate file handles */
384int
385_PyVerify_fd(int fd)
386{
Victor Stinner8c62be82010-05-06 00:08:46 +0000387 const int i1 = fd >> IOINFO_L2E;
388 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000389
Antoine Pitrou22e41552010-08-15 18:07:50 +0000390 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000391
Victor Stinner8c62be82010-05-06 00:08:46 +0000392 /* Determine the actual size of the ioinfo structure,
393 * as used by the CRT loaded in memory
394 */
395 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
396 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
397 }
398 if (sizeof_ioinfo == 0) {
399 /* This should not happen... */
400 goto fail;
401 }
402
403 /* See that it isn't a special CLEAR fileno */
404 if (fd != _NO_CONSOLE_FILENO) {
405 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
406 * we check pointer validity and other info
407 */
408 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
409 /* finally, check that the file is open */
410 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
411 if (info->osfile & FOPEN) {
412 return 1;
413 }
414 }
415 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000416 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000417 errno = EBADF;
418 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000419}
420
421/* the special case of checking dup2. The target fd must be in a sensible range */
422static int
423_PyVerify_fd_dup2(int fd1, int fd2)
424{
Victor Stinner8c62be82010-05-06 00:08:46 +0000425 if (!_PyVerify_fd(fd1))
426 return 0;
427 if (fd2 == _NO_CONSOLE_FILENO)
428 return 0;
429 if ((unsigned)fd2 < _NHANDLE_)
430 return 1;
431 else
432 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000433}
434#else
435/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
436#define _PyVerify_fd_dup2(A, B) (1)
437#endif
438
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000439#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000440/* The following structure was copied from
441 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
442 include doesn't seem to be present in the Windows SDK (at least as included
443 with Visual Studio Express). */
444typedef struct _REPARSE_DATA_BUFFER {
445 ULONG ReparseTag;
446 USHORT ReparseDataLength;
447 USHORT Reserved;
448 union {
449 struct {
450 USHORT SubstituteNameOffset;
451 USHORT SubstituteNameLength;
452 USHORT PrintNameOffset;
453 USHORT PrintNameLength;
454 ULONG Flags;
455 WCHAR PathBuffer[1];
456 } SymbolicLinkReparseBuffer;
457
458 struct {
459 USHORT SubstituteNameOffset;
460 USHORT SubstituteNameLength;
461 USHORT PrintNameOffset;
462 USHORT PrintNameLength;
463 WCHAR PathBuffer[1];
464 } MountPointReparseBuffer;
465
466 struct {
467 UCHAR DataBuffer[1];
468 } GenericReparseBuffer;
469 };
470} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
471
472#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
473 GenericReparseBuffer)
474#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
475
476static int
477_Py_ReadLink(HANDLE reparse_point_handle, ULONG *reparse_tag, wchar_t **target_path)
478{
479 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
480 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
481 DWORD n_bytes_returned;
482 const wchar_t *ptr;
483 wchar_t *buf;
484 size_t len;
485
486 if (0 == DeviceIoControl(
487 reparse_point_handle,
488 FSCTL_GET_REPARSE_POINT,
489 NULL, 0, /* in buffer */
490 target_buffer, sizeof(target_buffer),
491 &n_bytes_returned,
492 NULL)) /* we're not using OVERLAPPED_IO */
493 return 0;
494
495 if (reparse_tag)
496 *reparse_tag = rdb->ReparseTag;
497
498 if (target_path) {
499 switch (rdb->ReparseTag) {
500 case IO_REPARSE_TAG_SYMLINK:
501 /* XXX: Maybe should use SubstituteName? */
502 ptr = rdb->SymbolicLinkReparseBuffer.PathBuffer +
503 rdb->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR);
504 len = rdb->SymbolicLinkReparseBuffer.PrintNameLength/sizeof(WCHAR);
505 break;
506 case IO_REPARSE_TAG_MOUNT_POINT:
507 ptr = rdb->MountPointReparseBuffer.PathBuffer +
508 rdb->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR);
509 len = rdb->MountPointReparseBuffer.SubstituteNameLength/sizeof(WCHAR);
510 break;
511 default:
512 SetLastError(ERROR_REPARSE_TAG_MISMATCH); /* XXX: Proper error code? */
513 return 0;
514 }
515 buf = (wchar_t *)malloc(sizeof(wchar_t)*(len+1));
516 if (!buf) {
517 SetLastError(ERROR_OUTOFMEMORY);
518 return 0;
519 }
520 wcsncpy(buf, ptr, len);
521 buf[len] = L'\0';
522 if (wcsncmp(buf, L"\\??\\", 4) == 0)
523 buf[1] = L'\\';
524 *target_path = buf;
525 }
526
527 return 1;
528}
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000529#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000530
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000531/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000532#ifdef WITH_NEXT_FRAMEWORK
533/* On Darwin/MacOSX a shared library or framework has no access to
534** environ directly, we must obtain it with _NSGetEnviron().
535*/
536#include <crt_externs.h>
537static char **environ;
538#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000539extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000540#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000541
Barry Warsaw53699e91996-12-10 23:23:01 +0000542static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000543convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000544{
Victor Stinner8c62be82010-05-06 00:08:46 +0000545 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000546#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000547 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000548#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000549 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000550#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000551#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000552 APIRET rc;
553 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
554#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000555
Victor Stinner8c62be82010-05-06 00:08:46 +0000556 d = PyDict_New();
557 if (d == NULL)
558 return NULL;
559#ifdef WITH_NEXT_FRAMEWORK
560 if (environ == NULL)
561 environ = *_NSGetEnviron();
562#endif
563#ifdef MS_WINDOWS
564 /* _wenviron must be initialized in this way if the program is started
565 through main() instead of wmain(). */
566 _wgetenv(L"");
567 if (_wenviron == NULL)
568 return d;
569 /* This part ignores errors */
570 for (e = _wenviron; *e != NULL; e++) {
571 PyObject *k;
572 PyObject *v;
573 wchar_t *p = wcschr(*e, L'=');
574 if (p == NULL)
575 continue;
576 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
577 if (k == NULL) {
578 PyErr_Clear();
579 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000580 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000581 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
582 if (v == NULL) {
583 PyErr_Clear();
584 Py_DECREF(k);
585 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000586 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000587 if (PyDict_GetItem(d, k) == NULL) {
588 if (PyDict_SetItem(d, k, v) != 0)
589 PyErr_Clear();
590 }
591 Py_DECREF(k);
592 Py_DECREF(v);
593 }
594#else
595 if (environ == NULL)
596 return d;
597 /* This part ignores errors */
598 for (e = environ; *e != NULL; e++) {
599 PyObject *k;
600 PyObject *v;
601 char *p = strchr(*e, '=');
602 if (p == NULL)
603 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000604 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000605 if (k == NULL) {
606 PyErr_Clear();
607 continue;
608 }
Victor Stinner84ae1182010-05-06 22:05:07 +0000609 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +0000610 if (v == NULL) {
611 PyErr_Clear();
612 Py_DECREF(k);
613 continue;
614 }
615 if (PyDict_GetItem(d, k) == NULL) {
616 if (PyDict_SetItem(d, k, v) != 0)
617 PyErr_Clear();
618 }
619 Py_DECREF(k);
620 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000621 }
622#endif
Victor Stinner8c62be82010-05-06 00:08:46 +0000623#if defined(PYOS_OS2)
624 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
625 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
626 PyObject *v = PyBytes_FromString(buffer);
627 PyDict_SetItemString(d, "BEGINLIBPATH", v);
628 Py_DECREF(v);
629 }
630 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
631 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
632 PyObject *v = PyBytes_FromString(buffer);
633 PyDict_SetItemString(d, "ENDLIBPATH", v);
634 Py_DECREF(v);
635 }
636#endif
637 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000638}
639
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000640/* Set a POSIX-specific error from errno, and return NULL */
641
Barry Warsawd58d7641998-07-23 16:14:40 +0000642static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000643posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000644{
Victor Stinner8c62be82010-05-06 00:08:46 +0000645 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000646}
Barry Warsawd58d7641998-07-23 16:14:40 +0000647static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000648posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000649{
Victor Stinner8c62be82010-05-06 00:08:46 +0000650 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000651}
652
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000653
Mark Hammondef8b6542001-05-13 08:04:26 +0000654static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000655posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000656{
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000657 PyObject *name_str, *rc;
658 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
659 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +0000660 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000661 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
662 name_str);
663 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +0000664 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000665}
666
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000667#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000668static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +0000669win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000670{
Victor Stinner8c62be82010-05-06 00:08:46 +0000671 /* XXX We should pass the function name along in the future.
672 (winreg.c also wants to pass the function name.)
673 This would however require an additional param to the
674 Windows error object, which is non-trivial.
675 */
676 errno = GetLastError();
677 if (filename)
678 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
679 else
680 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000681}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000682
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000683static PyObject *
684win32_error_unicode(char* function, Py_UNICODE* filename)
685{
Victor Stinner8c62be82010-05-06 00:08:46 +0000686 /* XXX - see win32_error for comments on 'function' */
687 errno = GetLastError();
688 if (filename)
689 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
690 else
691 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000692}
693
Thomas Wouters477c8d52006-05-27 19:21:47 +0000694static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000695convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000696{
Victor Stinner8c62be82010-05-06 00:08:46 +0000697 if (PyUnicode_CheckExact(*param))
698 Py_INCREF(*param);
699 else if (PyUnicode_Check(*param))
700 /* For a Unicode subtype that's not a Unicode object,
701 return a true Unicode object with the same data. */
702 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
703 PyUnicode_GET_SIZE(*param));
704 else
705 *param = PyUnicode_FromEncodedObject(*param,
706 Py_FileSystemDefaultEncoding,
707 "strict");
708 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000709}
710
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000711#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000712
Guido van Rossumd48f2521997-12-05 22:19:34 +0000713#if defined(PYOS_OS2)
714/**********************************************************************
715 * Helper Function to Trim and Format OS/2 Messages
716 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000717static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000718os2_formatmsg(char *msgbuf, int msglen, char *reason)
719{
720 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
721
722 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
723 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
724
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000725 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000726 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
727 }
728
729 /* Add Optional Reason Text */
730 if (reason) {
731 strcat(msgbuf, " : ");
732 strcat(msgbuf, reason);
733 }
734}
735
736/**********************************************************************
737 * Decode an OS/2 Operating System Error Code
738 *
739 * A convenience function to lookup an OS/2 error code and return a
740 * text message we can use to raise a Python exception.
741 *
742 * Notes:
743 * The messages for errors returned from the OS/2 kernel reside in
744 * the file OSO001.MSG in the \OS2 directory hierarchy.
745 *
746 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000747static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000748os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
749{
750 APIRET rc;
751 ULONG msglen;
752
753 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
754 Py_BEGIN_ALLOW_THREADS
755 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
756 errorcode, "oso001.msg", &msglen);
757 Py_END_ALLOW_THREADS
758
759 if (rc == NO_ERROR)
760 os2_formatmsg(msgbuf, msglen, reason);
761 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000762 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +0000763 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000764
765 return msgbuf;
766}
767
768/* Set an OS/2-specific error and return NULL. OS/2 kernel
769 errors are not in a global variable e.g. 'errno' nor are
770 they congruent with posix error numbers. */
771
Victor Stinner8c62be82010-05-06 00:08:46 +0000772static PyObject *
773os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000774{
775 char text[1024];
776 PyObject *v;
777
778 os2_strerror(text, sizeof(text), code, "");
779
780 v = Py_BuildValue("(is)", code, text);
781 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000782 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000783 Py_DECREF(v);
784 }
785 return NULL; /* Signal to Python that an Exception is Pending */
786}
787
788#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000789
790/* POSIX generic methods */
791
Barry Warsaw53699e91996-12-10 23:23:01 +0000792static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000793posix_fildes(PyObject *fdobj, int (*func)(int))
794{
Victor Stinner8c62be82010-05-06 00:08:46 +0000795 int fd;
796 int res;
797 fd = PyObject_AsFileDescriptor(fdobj);
798 if (fd < 0)
799 return NULL;
800 if (!_PyVerify_fd(fd))
801 return posix_error();
802 Py_BEGIN_ALLOW_THREADS
803 res = (*func)(fd);
804 Py_END_ALLOW_THREADS
805 if (res < 0)
806 return posix_error();
807 Py_INCREF(Py_None);
808 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000809}
Guido van Rossum21142a01999-01-08 21:05:37 +0000810
811static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000812posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000813{
Victor Stinner8c62be82010-05-06 00:08:46 +0000814 PyObject *opath1 = NULL;
815 char *path1;
816 int res;
817 if (!PyArg_ParseTuple(args, format,
818 PyUnicode_FSConverter, &opath1))
819 return NULL;
820 path1 = PyBytes_AsString(opath1);
821 Py_BEGIN_ALLOW_THREADS
822 res = (*func)(path1);
823 Py_END_ALLOW_THREADS
824 if (res < 0)
825 return posix_error_with_allocated_filename(opath1);
826 Py_DECREF(opath1);
827 Py_INCREF(Py_None);
828 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000829}
830
Barry Warsaw53699e91996-12-10 23:23:01 +0000831static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000832posix_2str(PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +0000833 char *format,
834 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000835{
Victor Stinner8c62be82010-05-06 00:08:46 +0000836 PyObject *opath1 = NULL, *opath2 = NULL;
837 char *path1, *path2;
838 int res;
839 if (!PyArg_ParseTuple(args, format,
840 PyUnicode_FSConverter, &opath1,
841 PyUnicode_FSConverter, &opath2)) {
842 return NULL;
843 }
844 path1 = PyBytes_AsString(opath1);
845 path2 = PyBytes_AsString(opath2);
846 Py_BEGIN_ALLOW_THREADS
847 res = (*func)(path1, path2);
848 Py_END_ALLOW_THREADS
849 Py_DECREF(opath1);
850 Py_DECREF(opath2);
851 if (res != 0)
852 /* XXX how to report both path1 and path2??? */
853 return posix_error();
854 Py_INCREF(Py_None);
855 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000856}
857
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000858#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000859static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +0000860win32_1str(PyObject* args, char* func,
861 char* format, BOOL (__stdcall *funcA)(LPCSTR),
862 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000863{
Victor Stinner8c62be82010-05-06 00:08:46 +0000864 PyObject *uni;
865 char *ansi;
866 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +0000867
Victor Stinner8c62be82010-05-06 00:08:46 +0000868 if (!PyArg_ParseTuple(args, wformat, &uni))
869 PyErr_Clear();
870 else {
871 Py_BEGIN_ALLOW_THREADS
872 result = funcW(PyUnicode_AsUnicode(uni));
873 Py_END_ALLOW_THREADS
874 if (!result)
875 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
876 Py_INCREF(Py_None);
877 return Py_None;
878 }
879 if (!PyArg_ParseTuple(args, format, &ansi))
880 return NULL;
881 Py_BEGIN_ALLOW_THREADS
882 result = funcA(ansi);
883 Py_END_ALLOW_THREADS
884 if (!result)
885 return win32_error(func, ansi);
886 Py_INCREF(Py_None);
887 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000888
889}
890
891/* This is a reimplementation of the C library's chdir function,
892 but one that produces Win32 errors instead of DOS error codes.
893 chdir is essentially a wrapper around SetCurrentDirectory; however,
894 it also needs to set "magic" environment variables indicating
895 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000896static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000897win32_chdir(LPCSTR path)
898{
Victor Stinner8c62be82010-05-06 00:08:46 +0000899 char new_path[MAX_PATH+1];
900 int result;
901 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000902
Victor Stinner8c62be82010-05-06 00:08:46 +0000903 if(!SetCurrentDirectoryA(path))
904 return FALSE;
905 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
906 if (!result)
907 return FALSE;
908 /* In the ANSI API, there should not be any paths longer
909 than MAX_PATH. */
910 assert(result <= MAX_PATH+1);
911 if (strncmp(new_path, "\\\\", 2) == 0 ||
912 strncmp(new_path, "//", 2) == 0)
913 /* UNC path, nothing to do. */
914 return TRUE;
915 env[1] = new_path[0];
916 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000917}
918
919/* The Unicode version differs from the ANSI version
920 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000921static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000922win32_wchdir(LPCWSTR path)
923{
Victor Stinner8c62be82010-05-06 00:08:46 +0000924 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
925 int result;
926 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000927
Victor Stinner8c62be82010-05-06 00:08:46 +0000928 if(!SetCurrentDirectoryW(path))
929 return FALSE;
930 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
931 if (!result)
932 return FALSE;
933 if (result > MAX_PATH+1) {
934 new_path = malloc(result * sizeof(wchar_t));
935 if (!new_path) {
936 SetLastError(ERROR_OUTOFMEMORY);
937 return FALSE;
938 }
939 result = GetCurrentDirectoryW(result, new_path);
940 if (!result) {
941 free(new_path);
942 return FALSE;
943 }
944 }
945 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
946 wcsncmp(new_path, L"//", 2) == 0)
947 /* UNC path, nothing to do. */
948 return TRUE;
949 env[1] = new_path[0];
950 result = SetEnvironmentVariableW(env, new_path);
951 if (new_path != _new_path)
952 free(new_path);
953 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000954}
955#endif
956
Martin v. Löwis14694662006-02-03 12:54:16 +0000957#ifdef MS_WINDOWS
958/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
959 - time stamps are restricted to second resolution
960 - file modification times suffer from forth-and-back conversions between
961 UTC and local time
962 Therefore, we implement our own stat, based on the Win32 API directly.
963*/
Victor Stinner8c62be82010-05-06 00:08:46 +0000964#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +0000965
966struct win32_stat{
967 int st_dev;
968 __int64 st_ino;
969 unsigned short st_mode;
970 int st_nlink;
971 int st_uid;
972 int st_gid;
973 int st_rdev;
974 __int64 st_size;
975 int st_atime;
976 int st_atime_nsec;
977 int st_mtime;
978 int st_mtime_nsec;
979 int st_ctime;
980 int st_ctime_nsec;
981};
982
983static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
984
985static void
986FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
987{
Victor Stinner8c62be82010-05-06 00:08:46 +0000988 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
989 /* Cannot simply cast and dereference in_ptr,
990 since it might not be aligned properly */
991 __int64 in;
992 memcpy(&in, in_ptr, sizeof(in));
993 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
994 /* XXX Win32 supports time stamps past 2038; we currently don't */
995 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
Martin v. Löwis14694662006-02-03 12:54:16 +0000996}
997
Thomas Wouters477c8d52006-05-27 19:21:47 +0000998static void
999time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
1000{
Victor Stinner8c62be82010-05-06 00:08:46 +00001001 /* XXX endianness */
1002 __int64 out;
1003 out = time_in + secs_between_epochs;
1004 out = out * 10000000 + nsec_in / 100;
1005 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001006}
1007
Martin v. Löwis14694662006-02-03 12:54:16 +00001008/* Below, we *know* that ugo+r is 0444 */
1009#if _S_IREAD != 0400
1010#error Unsupported C library
1011#endif
1012static int
1013attributes_to_mode(DWORD attr)
1014{
Victor Stinner8c62be82010-05-06 00:08:46 +00001015 int m = 0;
1016 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1017 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1018 else
1019 m |= _S_IFREG;
1020 if (attr & FILE_ATTRIBUTE_READONLY)
1021 m |= 0444;
1022 else
1023 m |= 0666;
1024 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001025}
1026
1027static int
Brian Curtinf5e76d02010-11-24 13:14:05 +00001028attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001029{
Victor Stinner8c62be82010-05-06 00:08:46 +00001030 memset(result, 0, sizeof(*result));
1031 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1032 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1033 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1034 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1035 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001036 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001037 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Martin v. Löwis14694662006-02-03 12:54:16 +00001038
Victor Stinner8c62be82010-05-06 00:08:46 +00001039 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001040}
1041
Guido van Rossumd8faa362007-04-27 19:54:29 +00001042static BOOL
Brian Curtinf5e76d02010-11-24 13:14:05 +00001043attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001044{
Victor Stinner8c62be82010-05-06 00:08:46 +00001045 HANDLE hFindFile;
1046 WIN32_FIND_DATAA FileData;
1047 hFindFile = FindFirstFileA(pszFile, &FileData);
1048 if (hFindFile == INVALID_HANDLE_VALUE)
1049 return FALSE;
1050 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001051 memset(info, 0, sizeof(*info));
1052 info->dwFileAttributes = FileData.dwFileAttributes;
1053 info->ftCreationTime = FileData.ftCreationTime;
1054 info->ftLastAccessTime = FileData.ftLastAccessTime;
1055 info->ftLastWriteTime = FileData.ftLastWriteTime;
1056 info->nFileSizeHigh = FileData.nFileSizeHigh;
1057 info->nFileSizeLow = FileData.nFileSizeLow;
1058/* info->nNumberOfLinks = 1; */
Victor Stinner8c62be82010-05-06 00:08:46 +00001059 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001060}
1061
1062static BOOL
Brian Curtinf5e76d02010-11-24 13:14:05 +00001063attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001064{
Victor Stinner8c62be82010-05-06 00:08:46 +00001065 HANDLE hFindFile;
1066 WIN32_FIND_DATAW FileData;
1067 hFindFile = FindFirstFileW(pszFile, &FileData);
1068 if (hFindFile == INVALID_HANDLE_VALUE)
1069 return FALSE;
1070 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001071 memset(info, 0, sizeof(*info));
1072 info->dwFileAttributes = FileData.dwFileAttributes;
1073 info->ftCreationTime = FileData.ftCreationTime;
1074 info->ftLastAccessTime = FileData.ftLastAccessTime;
1075 info->ftLastWriteTime = FileData.ftLastWriteTime;
1076 info->nFileSizeHigh = FileData.nFileSizeHigh;
1077 info->nFileSizeLow = FileData.nFileSizeLow;
1078/* info->nNumberOfLinks = 1; */
Victor Stinner8c62be82010-05-06 00:08:46 +00001079 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001080}
1081
Brian Curtinf5e76d02010-11-24 13:14:05 +00001082#ifndef SYMLOOP_MAX
1083#define SYMLOOP_MAX ( 88 )
1084#endif
1085
1086static int
1087win32_xstat_for_handle(HANDLE hFile, struct win32_stat *result, BOOL traverse, int depth);
1088
1089static int
1090win32_xstat(const char *path, struct win32_stat *result, BOOL traverse, int depth)
1091{
1092 int code;
1093 HANDLE hFile;
1094 BY_HANDLE_FILE_INFORMATION info;
1095 const char *dot;
1096
1097 hFile = CreateFileA(
1098 path,
1099 0, /* desired access */
1100 0, /* share mode */
1101 NULL, /* security attributes */
1102 OPEN_EXISTING,
1103 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
1104 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT,
1105 NULL);
1106
1107 if(hFile == INVALID_HANDLE_VALUE) {
1108 /* Either the target doesn't exist, or we don't have access to
1109 get a handle to it. If the former, we need to return an error.
1110 If the latter, we can use attributes_from_dir. */
1111 if (GetLastError() != ERROR_SHARING_VIOLATION)
1112 goto err;
1113 else {
1114 /* Could not get attributes on open file. Fall back to
1115 reading the directory. */
1116 if (!attributes_from_dir(path, &info))
1117 /* Very strange. This should not fail now */
1118 goto err;
1119 if (traverse && (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
1120 /* Should traverse, but cannot open reparse point handle */
1121 SetLastError(ERROR_SHARING_VIOLATION);
1122 goto err;
1123 }
1124 attribute_data_to_stat(&info, result);
1125 }
1126 }
1127 else {
1128 code = win32_xstat_for_handle(hFile, result, traverse, depth);
1129 CloseHandle(hFile);
1130 if (code != 0)
1131 return code;
1132 }
1133
1134 /* Set S_IEXEC if it is an .exe, .bat, ... */
1135 dot = strrchr(path, '.');
1136 if (dot) {
1137 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1138 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1139 result->st_mode |= 0111;
1140 }
1141 return 0;
1142
1143err:
1144 /* Protocol violation: we explicitly clear errno, instead of
1145 setting it to a POSIX error. Callers should use GetLastError. */
1146 errno = 0;
1147 return -1;
1148}
1149
1150static int
1151win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse, int depth)
1152{
1153 int code;
1154 HANDLE hFile;
1155 BY_HANDLE_FILE_INFORMATION info;
1156 const wchar_t *dot;
1157
1158 hFile = CreateFileW(
1159 path,
1160 0, /* desired access */
1161 0, /* share mode */
1162 NULL, /* security attributes */
1163 OPEN_EXISTING,
1164 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
1165 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT,
1166 NULL);
1167
1168 if(hFile == INVALID_HANDLE_VALUE) {
1169 /* Either the target doesn't exist, or we don't have access to
1170 get a handle to it. If the former, we need to return an error.
1171 If the latter, we can use attributes_from_dir. */
1172 if (GetLastError() != ERROR_SHARING_VIOLATION)
1173 goto err;
1174 else {
1175 /* Could not get attributes on open file. Fall back to
1176 reading the directory. */
1177 if (!attributes_from_dir_w(path, &info))
1178 /* Very strange. This should not fail now */
1179 goto err;
1180 if (traverse && (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
1181 /* Should traverse, but cannot open reparse point handle */
1182 SetLastError(ERROR_SHARING_VIOLATION);
1183 goto err;
1184 }
1185 attribute_data_to_stat(&info, result);
1186 }
1187 }
1188 else {
1189 code = win32_xstat_for_handle(hFile, result, traverse, depth);
1190 CloseHandle(hFile);
1191 if (code != 0)
1192 return code;
1193 }
1194
1195 /* Set S_IEXEC if it is an .exe, .bat, ... */
1196 dot = wcsrchr(path, '.');
1197 if (dot) {
1198 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1199 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1200 result->st_mode |= 0111;
1201 }
1202 return 0;
1203
1204err:
1205 /* Protocol violation: we explicitly clear errno, instead of
1206 setting it to a POSIX error. Callers should use GetLastError. */
1207 errno = 0;
1208 return -1;
1209}
1210
1211static int
1212win32_xstat_for_handle(HANDLE hFile, struct win32_stat *result, BOOL traverse, int depth)
1213{
1214 int code;
1215 BOOL reparse_tag;
1216 wchar_t *target_path;
1217 BY_HANDLE_FILE_INFORMATION info;
1218
1219 if (!GetFileInformationByHandle(hFile, &info))
1220 return -1;
1221
1222 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1223 if (traverse) {
1224 if (depth + 1 > SYMLOOP_MAX) {
1225 SetLastError(ERROR_CANT_RESOLVE_FILENAME); /* XXX: ELOOP? */
1226 return -1;
1227 }
1228 if (!_Py_ReadLink(hFile, NULL, &target_path))
1229 return -1;
1230 code = win32_xstat_w(target_path, result, traverse, depth + 1);
1231 free(target_path);
1232 return code;
1233 } else {
1234 if (!_Py_ReadLink(hFile, &reparse_tag, NULL))
1235 return -1;
1236 attribute_data_to_stat(&info, result);
1237 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1238 /* first clear the S_IFMT bits */
1239 result->st_mode ^= (result->st_mode & 0170000);
1240 /* now set the bits that make this a symlink */
1241 result->st_mode |= 0120000;
1242 }
1243 }
1244 } else {
1245 attribute_data_to_stat(&info, result);
1246 }
1247 return 0;
1248}
1249
Brian Curtind40e6f72010-07-08 21:39:08 +00001250/* About the following functions: win32_lstat, win32_lstat_w, win32_stat,
1251 win32_stat_w
1252
1253 In Posix, stat automatically traverses symlinks and returns the stat
1254 structure for the target. In Windows, the equivalent GetFileAttributes by
1255 default does not traverse symlinks and instead returns attributes for
1256 the symlink.
1257
1258 Therefore, win32_lstat will get the attributes traditionally, and
1259 win32_stat will first explicitly resolve the symlink target and then will
1260 call win32_lstat on that result.
1261
1262 The _w represent Unicode equivalents of the aformentioned ANSI functions. */
1263
1264static int
1265win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001266{
Brian Curtinf5e76d02010-11-24 13:14:05 +00001267 return win32_xstat(path, result, FALSE, 0);
Martin v. Löwis14694662006-02-03 12:54:16 +00001268}
1269
Victor Stinner8c62be82010-05-06 00:08:46 +00001270static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001271win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001272{
Brian Curtinf5e76d02010-11-24 13:14:05 +00001273 return win32_xstat_w(path, result, FALSE, 0);
Brian Curtind40e6f72010-07-08 21:39:08 +00001274}
1275
1276static int
1277win32_stat(const char* path, struct win32_stat *result)
1278{
Brian Curtinf5e76d02010-11-24 13:14:05 +00001279 return win32_xstat(path, result, TRUE, 0);
Brian Curtind40e6f72010-07-08 21:39:08 +00001280}
1281
1282static int
1283win32_stat_w(const wchar_t* path, struct win32_stat *result)
1284{
Brian Curtinf5e76d02010-11-24 13:14:05 +00001285 return win32_xstat_w(path, result, TRUE, 0);
Martin v. Löwis14694662006-02-03 12:54:16 +00001286}
1287
1288static int
1289win32_fstat(int file_number, struct win32_stat *result)
1290{
Victor Stinner8c62be82010-05-06 00:08:46 +00001291 BY_HANDLE_FILE_INFORMATION info;
1292 HANDLE h;
1293 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001294
Victor Stinner8c62be82010-05-06 00:08:46 +00001295 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001296
Victor Stinner8c62be82010-05-06 00:08:46 +00001297 /* Protocol violation: we explicitly clear errno, instead of
1298 setting it to a POSIX error. Callers should use GetLastError. */
1299 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001300
Victor Stinner8c62be82010-05-06 00:08:46 +00001301 if (h == INVALID_HANDLE_VALUE) {
1302 /* This is really a C library error (invalid file handle).
1303 We set the Win32 error to the closes one matching. */
1304 SetLastError(ERROR_INVALID_HANDLE);
1305 return -1;
1306 }
1307 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001308
Victor Stinner8c62be82010-05-06 00:08:46 +00001309 type = GetFileType(h);
1310 if (type == FILE_TYPE_UNKNOWN) {
1311 DWORD error = GetLastError();
1312 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001313 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001314 }
1315 /* else: valid but unknown file */
1316 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001317
Victor Stinner8c62be82010-05-06 00:08:46 +00001318 if (type != FILE_TYPE_DISK) {
1319 if (type == FILE_TYPE_CHAR)
1320 result->st_mode = _S_IFCHR;
1321 else if (type == FILE_TYPE_PIPE)
1322 result->st_mode = _S_IFIFO;
1323 return 0;
1324 }
1325
1326 if (!GetFileInformationByHandle(h, &info)) {
1327 return -1;
1328 }
1329
Brian Curtinf5e76d02010-11-24 13:14:05 +00001330 attribute_data_to_stat(&info, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001331 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001332 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1333 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001334}
1335
1336#endif /* MS_WINDOWS */
1337
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001338PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001339"stat_result: Result from stat or lstat.\n\n\
1340This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001341 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001342or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1343\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001344Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1345or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001346\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001347See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001348
1349static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001350 {"st_mode", "protection bits"},
1351 {"st_ino", "inode"},
1352 {"st_dev", "device"},
1353 {"st_nlink", "number of hard links"},
1354 {"st_uid", "user ID of owner"},
1355 {"st_gid", "group ID of owner"},
1356 {"st_size", "total size, in bytes"},
1357 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1358 {NULL, "integer time of last access"},
1359 {NULL, "integer time of last modification"},
1360 {NULL, "integer time of last change"},
1361 {"st_atime", "time of last access"},
1362 {"st_mtime", "time of last modification"},
1363 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001364#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001365 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001366#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001367#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001368 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001369#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001370#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001371 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001372#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001373#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001374 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001375#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001376#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001377 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001378#endif
1379#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001380 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001381#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001382 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001383};
1384
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001385#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001386#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001387#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001388#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001389#endif
1390
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001391#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001392#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1393#else
1394#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1395#endif
1396
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001397#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001398#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1399#else
1400#define ST_RDEV_IDX ST_BLOCKS_IDX
1401#endif
1402
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001403#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1404#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1405#else
1406#define ST_FLAGS_IDX ST_RDEV_IDX
1407#endif
1408
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001409#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001410#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001411#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001412#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001413#endif
1414
1415#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1416#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1417#else
1418#define ST_BIRTHTIME_IDX ST_GEN_IDX
1419#endif
1420
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001421static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001422 "stat_result", /* name */
1423 stat_result__doc__, /* doc */
1424 stat_result_fields,
1425 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001426};
1427
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001428PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001429"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1430This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001431 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001432or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001433\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001434See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001435
1436static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001437 {"f_bsize", },
1438 {"f_frsize", },
1439 {"f_blocks", },
1440 {"f_bfree", },
1441 {"f_bavail", },
1442 {"f_files", },
1443 {"f_ffree", },
1444 {"f_favail", },
1445 {"f_flag", },
1446 {"f_namemax",},
1447 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001448};
1449
1450static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001451 "statvfs_result", /* name */
1452 statvfs_result__doc__, /* doc */
1453 statvfs_result_fields,
1454 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001455};
1456
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001457static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001458static PyTypeObject StatResultType;
1459static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001460static newfunc structseq_new;
1461
1462static PyObject *
1463statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1464{
Victor Stinner8c62be82010-05-06 00:08:46 +00001465 PyStructSequence *result;
1466 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001467
Victor Stinner8c62be82010-05-06 00:08:46 +00001468 result = (PyStructSequence*)structseq_new(type, args, kwds);
1469 if (!result)
1470 return NULL;
1471 /* If we have been initialized from a tuple,
1472 st_?time might be set to None. Initialize it
1473 from the int slots. */
1474 for (i = 7; i <= 9; i++) {
1475 if (result->ob_item[i+3] == Py_None) {
1476 Py_DECREF(Py_None);
1477 Py_INCREF(result->ob_item[i]);
1478 result->ob_item[i+3] = result->ob_item[i];
1479 }
1480 }
1481 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001482}
1483
1484
1485
1486/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001487static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001488
1489PyDoc_STRVAR(stat_float_times__doc__,
1490"stat_float_times([newval]) -> oldval\n\n\
1491Determine whether os.[lf]stat represents time stamps as float objects.\n\
1492If newval is True, future calls to stat() return floats, if it is False,\n\
1493future calls return ints. \n\
1494If newval is omitted, return the current setting.\n");
1495
1496static PyObject*
1497stat_float_times(PyObject* self, PyObject *args)
1498{
Victor Stinner8c62be82010-05-06 00:08:46 +00001499 int newval = -1;
1500 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1501 return NULL;
1502 if (newval == -1)
1503 /* Return old value */
1504 return PyBool_FromLong(_stat_float_times);
1505 _stat_float_times = newval;
1506 Py_INCREF(Py_None);
1507 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001508}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001509
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001510static void
1511fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1512{
Victor Stinner8c62be82010-05-06 00:08:46 +00001513 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001514#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner8c62be82010-05-06 00:08:46 +00001515 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001516#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001517 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001518#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001519 if (!ival)
1520 return;
1521 if (_stat_float_times) {
1522 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1523 } else {
1524 fval = ival;
1525 Py_INCREF(fval);
1526 }
1527 PyStructSequence_SET_ITEM(v, index, ival);
1528 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001529}
1530
Tim Peters5aa91602002-01-30 05:46:57 +00001531/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001532 (used by posix_stat() and posix_fstat()) */
1533static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001534_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001535{
Victor Stinner8c62be82010-05-06 00:08:46 +00001536 unsigned long ansec, mnsec, cnsec;
1537 PyObject *v = PyStructSequence_New(&StatResultType);
1538 if (v == NULL)
1539 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001540
Victor Stinner8c62be82010-05-06 00:08:46 +00001541 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001542#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001543 PyStructSequence_SET_ITEM(v, 1,
1544 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001545#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001546 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001547#endif
1548#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001549 PyStructSequence_SET_ITEM(v, 2,
1550 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001551#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001552 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001553#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001554 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1555 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1556 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001557#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001558 PyStructSequence_SET_ITEM(v, 6,
1559 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001560#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001561 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001562#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001563
Martin v. Löwis14694662006-02-03 12:54:16 +00001564#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001565 ansec = st->st_atim.tv_nsec;
1566 mnsec = st->st_mtim.tv_nsec;
1567 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001568#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001569 ansec = st->st_atimespec.tv_nsec;
1570 mnsec = st->st_mtimespec.tv_nsec;
1571 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001572#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001573 ansec = st->st_atime_nsec;
1574 mnsec = st->st_mtime_nsec;
1575 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001576#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001577 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001578#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001579 fill_time(v, 7, st->st_atime, ansec);
1580 fill_time(v, 8, st->st_mtime, mnsec);
1581 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001582
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001583#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001584 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1585 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001586#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001587#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001588 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1589 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001590#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001591#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001592 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1593 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001594#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001595#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001596 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1597 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001598#endif
1599#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001600 {
1601 PyObject *val;
1602 unsigned long bsec,bnsec;
1603 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001604#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner8c62be82010-05-06 00:08:46 +00001605 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001606#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001607 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001608#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001609 if (_stat_float_times) {
1610 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1611 } else {
1612 val = PyLong_FromLong((long)bsec);
1613 }
1614 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1615 val);
1616 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001617#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001618#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001619 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1620 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001621#endif
Fred Drake699f3522000-06-29 21:12:41 +00001622
Victor Stinner8c62be82010-05-06 00:08:46 +00001623 if (PyErr_Occurred()) {
1624 Py_DECREF(v);
1625 return NULL;
1626 }
Fred Drake699f3522000-06-29 21:12:41 +00001627
Victor Stinner8c62be82010-05-06 00:08:46 +00001628 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001629}
1630
Barry Warsaw53699e91996-12-10 23:23:01 +00001631static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001632posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +00001633 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001634#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00001635 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001636#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001637 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001638#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001639 char *wformat,
1640 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001641{
Victor Stinner8c62be82010-05-06 00:08:46 +00001642 STRUCT_STAT st;
1643 PyObject *opath;
1644 char *path;
1645 int res;
1646 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001647
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001648#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001649 PyUnicodeObject *po;
1650 if (PyArg_ParseTuple(args, wformat, &po)) {
1651 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001652
Victor Stinner8c62be82010-05-06 00:08:46 +00001653 Py_BEGIN_ALLOW_THREADS
1654 /* PyUnicode_AS_UNICODE result OK without
1655 thread lock as it is a simple dereference. */
1656 res = wstatfunc(wpath, &st);
1657 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001658
Victor Stinner8c62be82010-05-06 00:08:46 +00001659 if (res != 0)
1660 return win32_error_unicode("stat", wpath);
1661 return _pystat_fromstructstat(&st);
1662 }
1663 /* Drop the argument parsing error as narrow strings
1664 are also valid. */
1665 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001666#endif
1667
Victor Stinner8c62be82010-05-06 00:08:46 +00001668 if (!PyArg_ParseTuple(args, format,
1669 PyUnicode_FSConverter, &opath))
1670 return NULL;
1671 path = PyBytes_AsString(opath);
1672 Py_BEGIN_ALLOW_THREADS
1673 res = (*statfunc)(path, &st);
1674 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001675
Victor Stinner8c62be82010-05-06 00:08:46 +00001676 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001677#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001678 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001679#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001680 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001681#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001682 }
1683 else
1684 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001685
Victor Stinner8c62be82010-05-06 00:08:46 +00001686 Py_DECREF(opath);
1687 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001688}
1689
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001690/* POSIX methods */
1691
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001692PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001693"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001694Use the real uid/gid to test for access to a path. Note that most\n\
1695operations will use the effective uid/gid, therefore this routine can\n\
1696be used in a suid/sgid environment to test if the invoking user has the\n\
1697specified access to the path. The mode argument can be F_OK to test\n\
1698existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001699
1700static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001701posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001702{
Victor Stinner8c62be82010-05-06 00:08:46 +00001703 PyObject *opath;
1704 char *path;
1705 int mode;
1706
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001707#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001708 DWORD attr;
1709 PyUnicodeObject *po;
1710 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1711 Py_BEGIN_ALLOW_THREADS
1712 /* PyUnicode_AS_UNICODE OK without thread lock as
1713 it is a simple dereference. */
1714 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1715 Py_END_ALLOW_THREADS
1716 goto finish;
1717 }
1718 /* Drop the argument parsing error as narrow strings
1719 are also valid. */
1720 PyErr_Clear();
1721 if (!PyArg_ParseTuple(args, "O&i:access",
1722 PyUnicode_FSConverter, &opath, &mode))
1723 return NULL;
1724 path = PyBytes_AsString(opath);
1725 Py_BEGIN_ALLOW_THREADS
1726 attr = GetFileAttributesA(path);
1727 Py_END_ALLOW_THREADS
1728 Py_DECREF(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001729finish:
Victor Stinner8c62be82010-05-06 00:08:46 +00001730 if (attr == 0xFFFFFFFF)
1731 /* File does not exist, or cannot read attributes */
1732 return PyBool_FromLong(0);
1733 /* Access is possible if either write access wasn't requested, or
1734 the file isn't read-only, or if it's a directory, as there are
1735 no read-only directories on Windows. */
1736 return PyBool_FromLong(!(mode & 2)
1737 || !(attr & FILE_ATTRIBUTE_READONLY)
1738 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001739#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001740 int res;
1741 if (!PyArg_ParseTuple(args, "O&i:access",
1742 PyUnicode_FSConverter, &opath, &mode))
1743 return NULL;
1744 path = PyBytes_AsString(opath);
1745 Py_BEGIN_ALLOW_THREADS
1746 res = access(path, mode);
1747 Py_END_ALLOW_THREADS
1748 Py_DECREF(opath);
1749 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001750#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001751}
1752
Guido van Rossumd371ff11999-01-25 16:12:23 +00001753#ifndef F_OK
1754#define F_OK 0
1755#endif
1756#ifndef R_OK
1757#define R_OK 4
1758#endif
1759#ifndef W_OK
1760#define W_OK 2
1761#endif
1762#ifndef X_OK
1763#define X_OK 1
1764#endif
1765
1766#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001767PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001768"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001769Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001770
1771static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001772posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001773{
Victor Stinner8c62be82010-05-06 00:08:46 +00001774 int id;
1775 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001776
Victor Stinner8c62be82010-05-06 00:08:46 +00001777 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1778 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001779
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001780#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001781 /* file descriptor 0 only, the default input device (stdin) */
1782 if (id == 0) {
1783 ret = ttyname();
1784 }
1785 else {
1786 ret = NULL;
1787 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001788#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001789 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001790#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001791 if (ret == NULL)
1792 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001793 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001794}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001795#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001796
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001797#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001798PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001799"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001800Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001801
1802static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001803posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001804{
Victor Stinner8c62be82010-05-06 00:08:46 +00001805 char *ret;
1806 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001807
Greg Wardb48bc172000-03-01 21:51:56 +00001808#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00001809 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001810#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001811 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001812#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001813 if (ret == NULL)
1814 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001815 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001816}
1817#endif
1818
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001819PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001820"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001821Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001822
Barry Warsaw53699e91996-12-10 23:23:01 +00001823static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001824posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001825{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001826#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001827 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001828#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001829 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001830#elif defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001831 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001832#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001833 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001834#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001835}
1836
Fred Drake4d1e64b2002-04-15 19:40:07 +00001837#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001838PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001839"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001840Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001841opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001842
1843static PyObject *
1844posix_fchdir(PyObject *self, PyObject *fdobj)
1845{
Victor Stinner8c62be82010-05-06 00:08:46 +00001846 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001847}
1848#endif /* HAVE_FCHDIR */
1849
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001850
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001851PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001852"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001853Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001854
Barry Warsaw53699e91996-12-10 23:23:01 +00001855static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001856posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001857{
Victor Stinner8c62be82010-05-06 00:08:46 +00001858 PyObject *opath = NULL;
1859 char *path = NULL;
1860 int i;
1861 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001862#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001863 DWORD attr;
1864 PyUnicodeObject *po;
1865 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1866 Py_BEGIN_ALLOW_THREADS
1867 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1868 if (attr != 0xFFFFFFFF) {
1869 if (i & _S_IWRITE)
1870 attr &= ~FILE_ATTRIBUTE_READONLY;
1871 else
1872 attr |= FILE_ATTRIBUTE_READONLY;
1873 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1874 }
1875 else
1876 res = 0;
1877 Py_END_ALLOW_THREADS
1878 if (!res)
1879 return win32_error_unicode("chmod",
1880 PyUnicode_AS_UNICODE(po));
1881 Py_INCREF(Py_None);
1882 return Py_None;
1883 }
1884 /* Drop the argument parsing error as narrow strings
1885 are also valid. */
1886 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001887
Victor Stinner8c62be82010-05-06 00:08:46 +00001888 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1889 &opath, &i))
1890 return NULL;
1891 path = PyBytes_AsString(opath);
1892 Py_BEGIN_ALLOW_THREADS
1893 attr = GetFileAttributesA(path);
1894 if (attr != 0xFFFFFFFF) {
1895 if (i & _S_IWRITE)
1896 attr &= ~FILE_ATTRIBUTE_READONLY;
1897 else
1898 attr |= FILE_ATTRIBUTE_READONLY;
1899 res = SetFileAttributesA(path, attr);
1900 }
1901 else
1902 res = 0;
1903 Py_END_ALLOW_THREADS
1904 if (!res) {
1905 win32_error("chmod", path);
1906 Py_DECREF(opath);
1907 return NULL;
1908 }
1909 Py_DECREF(opath);
1910 Py_INCREF(Py_None);
1911 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001912#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00001913 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1914 &opath, &i))
1915 return NULL;
1916 path = PyBytes_AsString(opath);
1917 Py_BEGIN_ALLOW_THREADS
1918 res = chmod(path, i);
1919 Py_END_ALLOW_THREADS
1920 if (res < 0)
1921 return posix_error_with_allocated_filename(opath);
1922 Py_DECREF(opath);
1923 Py_INCREF(Py_None);
1924 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001925#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001926}
1927
Christian Heimes4e30a842007-11-30 22:12:06 +00001928#ifdef HAVE_FCHMOD
1929PyDoc_STRVAR(posix_fchmod__doc__,
1930"fchmod(fd, mode)\n\n\
1931Change the access permissions of the file given by file\n\
1932descriptor fd.");
1933
1934static PyObject *
1935posix_fchmod(PyObject *self, PyObject *args)
1936{
Victor Stinner8c62be82010-05-06 00:08:46 +00001937 int fd, mode, res;
1938 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1939 return NULL;
1940 Py_BEGIN_ALLOW_THREADS
1941 res = fchmod(fd, mode);
1942 Py_END_ALLOW_THREADS
1943 if (res < 0)
1944 return posix_error();
1945 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001946}
1947#endif /* HAVE_FCHMOD */
1948
1949#ifdef HAVE_LCHMOD
1950PyDoc_STRVAR(posix_lchmod__doc__,
1951"lchmod(path, mode)\n\n\
1952Change the access permissions of a file. If path is a symlink, this\n\
1953affects the link itself rather than the target.");
1954
1955static PyObject *
1956posix_lchmod(PyObject *self, PyObject *args)
1957{
Victor Stinner8c62be82010-05-06 00:08:46 +00001958 PyObject *opath;
1959 char *path;
1960 int i;
1961 int res;
1962 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
1963 &opath, &i))
1964 return NULL;
1965 path = PyBytes_AsString(opath);
1966 Py_BEGIN_ALLOW_THREADS
1967 res = lchmod(path, i);
1968 Py_END_ALLOW_THREADS
1969 if (res < 0)
1970 return posix_error_with_allocated_filename(opath);
1971 Py_DECREF(opath);
1972 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001973}
1974#endif /* HAVE_LCHMOD */
1975
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001976
Thomas Wouterscf297e42007-02-23 15:07:44 +00001977#ifdef HAVE_CHFLAGS
1978PyDoc_STRVAR(posix_chflags__doc__,
1979"chflags(path, flags)\n\n\
1980Set file flags.");
1981
1982static PyObject *
1983posix_chflags(PyObject *self, PyObject *args)
1984{
Victor Stinner8c62be82010-05-06 00:08:46 +00001985 PyObject *opath;
1986 char *path;
1987 unsigned long flags;
1988 int res;
1989 if (!PyArg_ParseTuple(args, "O&k:chflags",
1990 PyUnicode_FSConverter, &opath, &flags))
1991 return NULL;
1992 path = PyBytes_AsString(opath);
1993 Py_BEGIN_ALLOW_THREADS
1994 res = chflags(path, flags);
1995 Py_END_ALLOW_THREADS
1996 if (res < 0)
1997 return posix_error_with_allocated_filename(opath);
1998 Py_DECREF(opath);
1999 Py_INCREF(Py_None);
2000 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002001}
2002#endif /* HAVE_CHFLAGS */
2003
2004#ifdef HAVE_LCHFLAGS
2005PyDoc_STRVAR(posix_lchflags__doc__,
2006"lchflags(path, flags)\n\n\
2007Set file flags.\n\
2008This function will not follow symbolic links.");
2009
2010static PyObject *
2011posix_lchflags(PyObject *self, PyObject *args)
2012{
Victor Stinner8c62be82010-05-06 00:08:46 +00002013 PyObject *opath;
2014 char *path;
2015 unsigned long flags;
2016 int res;
2017 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2018 PyUnicode_FSConverter, &opath, &flags))
2019 return NULL;
2020 path = PyBytes_AsString(opath);
2021 Py_BEGIN_ALLOW_THREADS
2022 res = lchflags(path, flags);
2023 Py_END_ALLOW_THREADS
2024 if (res < 0)
2025 return posix_error_with_allocated_filename(opath);
2026 Py_DECREF(opath);
2027 Py_INCREF(Py_None);
2028 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002029}
2030#endif /* HAVE_LCHFLAGS */
2031
Martin v. Löwis244edc82001-10-04 22:44:26 +00002032#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002033PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002034"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002035Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002036
2037static PyObject *
2038posix_chroot(PyObject *self, PyObject *args)
2039{
Victor Stinner8c62be82010-05-06 00:08:46 +00002040 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002041}
2042#endif
2043
Guido van Rossum21142a01999-01-08 21:05:37 +00002044#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002045PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002046"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002047force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002048
2049static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002050posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002051{
Stefan Krah0e803b32010-11-26 16:16:47 +00002052 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002053}
2054#endif /* HAVE_FSYNC */
2055
2056#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002057
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002058#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002059extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2060#endif
2061
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002062PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002063"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002064force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002065 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002066
2067static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002068posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002069{
Stefan Krah0e803b32010-11-26 16:16:47 +00002070 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002071}
2072#endif /* HAVE_FDATASYNC */
2073
2074
Fredrik Lundh10723342000-07-10 16:38:09 +00002075#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002076PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002077"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002078Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002079
Barry Warsaw53699e91996-12-10 23:23:01 +00002080static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002081posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002082{
Victor Stinner8c62be82010-05-06 00:08:46 +00002083 PyObject *opath;
2084 char *path;
2085 long uid, gid;
2086 int res;
2087 if (!PyArg_ParseTuple(args, "O&ll:chown",
2088 PyUnicode_FSConverter, &opath,
2089 &uid, &gid))
2090 return NULL;
2091 path = PyBytes_AsString(opath);
2092 Py_BEGIN_ALLOW_THREADS
2093 res = chown(path, (uid_t) uid, (gid_t) gid);
2094 Py_END_ALLOW_THREADS
2095 if (res < 0)
2096 return posix_error_with_allocated_filename(opath);
2097 Py_DECREF(opath);
2098 Py_INCREF(Py_None);
2099 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002100}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002101#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002102
Christian Heimes4e30a842007-11-30 22:12:06 +00002103#ifdef HAVE_FCHOWN
2104PyDoc_STRVAR(posix_fchown__doc__,
2105"fchown(fd, uid, gid)\n\n\
2106Change the owner and group id of the file given by file descriptor\n\
2107fd to the numeric uid and gid.");
2108
2109static PyObject *
2110posix_fchown(PyObject *self, PyObject *args)
2111{
Victor Stinner8c62be82010-05-06 00:08:46 +00002112 int fd;
2113 long uid, gid;
2114 int res;
2115 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
2116 return NULL;
2117 Py_BEGIN_ALLOW_THREADS
2118 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2119 Py_END_ALLOW_THREADS
2120 if (res < 0)
2121 return posix_error();
2122 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002123}
2124#endif /* HAVE_FCHOWN */
2125
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002126#ifdef HAVE_LCHOWN
2127PyDoc_STRVAR(posix_lchown__doc__,
2128"lchown(path, uid, gid)\n\n\
2129Change the owner and group id of path to the numeric uid and gid.\n\
2130This function will not follow symbolic links.");
2131
2132static PyObject *
2133posix_lchown(PyObject *self, PyObject *args)
2134{
Victor Stinner8c62be82010-05-06 00:08:46 +00002135 PyObject *opath;
2136 char *path;
2137 long uid, gid;
2138 int res;
2139 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2140 PyUnicode_FSConverter, &opath,
2141 &uid, &gid))
2142 return NULL;
2143 path = PyBytes_AsString(opath);
2144 Py_BEGIN_ALLOW_THREADS
2145 res = lchown(path, (uid_t) uid, (gid_t) gid);
2146 Py_END_ALLOW_THREADS
2147 if (res < 0)
2148 return posix_error_with_allocated_filename(opath);
2149 Py_DECREF(opath);
2150 Py_INCREF(Py_None);
2151 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002152}
2153#endif /* HAVE_LCHOWN */
2154
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002155
Guido van Rossum36bc6801995-06-14 22:54:23 +00002156#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002157static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002158posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002159{
Victor Stinner8c62be82010-05-06 00:08:46 +00002160 char buf[1026];
2161 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002162
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002163#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002164 if (!use_bytes) {
2165 wchar_t wbuf[1026];
2166 wchar_t *wbuf2 = wbuf;
2167 PyObject *resobj;
2168 DWORD len;
2169 Py_BEGIN_ALLOW_THREADS
2170 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2171 /* If the buffer is large enough, len does not include the
2172 terminating \0. If the buffer is too small, len includes
2173 the space needed for the terminator. */
2174 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2175 wbuf2 = malloc(len * sizeof(wchar_t));
2176 if (wbuf2)
2177 len = GetCurrentDirectoryW(len, wbuf2);
2178 }
2179 Py_END_ALLOW_THREADS
2180 if (!wbuf2) {
2181 PyErr_NoMemory();
2182 return NULL;
2183 }
2184 if (!len) {
2185 if (wbuf2 != wbuf) free(wbuf2);
2186 return win32_error("getcwdu", NULL);
2187 }
2188 resobj = PyUnicode_FromWideChar(wbuf2, len);
2189 if (wbuf2 != wbuf) free(wbuf2);
2190 return resobj;
2191 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002192#endif
2193
Victor Stinner8c62be82010-05-06 00:08:46 +00002194 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002195#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002196 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002197#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002198 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002199#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002200 Py_END_ALLOW_THREADS
2201 if (res == NULL)
2202 return posix_error();
2203 if (use_bytes)
2204 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002205 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002206}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002207
2208PyDoc_STRVAR(posix_getcwd__doc__,
2209"getcwd() -> path\n\n\
2210Return a unicode string representing the current working directory.");
2211
2212static PyObject *
2213posix_getcwd_unicode(PyObject *self)
2214{
2215 return posix_getcwd(0);
2216}
2217
2218PyDoc_STRVAR(posix_getcwdb__doc__,
2219"getcwdb() -> path\n\n\
2220Return a bytes string representing the current working directory.");
2221
2222static PyObject *
2223posix_getcwd_bytes(PyObject *self)
2224{
2225 return posix_getcwd(1);
2226}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002227#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002228
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002229
Guido van Rossumb6775db1994-08-01 11:34:53 +00002230#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002231PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002232"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002233Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002234
Barry Warsaw53699e91996-12-10 23:23:01 +00002235static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002236posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002237{
Victor Stinner8c62be82010-05-06 00:08:46 +00002238 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002239}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002240#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002241
Brian Curtin1b9df392010-11-24 20:24:31 +00002242#ifdef MS_WINDOWS
2243PyDoc_STRVAR(win32_link__doc__,
2244"link(src, dst)\n\n\
2245Create a hard link to a file.");
2246
2247static PyObject *
2248win32_link(PyObject *self, PyObject *args)
2249{
2250 PyObject *osrc, *odst;
2251 char *src, *dst;
2252 BOOL rslt;
2253
Brian Curtinfc889c42010-11-28 23:59:46 +00002254 PyUnicodeObject *usrc, *udst;
2255 if (PyArg_ParseTuple(args, "UU:link", &usrc, &udst)) {
2256 Py_BEGIN_ALLOW_THREADS
2257 rslt = CreateHardLinkW(PyUnicode_AS_UNICODE(udst),
2258 PyUnicode_AS_UNICODE(usrc), NULL);
2259 Py_END_ALLOW_THREADS
2260
2261 if (rslt == 0)
2262 return win32_error("link", NULL);
2263
2264 Py_RETURN_NONE;
2265 }
2266
2267 /* Narrow strings also valid. */
2268 PyErr_Clear();
2269
Brian Curtin1b9df392010-11-24 20:24:31 +00002270 if (!PyArg_ParseTuple(args, "O&O&:link", PyUnicode_FSConverter, &osrc,
2271 PyUnicode_FSConverter, &odst))
2272 return NULL;
2273
2274 src = PyBytes_AsString(osrc);
2275 dst = PyBytes_AsString(odst);
2276
2277 Py_BEGIN_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00002278 rslt = CreateHardLinkA(dst, src, NULL);
Brian Curtin1b9df392010-11-24 20:24:31 +00002279 Py_END_ALLOW_THREADS
2280
Stefan Krah30b341f2010-11-27 11:44:18 +00002281 Py_DECREF(osrc);
2282 Py_DECREF(odst);
Brian Curtin1b9df392010-11-24 20:24:31 +00002283 if (rslt == 0)
Brian Curtinfc889c42010-11-28 23:59:46 +00002284 return win32_error("link", NULL);
Brian Curtin1b9df392010-11-24 20:24:31 +00002285
2286 Py_RETURN_NONE;
2287}
2288#endif /* MS_WINDOWS */
2289
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002290
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002291PyDoc_STRVAR(posix_listdir__doc__,
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002292"listdir([path]) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002293Return a list containing the names of the entries in the directory.\n\
2294\n\
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002295 path: path of directory to list (default: '.')\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002296\n\
2297The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002298entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002299
Barry Warsaw53699e91996-12-10 23:23:01 +00002300static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002301posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002302{
Victor Stinner8c62be82010-05-06 00:08:46 +00002303 /* XXX Should redo this putting the (now four) versions of opendir
2304 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002305#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002306
Victor Stinner8c62be82010-05-06 00:08:46 +00002307 PyObject *d, *v;
2308 HANDLE hFindFile;
2309 BOOL result;
2310 WIN32_FIND_DATA FileData;
2311 PyObject *opath;
2312 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2313 char *bufptr = namebuf;
2314 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002315
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002316 PyObject *po = NULL;
2317 if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002318 WIN32_FIND_DATAW wFileData;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002319 Py_UNICODE *wnamebuf, *po_wchars;
2320
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002321 if (po == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002322 po_wchars = L".";
2323 len = 1;
2324 } else {
2325 po_wchars = PyUnicode_AS_UNICODE(po);
2326 len = PyUnicode_GET_SIZE(po);
2327 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002328 /* Overallocate for \\*.*\0 */
Victor Stinner8c62be82010-05-06 00:08:46 +00002329 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2330 if (!wnamebuf) {
2331 PyErr_NoMemory();
2332 return NULL;
2333 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002334 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00002335 if (len > 0) {
2336 Py_UNICODE wch = wnamebuf[len-1];
2337 if (wch != L'/' && wch != L'\\' && wch != L':')
2338 wnamebuf[len++] = L'\\';
2339 wcscpy(wnamebuf + len, L"*.*");
2340 }
2341 if ((d = PyList_New(0)) == NULL) {
2342 free(wnamebuf);
2343 return NULL;
2344 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00002345 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002346 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002347 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002348 if (hFindFile == INVALID_HANDLE_VALUE) {
2349 int error = GetLastError();
2350 if (error == ERROR_FILE_NOT_FOUND) {
2351 free(wnamebuf);
2352 return d;
2353 }
2354 Py_DECREF(d);
2355 win32_error_unicode("FindFirstFileW", wnamebuf);
2356 free(wnamebuf);
2357 return NULL;
2358 }
2359 do {
2360 /* Skip over . and .. */
2361 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2362 wcscmp(wFileData.cFileName, L"..") != 0) {
2363 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2364 if (v == NULL) {
2365 Py_DECREF(d);
2366 d = NULL;
2367 break;
2368 }
2369 if (PyList_Append(d, v) != 0) {
2370 Py_DECREF(v);
2371 Py_DECREF(d);
2372 d = NULL;
2373 break;
2374 }
2375 Py_DECREF(v);
2376 }
2377 Py_BEGIN_ALLOW_THREADS
2378 result = FindNextFileW(hFindFile, &wFileData);
2379 Py_END_ALLOW_THREADS
2380 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2381 it got to the end of the directory. */
2382 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2383 Py_DECREF(d);
2384 win32_error_unicode("FindNextFileW", wnamebuf);
2385 FindClose(hFindFile);
2386 free(wnamebuf);
2387 return NULL;
2388 }
2389 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002390
Victor Stinner8c62be82010-05-06 00:08:46 +00002391 if (FindClose(hFindFile) == FALSE) {
2392 Py_DECREF(d);
2393 win32_error_unicode("FindClose", wnamebuf);
2394 free(wnamebuf);
2395 return NULL;
2396 }
2397 free(wnamebuf);
2398 return d;
2399 }
2400 /* Drop the argument parsing error as narrow strings
2401 are also valid. */
2402 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002403
Victor Stinner8c62be82010-05-06 00:08:46 +00002404 if (!PyArg_ParseTuple(args, "O&:listdir",
2405 PyUnicode_FSConverter, &opath))
2406 return NULL;
2407 if (PyBytes_GET_SIZE(opath)+1 > MAX_PATH) {
2408 PyErr_SetString(PyExc_ValueError, "path too long");
2409 Py_DECREF(opath);
2410 return NULL;
2411 }
2412 strcpy(namebuf, PyBytes_AsString(opath));
2413 len = PyObject_Size(opath);
Stefan Krah2a7feee2010-11-27 22:06:49 +00002414 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00002415 if (len > 0) {
2416 char ch = namebuf[len-1];
2417 if (ch != SEP && ch != ALTSEP && ch != ':')
2418 namebuf[len++] = '/';
2419 strcpy(namebuf + len, "*.*");
2420 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002421
Victor Stinner8c62be82010-05-06 00:08:46 +00002422 if ((d = PyList_New(0)) == NULL)
2423 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002424
Antoine Pitroub73caab2010-08-09 23:39:31 +00002425 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002426 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002427 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002428 if (hFindFile == INVALID_HANDLE_VALUE) {
2429 int error = GetLastError();
2430 if (error == ERROR_FILE_NOT_FOUND)
2431 return d;
2432 Py_DECREF(d);
2433 return win32_error("FindFirstFile", namebuf);
2434 }
2435 do {
2436 /* Skip over . and .. */
2437 if (strcmp(FileData.cFileName, ".") != 0 &&
2438 strcmp(FileData.cFileName, "..") != 0) {
2439 v = PyBytes_FromString(FileData.cFileName);
2440 if (v == NULL) {
2441 Py_DECREF(d);
2442 d = NULL;
2443 break;
2444 }
2445 if (PyList_Append(d, v) != 0) {
2446 Py_DECREF(v);
2447 Py_DECREF(d);
2448 d = NULL;
2449 break;
2450 }
2451 Py_DECREF(v);
2452 }
2453 Py_BEGIN_ALLOW_THREADS
2454 result = FindNextFile(hFindFile, &FileData);
2455 Py_END_ALLOW_THREADS
2456 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2457 it got to the end of the directory. */
2458 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2459 Py_DECREF(d);
2460 win32_error("FindNextFile", namebuf);
2461 FindClose(hFindFile);
2462 return NULL;
2463 }
2464 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002465
Victor Stinner8c62be82010-05-06 00:08:46 +00002466 if (FindClose(hFindFile) == FALSE) {
2467 Py_DECREF(d);
2468 return win32_error("FindClose", namebuf);
2469 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002470
Victor Stinner8c62be82010-05-06 00:08:46 +00002471 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002472
Tim Peters0bb44a42000-09-15 07:44:49 +00002473#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002474
2475#ifndef MAX_PATH
2476#define MAX_PATH CCHMAXPATH
2477#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002478 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002479 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002480 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002481 PyObject *d, *v;
2482 char namebuf[MAX_PATH+5];
2483 HDIR hdir = 1;
2484 ULONG srchcnt = 1;
2485 FILEFINDBUF3 ep;
2486 APIRET rc;
2487
Victor Stinner8c62be82010-05-06 00:08:46 +00002488 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002489 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002490 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002491 name = PyBytes_AsString(oname);
2492 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002493 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002494 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002495 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002496 return NULL;
2497 }
2498 strcpy(namebuf, name);
2499 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002500 if (*pt == ALTSEP)
2501 *pt = SEP;
2502 if (namebuf[len-1] != SEP)
2503 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002504 strcpy(namebuf + len, "*.*");
2505
Neal Norwitz6c913782007-10-14 03:23:09 +00002506 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002507 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002508 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002509 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002510
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002511 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2512 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002513 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002514 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2515 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2516 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002517
2518 if (rc != NO_ERROR) {
2519 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002520 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002521 }
2522
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002523 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002524 do {
2525 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002526 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002527 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002528
2529 strcpy(namebuf, ep.achName);
2530
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002531 /* Leave Case of Name Alone -- In Native Form */
2532 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002533
Christian Heimes72b710a2008-05-26 13:28:38 +00002534 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002535 if (v == NULL) {
2536 Py_DECREF(d);
2537 d = NULL;
2538 break;
2539 }
2540 if (PyList_Append(d, v) != 0) {
2541 Py_DECREF(v);
2542 Py_DECREF(d);
2543 d = NULL;
2544 break;
2545 }
2546 Py_DECREF(v);
2547 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2548 }
2549
Victor Stinnerdcb24032010-04-22 12:08:36 +00002550 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002551 return d;
2552#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002553 PyObject *oname;
2554 char *name;
2555 PyObject *d, *v;
2556 DIR *dirp;
2557 struct dirent *ep;
2558 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002559
Victor Stinner8c62be82010-05-06 00:08:46 +00002560 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002561 /* v is never read, so it does not need to be initialized yet. */
2562 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002563 arg_is_unicode = 0;
2564 PyErr_Clear();
2565 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002566 oname = NULL;
2567 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
Victor Stinner8c62be82010-05-06 00:08:46 +00002568 return NULL;
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002569 if (oname == NULL) { /* Default arg: "." */
Stefan Krah0e803b32010-11-26 16:16:47 +00002570 oname = PyBytes_FromString(".");
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002571 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002572 name = PyBytes_AsString(oname);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002573 Py_BEGIN_ALLOW_THREADS
2574 dirp = opendir(name);
2575 Py_END_ALLOW_THREADS
2576 if (dirp == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002577 return posix_error_with_allocated_filename(oname);
2578 }
2579 if ((d = PyList_New(0)) == NULL) {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002580 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002581 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002582 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002583 Py_DECREF(oname);
2584 return NULL;
2585 }
2586 for (;;) {
2587 errno = 0;
2588 Py_BEGIN_ALLOW_THREADS
2589 ep = readdir(dirp);
2590 Py_END_ALLOW_THREADS
2591 if (ep == NULL) {
2592 if (errno == 0) {
2593 break;
2594 } else {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002595 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002596 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002597 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002598 Py_DECREF(d);
2599 return posix_error_with_allocated_filename(oname);
2600 }
2601 }
2602 if (ep->d_name[0] == '.' &&
2603 (NAMLEN(ep) == 1 ||
2604 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2605 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002606 if (arg_is_unicode)
2607 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2608 else
2609 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002610 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002611 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002612 break;
2613 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002614 if (PyList_Append(d, v) != 0) {
2615 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002616 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002617 break;
2618 }
2619 Py_DECREF(v);
2620 }
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002621 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002622 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002623 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002624 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002625
Victor Stinner8c62be82010-05-06 00:08:46 +00002626 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002627
Tim Peters0bb44a42000-09-15 07:44:49 +00002628#endif /* which OS */
2629} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002630
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002631#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002632/* A helper function for abspath on win32 */
2633static PyObject *
2634posix__getfullpathname(PyObject *self, PyObject *args)
2635{
Victor Stinner8c62be82010-05-06 00:08:46 +00002636 PyObject *opath;
2637 char *path;
2638 char outbuf[MAX_PATH*2];
2639 char *temp;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002640#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002641 PyUnicodeObject *po;
2642 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2643 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2644 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2645 Py_UNICODE *wtemp;
2646 DWORD result;
2647 PyObject *v;
2648 result = GetFullPathNameW(wpath,
2649 sizeof(woutbuf)/sizeof(woutbuf[0]),
2650 woutbuf, &wtemp);
2651 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2652 woutbufp = malloc(result * sizeof(Py_UNICODE));
2653 if (!woutbufp)
2654 return PyErr_NoMemory();
2655 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2656 }
2657 if (result)
2658 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2659 else
2660 v = win32_error_unicode("GetFullPathNameW", wpath);
2661 if (woutbufp != woutbuf)
2662 free(woutbufp);
2663 return v;
2664 }
2665 /* Drop the argument parsing error as narrow strings
2666 are also valid. */
2667 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002668
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002669#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002670 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2671 PyUnicode_FSConverter, &opath))
2672 return NULL;
2673 path = PyBytes_AsString(opath);
2674 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2675 outbuf, &temp)) {
2676 win32_error("GetFullPathName", path);
2677 Py_DECREF(opath);
2678 return NULL;
2679 }
2680 Py_DECREF(opath);
2681 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2682 return PyUnicode_Decode(outbuf, strlen(outbuf),
2683 Py_FileSystemDefaultEncoding, NULL);
2684 }
2685 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002686} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00002687
Brian Curtinf5e76d02010-11-24 13:14:05 +00002688/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
2689static int has_GetFinalPathNameByHandle = 0;
2690static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
2691 DWORD);
2692static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
2693 DWORD);
2694static int
2695check_GetFinalPathNameByHandle()
2696{
2697 HINSTANCE hKernel32;
2698 /* only recheck */
2699 if (!has_GetFinalPathNameByHandle)
2700 {
2701 hKernel32 = GetModuleHandle("KERNEL32");
2702 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
2703 "GetFinalPathNameByHandleA");
2704 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
2705 "GetFinalPathNameByHandleW");
2706 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
2707 Py_GetFinalPathNameByHandleW;
2708 }
2709 return has_GetFinalPathNameByHandle;
2710}
2711
Brian Curtind40e6f72010-07-08 21:39:08 +00002712/* A helper function for samepath on windows */
2713static PyObject *
2714posix__getfinalpathname(PyObject *self, PyObject *args)
2715{
2716 HANDLE hFile;
2717 int buf_size;
2718 wchar_t *target_path;
2719 int result_length;
2720 PyObject *result;
2721 wchar_t *path;
2722
Brian Curtin94622b02010-09-24 00:03:39 +00002723 if (!PyArg_ParseTuple(args, "u|:_getfinalpathname", &path)) {
Brian Curtind40e6f72010-07-08 21:39:08 +00002724 return NULL;
2725 }
2726
2727 if(!check_GetFinalPathNameByHandle()) {
2728 /* If the OS doesn't have GetFinalPathNameByHandle, return a
2729 NotImplementedError. */
2730 return PyErr_Format(PyExc_NotImplementedError,
2731 "GetFinalPathNameByHandle not available on this platform");
2732 }
2733
2734 hFile = CreateFileW(
2735 path,
2736 0, /* desired access */
2737 0, /* share mode */
2738 NULL, /* security attributes */
2739 OPEN_EXISTING,
2740 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
2741 FILE_FLAG_BACKUP_SEMANTICS,
2742 NULL);
2743
2744 if(hFile == INVALID_HANDLE_VALUE) {
2745 return win32_error_unicode("GetFinalPathNamyByHandle", path);
Brian Curtin74e45612010-07-09 15:58:59 +00002746 return PyErr_Format(PyExc_RuntimeError,
2747 "Could not get a handle to file.");
Brian Curtind40e6f72010-07-08 21:39:08 +00002748 }
2749
2750 /* We have a good handle to the target, use it to determine the
2751 target path name. */
2752 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
2753
2754 if(!buf_size)
2755 return win32_error_unicode("GetFinalPathNameByHandle", path);
2756
2757 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
2758 if(!target_path)
2759 return PyErr_NoMemory();
2760
2761 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
2762 buf_size, VOLUME_NAME_DOS);
2763 if(!result_length)
2764 return win32_error_unicode("GetFinalPathNamyByHandle", path);
2765
2766 if(!CloseHandle(hFile))
2767 return win32_error_unicode("GetFinalPathNameByHandle", path);
2768
2769 target_path[result_length] = 0;
2770 result = PyUnicode_FromUnicode(target_path, result_length);
2771 free(target_path);
2772 return result;
2773
2774} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00002775
2776static PyObject *
2777posix__getfileinformation(PyObject *self, PyObject *args)
2778{
2779 HANDLE hFile;
2780 BY_HANDLE_FILE_INFORMATION info;
2781 int fd;
2782
2783 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
2784 return NULL;
2785
2786 if (!_PyVerify_fd(fd)) {
2787 PyErr_SetString(PyExc_ValueError, "received invalid file descriptor");
2788 return NULL;
2789 }
2790
2791 hFile = (HANDLE)_get_osfhandle(fd);
2792 if (hFile == INVALID_HANDLE_VALUE)
2793 return win32_error("_getfileinformation", NULL);
2794
2795 if (!GetFileInformationByHandle(hFile, &info))
2796 return win32_error("_getfileinformation", NULL);
2797
2798 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
2799 info.nFileIndexHigh,
2800 info.nFileIndexLow);
2801}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002802#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002803
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002804PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002805"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002806Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002807
Barry Warsaw53699e91996-12-10 23:23:01 +00002808static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002809posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002810{
Victor Stinner8c62be82010-05-06 00:08:46 +00002811 int res;
2812 PyObject *opath;
2813 char *path;
2814 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002815
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002816#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002817 PyUnicodeObject *po;
2818 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2819 Py_BEGIN_ALLOW_THREADS
2820 /* PyUnicode_AS_UNICODE OK without thread lock as
2821 it is a simple dereference. */
2822 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2823 Py_END_ALLOW_THREADS
2824 if (!res)
2825 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2826 Py_INCREF(Py_None);
2827 return Py_None;
2828 }
2829 /* Drop the argument parsing error as narrow strings
2830 are also valid. */
2831 PyErr_Clear();
2832 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2833 PyUnicode_FSConverter, &opath, &mode))
2834 return NULL;
2835 path = PyBytes_AsString(opath);
2836 Py_BEGIN_ALLOW_THREADS
2837 /* PyUnicode_AS_UNICODE OK without thread lock as
2838 it is a simple dereference. */
2839 res = CreateDirectoryA(path, NULL);
2840 Py_END_ALLOW_THREADS
2841 if (!res) {
2842 win32_error("mkdir", path);
2843 Py_DECREF(opath);
2844 return NULL;
2845 }
2846 Py_DECREF(opath);
2847 Py_INCREF(Py_None);
2848 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002849#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002850
Victor Stinner8c62be82010-05-06 00:08:46 +00002851 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2852 PyUnicode_FSConverter, &opath, &mode))
2853 return NULL;
2854 path = PyBytes_AsString(opath);
2855 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002856#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00002857 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002858#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002859 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002860#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002861 Py_END_ALLOW_THREADS
2862 if (res < 0)
2863 return posix_error_with_allocated_filename(opath);
2864 Py_DECREF(opath);
2865 Py_INCREF(Py_None);
2866 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002867#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002868}
2869
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002870
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002871/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2872#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002873#include <sys/resource.h>
2874#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002875
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002876
2877#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002878PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002879"nice(inc) -> new_priority\n\n\
2880Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002881
Barry Warsaw53699e91996-12-10 23:23:01 +00002882static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002883posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002884{
Victor Stinner8c62be82010-05-06 00:08:46 +00002885 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002886
Victor Stinner8c62be82010-05-06 00:08:46 +00002887 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2888 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002889
Victor Stinner8c62be82010-05-06 00:08:46 +00002890 /* There are two flavours of 'nice': one that returns the new
2891 priority (as required by almost all standards out there) and the
2892 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2893 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002894
Victor Stinner8c62be82010-05-06 00:08:46 +00002895 If we are of the nice family that returns the new priority, we
2896 need to clear errno before the call, and check if errno is filled
2897 before calling posix_error() on a returnvalue of -1, because the
2898 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002899
Victor Stinner8c62be82010-05-06 00:08:46 +00002900 errno = 0;
2901 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002902#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00002903 if (value == 0)
2904 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002905#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002906 if (value == -1 && errno != 0)
2907 /* either nice() or getpriority() returned an error */
2908 return posix_error();
2909 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002910}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002911#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002912
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002913PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002914"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002915Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002916
Barry Warsaw53699e91996-12-10 23:23:01 +00002917static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002918posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002919{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002920#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002921 PyObject *o1, *o2;
2922 char *p1, *p2;
2923 BOOL result;
2924 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2925 goto error;
2926 if (!convert_to_unicode(&o1))
2927 goto error;
2928 if (!convert_to_unicode(&o2)) {
2929 Py_DECREF(o1);
2930 goto error;
2931 }
2932 Py_BEGIN_ALLOW_THREADS
2933 result = MoveFileW(PyUnicode_AsUnicode(o1),
2934 PyUnicode_AsUnicode(o2));
2935 Py_END_ALLOW_THREADS
2936 Py_DECREF(o1);
2937 Py_DECREF(o2);
2938 if (!result)
2939 return win32_error("rename", NULL);
2940 Py_INCREF(Py_None);
2941 return Py_None;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002942error:
Victor Stinner8c62be82010-05-06 00:08:46 +00002943 PyErr_Clear();
2944 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2945 return NULL;
2946 Py_BEGIN_ALLOW_THREADS
2947 result = MoveFileA(p1, p2);
2948 Py_END_ALLOW_THREADS
2949 if (!result)
2950 return win32_error("rename", NULL);
2951 Py_INCREF(Py_None);
2952 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002953#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002954 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002955#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002956}
2957
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002958
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002959PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002960"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002961Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002962
Barry Warsaw53699e91996-12-10 23:23:01 +00002963static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002964posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002965{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002966#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002967 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002968#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002969 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002970#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002971}
2972
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002973
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002974PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002975"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002976Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002977
Barry Warsaw53699e91996-12-10 23:23:01 +00002978static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002979posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002980{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002981#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00002982 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002983#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002984 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002985#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002986}
2987
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002988
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002989#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002990PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002991"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002992Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002993
Barry Warsaw53699e91996-12-10 23:23:01 +00002994static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002995posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002996{
Victor Stinner8c62be82010-05-06 00:08:46 +00002997 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002998#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002999 wchar_t *command;
3000 if (!PyArg_ParseTuple(args, "u:system", &command))
3001 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003002
Victor Stinner8c62be82010-05-06 00:08:46 +00003003 Py_BEGIN_ALLOW_THREADS
3004 sts = _wsystem(command);
3005 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00003006#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003007 PyObject *command_obj;
3008 char *command;
3009 if (!PyArg_ParseTuple(args, "O&:system",
3010 PyUnicode_FSConverter, &command_obj))
3011 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003012
Victor Stinner8c62be82010-05-06 00:08:46 +00003013 command = PyBytes_AsString(command_obj);
3014 Py_BEGIN_ALLOW_THREADS
3015 sts = system(command);
3016 Py_END_ALLOW_THREADS
3017 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00003018#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003019 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003020}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003021#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003022
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003023
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003024PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003025"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003026Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003027
Barry Warsaw53699e91996-12-10 23:23:01 +00003028static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003029posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003030{
Victor Stinner8c62be82010-05-06 00:08:46 +00003031 int i;
3032 if (!PyArg_ParseTuple(args, "i:umask", &i))
3033 return NULL;
3034 i = (int)umask(i);
3035 if (i < 0)
3036 return posix_error();
3037 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003038}
3039
Brian Curtind40e6f72010-07-08 21:39:08 +00003040#ifdef MS_WINDOWS
3041
3042/* override the default DeleteFileW behavior so that directory
3043symlinks can be removed with this function, the same as with
3044Unix symlinks */
3045BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
3046{
3047 WIN32_FILE_ATTRIBUTE_DATA info;
3048 WIN32_FIND_DATAW find_data;
3049 HANDLE find_data_handle;
3050 int is_directory = 0;
3051 int is_link = 0;
3052
3053 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3054 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
3055
3056 /* Get WIN32_FIND_DATA structure for the path to determine if
3057 it is a symlink */
3058 if(is_directory &&
3059 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3060 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3061
3062 if(find_data_handle != INVALID_HANDLE_VALUE) {
3063 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3064 FindClose(find_data_handle);
3065 }
3066 }
3067 }
3068
3069 if (is_directory && is_link)
3070 return RemoveDirectoryW(lpFileName);
3071
3072 return DeleteFileW(lpFileName);
3073}
3074#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003075
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003076PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003077"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003078Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003079
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003080PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003081"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003082Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003083
Barry Warsaw53699e91996-12-10 23:23:01 +00003084static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003085posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003086{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003087#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003088 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3089 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003090#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003091 return posix_1str(args, "O&:remove", unlink);
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 Rossumb6775db1994-08-01 11:34:53 +00003096#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003097PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003098"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003099Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003100
Barry Warsaw53699e91996-12-10 23:23:01 +00003101static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003102posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003103{
Victor Stinner8c62be82010-05-06 00:08:46 +00003104 struct utsname u;
3105 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003106
Victor Stinner8c62be82010-05-06 00:08:46 +00003107 Py_BEGIN_ALLOW_THREADS
3108 res = uname(&u);
3109 Py_END_ALLOW_THREADS
3110 if (res < 0)
3111 return posix_error();
3112 return Py_BuildValue("(sssss)",
3113 u.sysname,
3114 u.nodename,
3115 u.release,
3116 u.version,
3117 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003118}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003119#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003120
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003121static int
3122extract_time(PyObject *t, long* sec, long* usec)
3123{
Victor Stinner8c62be82010-05-06 00:08:46 +00003124 long intval;
3125 if (PyFloat_Check(t)) {
3126 double tval = PyFloat_AsDouble(t);
3127 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
3128 if (!intobj)
3129 return -1;
3130 intval = PyLong_AsLong(intobj);
3131 Py_DECREF(intobj);
3132 if (intval == -1 && PyErr_Occurred())
3133 return -1;
3134 *sec = intval;
3135 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
3136 if (*usec < 0)
3137 /* If rounding gave us a negative number,
3138 truncate. */
3139 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00003140 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003141 }
3142 intval = PyLong_AsLong(t);
3143 if (intval == -1 && PyErr_Occurred())
3144 return -1;
3145 *sec = intval;
3146 *usec = 0;
3147 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003148}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003149
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003150PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00003151"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00003152utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00003153Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003154second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003155
Barry Warsaw53699e91996-12-10 23:23:01 +00003156static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003157posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003158{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003159#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003160 PyObject *arg;
3161 PyUnicodeObject *obwpath;
3162 wchar_t *wpath = NULL;
3163 PyObject *oapath;
3164 char *apath;
3165 HANDLE hFile;
3166 long atimesec, mtimesec, ausec, musec;
3167 FILETIME atime, mtime;
3168 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003169
Victor Stinner8c62be82010-05-06 00:08:46 +00003170 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
3171 wpath = PyUnicode_AS_UNICODE(obwpath);
3172 Py_BEGIN_ALLOW_THREADS
3173 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3174 NULL, OPEN_EXISTING,
3175 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3176 Py_END_ALLOW_THREADS
3177 if (hFile == INVALID_HANDLE_VALUE)
3178 return win32_error_unicode("utime", wpath);
3179 } else
3180 /* Drop the argument parsing error as narrow strings
3181 are also valid. */
3182 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003183
Victor Stinner8c62be82010-05-06 00:08:46 +00003184 if (!wpath) {
3185 if (!PyArg_ParseTuple(args, "O&O:utime",
3186 PyUnicode_FSConverter, &oapath, &arg))
3187 return NULL;
3188 apath = PyBytes_AsString(oapath);
3189 Py_BEGIN_ALLOW_THREADS
3190 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3191 NULL, OPEN_EXISTING,
3192 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3193 Py_END_ALLOW_THREADS
3194 if (hFile == INVALID_HANDLE_VALUE) {
3195 win32_error("utime", apath);
3196 Py_DECREF(oapath);
3197 return NULL;
3198 }
3199 Py_DECREF(oapath);
3200 }
3201
3202 if (arg == Py_None) {
3203 SYSTEMTIME now;
3204 GetSystemTime(&now);
3205 if (!SystemTimeToFileTime(&now, &mtime) ||
3206 !SystemTimeToFileTime(&now, &atime)) {
3207 win32_error("utime", NULL);
3208 goto done;
Stefan Krah0e803b32010-11-26 16:16:47 +00003209 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003210 }
3211 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3212 PyErr_SetString(PyExc_TypeError,
3213 "utime() arg 2 must be a tuple (atime, mtime)");
3214 goto done;
3215 }
3216 else {
3217 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3218 &atimesec, &ausec) == -1)
3219 goto done;
3220 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3221 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3222 &mtimesec, &musec) == -1)
3223 goto done;
3224 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3225 }
3226 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3227 /* Avoid putting the file name into the error here,
3228 as that may confuse the user into believing that
3229 something is wrong with the file, when it also
3230 could be the time stamp that gives a problem. */
3231 win32_error("utime", NULL);
3232 }
3233 Py_INCREF(Py_None);
3234 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003235done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003236 CloseHandle(hFile);
3237 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003238#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003239
Victor Stinner8c62be82010-05-06 00:08:46 +00003240 PyObject *opath;
3241 char *path;
3242 long atime, mtime, ausec, musec;
3243 int res;
3244 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003245
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003246#if defined(HAVE_UTIMES)
Victor Stinner8c62be82010-05-06 00:08:46 +00003247 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003248#define ATIME buf[0].tv_sec
3249#define MTIME buf[1].tv_sec
3250#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003251/* XXX should define struct utimbuf instead, above */
Victor Stinner8c62be82010-05-06 00:08:46 +00003252 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003253#define ATIME buf.actime
3254#define MTIME buf.modtime
3255#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003256#else /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003257 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003258#define ATIME buf[0]
3259#define MTIME buf[1]
3260#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003261#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003262
Mark Hammond817c9292003-12-03 01:22:38 +00003263
Victor Stinner8c62be82010-05-06 00:08:46 +00003264 if (!PyArg_ParseTuple(args, "O&O:utime",
3265 PyUnicode_FSConverter, &opath, &arg))
3266 return NULL;
3267 path = PyBytes_AsString(opath);
3268 if (arg == Py_None) {
3269 /* optional time values not given */
3270 Py_BEGIN_ALLOW_THREADS
3271 res = utime(path, NULL);
3272 Py_END_ALLOW_THREADS
3273 }
3274 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3275 PyErr_SetString(PyExc_TypeError,
3276 "utime() arg 2 must be a tuple (atime, mtime)");
3277 Py_DECREF(opath);
3278 return NULL;
3279 }
3280 else {
3281 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3282 &atime, &ausec) == -1) {
3283 Py_DECREF(opath);
3284 return NULL;
3285 }
3286 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3287 &mtime, &musec) == -1) {
3288 Py_DECREF(opath);
3289 return NULL;
3290 }
3291 ATIME = atime;
3292 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003293#ifdef HAVE_UTIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00003294 buf[0].tv_usec = ausec;
3295 buf[1].tv_usec = musec;
3296 Py_BEGIN_ALLOW_THREADS
3297 res = utimes(path, buf);
3298 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003299#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003300 Py_BEGIN_ALLOW_THREADS
3301 res = utime(path, UTIME_ARG);
3302 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003303#endif /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003304 }
3305 if (res < 0) {
3306 return posix_error_with_allocated_filename(opath);
3307 }
3308 Py_DECREF(opath);
3309 Py_INCREF(Py_None);
3310 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003311#undef UTIME_ARG
3312#undef ATIME
3313#undef MTIME
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003314#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003315}
3316
Guido van Rossum85e3b011991-06-03 12:42:10 +00003317
Guido van Rossum3b066191991-06-04 19:40:25 +00003318/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003319
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003320PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003321"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003322Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003323
Barry Warsaw53699e91996-12-10 23:23:01 +00003324static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003325posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003326{
Victor Stinner8c62be82010-05-06 00:08:46 +00003327 int sts;
3328 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3329 return NULL;
3330 _exit(sts);
3331 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003332}
3333
Martin v. Löwis114619e2002-10-07 06:44:21 +00003334#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3335static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003336free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003337{
Victor Stinner8c62be82010-05-06 00:08:46 +00003338 Py_ssize_t i;
3339 for (i = 0; i < count; i++)
3340 PyMem_Free(array[i]);
3341 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003342}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003343
Antoine Pitrou69f71142009-05-24 21:25:49 +00003344static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003345int fsconvert_strdup(PyObject *o, char**out)
3346{
Victor Stinner8c62be82010-05-06 00:08:46 +00003347 PyObject *bytes;
3348 Py_ssize_t size;
3349 if (!PyUnicode_FSConverter(o, &bytes))
3350 return 0;
3351 size = PyBytes_GET_SIZE(bytes);
3352 *out = PyMem_Malloc(size+1);
3353 if (!*out)
3354 return 0;
3355 memcpy(*out, PyBytes_AsString(bytes), size+1);
3356 Py_DECREF(bytes);
3357 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003358}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003359#endif
3360
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003361
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003362#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003363PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003364"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003365Execute an executable path with arguments, replacing current process.\n\
3366\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003367 path: path of executable file\n\
3368 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003369
Barry Warsaw53699e91996-12-10 23:23:01 +00003370static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003371posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003372{
Victor Stinner8c62be82010-05-06 00:08:46 +00003373 PyObject *opath;
3374 char *path;
3375 PyObject *argv;
3376 char **argvlist;
3377 Py_ssize_t i, argc;
3378 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003379
Victor Stinner8c62be82010-05-06 00:08:46 +00003380 /* execv has two arguments: (path, argv), where
3381 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003382
Victor Stinner8c62be82010-05-06 00:08:46 +00003383 if (!PyArg_ParseTuple(args, "O&O:execv",
3384 PyUnicode_FSConverter,
3385 &opath, &argv))
3386 return NULL;
3387 path = PyBytes_AsString(opath);
3388 if (PyList_Check(argv)) {
3389 argc = PyList_Size(argv);
3390 getitem = PyList_GetItem;
3391 }
3392 else if (PyTuple_Check(argv)) {
3393 argc = PyTuple_Size(argv);
3394 getitem = PyTuple_GetItem;
3395 }
3396 else {
3397 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3398 Py_DECREF(opath);
3399 return NULL;
3400 }
3401 if (argc < 1) {
3402 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3403 Py_DECREF(opath);
3404 return NULL;
3405 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003406
Victor Stinner8c62be82010-05-06 00:08:46 +00003407 argvlist = PyMem_NEW(char *, argc+1);
3408 if (argvlist == NULL) {
3409 Py_DECREF(opath);
3410 return PyErr_NoMemory();
3411 }
3412 for (i = 0; i < argc; i++) {
3413 if (!fsconvert_strdup((*getitem)(argv, i),
3414 &argvlist[i])) {
3415 free_string_array(argvlist, i);
3416 PyErr_SetString(PyExc_TypeError,
3417 "execv() arg 2 must contain only strings");
3418 Py_DECREF(opath);
3419 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003420
Victor Stinner8c62be82010-05-06 00:08:46 +00003421 }
3422 }
3423 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003424
Victor Stinner8c62be82010-05-06 00:08:46 +00003425 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003426
Victor Stinner8c62be82010-05-06 00:08:46 +00003427 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003428
Victor Stinner8c62be82010-05-06 00:08:46 +00003429 free_string_array(argvlist, argc);
3430 Py_DECREF(opath);
3431 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003432}
3433
Victor Stinner13bb71c2010-04-23 21:41:56 +00003434static char**
3435parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3436{
Victor Stinner8c62be82010-05-06 00:08:46 +00003437 char **envlist;
3438 Py_ssize_t i, pos, envc;
3439 PyObject *keys=NULL, *vals=NULL;
3440 PyObject *key, *val, *key2, *val2;
3441 char *p, *k, *v;
3442 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003443
Victor Stinner8c62be82010-05-06 00:08:46 +00003444 i = PyMapping_Size(env);
3445 if (i < 0)
3446 return NULL;
3447 envlist = PyMem_NEW(char *, i + 1);
3448 if (envlist == NULL) {
3449 PyErr_NoMemory();
3450 return NULL;
3451 }
3452 envc = 0;
3453 keys = PyMapping_Keys(env);
3454 vals = PyMapping_Values(env);
3455 if (!keys || !vals)
3456 goto error;
3457 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3458 PyErr_Format(PyExc_TypeError,
3459 "env.keys() or env.values() is not a list");
3460 goto error;
3461 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003462
Victor Stinner8c62be82010-05-06 00:08:46 +00003463 for (pos = 0; pos < i; pos++) {
3464 key = PyList_GetItem(keys, pos);
3465 val = PyList_GetItem(vals, pos);
3466 if (!key || !val)
3467 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003468
Victor Stinner8c62be82010-05-06 00:08:46 +00003469 if (PyUnicode_FSConverter(key, &key2) == 0)
3470 goto error;
3471 if (PyUnicode_FSConverter(val, &val2) == 0) {
3472 Py_DECREF(key2);
3473 goto error;
3474 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003475
3476#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003477 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3478 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00003479#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003480 k = PyBytes_AsString(key2);
3481 v = PyBytes_AsString(val2);
3482 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003483
Victor Stinner8c62be82010-05-06 00:08:46 +00003484 p = PyMem_NEW(char, len);
3485 if (p == NULL) {
3486 PyErr_NoMemory();
3487 Py_DECREF(key2);
3488 Py_DECREF(val2);
3489 goto error;
3490 }
3491 PyOS_snprintf(p, len, "%s=%s", k, v);
3492 envlist[envc++] = p;
3493 Py_DECREF(key2);
3494 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003495#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003496 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003497#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003498 }
3499 Py_DECREF(vals);
3500 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003501
Victor Stinner8c62be82010-05-06 00:08:46 +00003502 envlist[envc] = 0;
3503 *envc_ptr = envc;
3504 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003505
3506error:
Victor Stinner8c62be82010-05-06 00:08:46 +00003507 Py_XDECREF(keys);
3508 Py_XDECREF(vals);
3509 while (--envc >= 0)
3510 PyMem_DEL(envlist[envc]);
3511 PyMem_DEL(envlist);
3512 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003513}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003514
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003515PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003516"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003517Execute a path with arguments and environment, replacing current process.\n\
3518\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003519 path: path of executable file\n\
3520 args: tuple or list of arguments\n\
3521 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003522
Barry Warsaw53699e91996-12-10 23:23:01 +00003523static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003524posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003525{
Victor Stinner8c62be82010-05-06 00:08:46 +00003526 PyObject *opath;
3527 char *path;
3528 PyObject *argv, *env;
3529 char **argvlist;
3530 char **envlist;
3531 Py_ssize_t i, argc, envc;
3532 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3533 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003534
Victor Stinner8c62be82010-05-06 00:08:46 +00003535 /* execve has three arguments: (path, argv, env), where
3536 argv is a list or tuple of strings and env is a dictionary
3537 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003538
Victor Stinner8c62be82010-05-06 00:08:46 +00003539 if (!PyArg_ParseTuple(args, "O&OO:execve",
3540 PyUnicode_FSConverter,
3541 &opath, &argv, &env))
3542 return NULL;
3543 path = PyBytes_AsString(opath);
3544 if (PyList_Check(argv)) {
3545 argc = PyList_Size(argv);
3546 getitem = PyList_GetItem;
3547 }
3548 else if (PyTuple_Check(argv)) {
3549 argc = PyTuple_Size(argv);
3550 getitem = PyTuple_GetItem;
3551 }
3552 else {
3553 PyErr_SetString(PyExc_TypeError,
3554 "execve() arg 2 must be a tuple or list");
3555 goto fail_0;
3556 }
3557 if (!PyMapping_Check(env)) {
3558 PyErr_SetString(PyExc_TypeError,
3559 "execve() arg 3 must be a mapping object");
3560 goto fail_0;
3561 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003562
Victor Stinner8c62be82010-05-06 00:08:46 +00003563 argvlist = PyMem_NEW(char *, argc+1);
3564 if (argvlist == NULL) {
3565 PyErr_NoMemory();
3566 goto fail_0;
3567 }
3568 for (i = 0; i < argc; i++) {
3569 if (!fsconvert_strdup((*getitem)(argv, i),
3570 &argvlist[i]))
3571 {
3572 lastarg = i;
3573 goto fail_1;
3574 }
3575 }
3576 lastarg = argc;
3577 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003578
Victor Stinner8c62be82010-05-06 00:08:46 +00003579 envlist = parse_envlist(env, &envc);
3580 if (envlist == NULL)
3581 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003582
Victor Stinner8c62be82010-05-06 00:08:46 +00003583 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003584
Victor Stinner8c62be82010-05-06 00:08:46 +00003585 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003586
Victor Stinner8c62be82010-05-06 00:08:46 +00003587 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003588
Victor Stinner8c62be82010-05-06 00:08:46 +00003589 while (--envc >= 0)
3590 PyMem_DEL(envlist[envc]);
3591 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003592 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003593 free_string_array(argvlist, lastarg);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003594 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003595 Py_DECREF(opath);
3596 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003597}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003598#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003599
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003600
Guido van Rossuma1065681999-01-25 23:20:23 +00003601#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003602PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003603"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003604Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003605\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003606 mode: mode of process creation\n\
3607 path: path of executable file\n\
3608 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003609
3610static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003611posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003612{
Victor Stinner8c62be82010-05-06 00:08:46 +00003613 PyObject *opath;
3614 char *path;
3615 PyObject *argv;
3616 char **argvlist;
3617 int mode, i;
3618 Py_ssize_t argc;
3619 Py_intptr_t spawnval;
3620 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003621
Victor Stinner8c62be82010-05-06 00:08:46 +00003622 /* spawnv has three arguments: (mode, path, argv), where
3623 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003624
Victor Stinner8c62be82010-05-06 00:08:46 +00003625 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3626 PyUnicode_FSConverter,
3627 &opath, &argv))
3628 return NULL;
3629 path = PyBytes_AsString(opath);
3630 if (PyList_Check(argv)) {
3631 argc = PyList_Size(argv);
3632 getitem = PyList_GetItem;
3633 }
3634 else if (PyTuple_Check(argv)) {
3635 argc = PyTuple_Size(argv);
3636 getitem = PyTuple_GetItem;
3637 }
3638 else {
3639 PyErr_SetString(PyExc_TypeError,
3640 "spawnv() arg 2 must be a tuple or list");
3641 Py_DECREF(opath);
3642 return NULL;
3643 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003644
Victor Stinner8c62be82010-05-06 00:08:46 +00003645 argvlist = PyMem_NEW(char *, argc+1);
3646 if (argvlist == NULL) {
3647 Py_DECREF(opath);
3648 return PyErr_NoMemory();
3649 }
3650 for (i = 0; i < argc; i++) {
3651 if (!fsconvert_strdup((*getitem)(argv, i),
3652 &argvlist[i])) {
3653 free_string_array(argvlist, i);
3654 PyErr_SetString(
3655 PyExc_TypeError,
3656 "spawnv() arg 2 must contain only strings");
3657 Py_DECREF(opath);
3658 return NULL;
3659 }
3660 }
3661 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003662
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003663#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003664 Py_BEGIN_ALLOW_THREADS
3665 spawnval = spawnv(mode, path, argvlist);
3666 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003667#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003668 if (mode == _OLD_P_OVERLAY)
3669 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003670
Victor Stinner8c62be82010-05-06 00:08:46 +00003671 Py_BEGIN_ALLOW_THREADS
3672 spawnval = _spawnv(mode, path, argvlist);
3673 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003674#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003675
Victor Stinner8c62be82010-05-06 00:08:46 +00003676 free_string_array(argvlist, argc);
3677 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003678
Victor Stinner8c62be82010-05-06 00:08:46 +00003679 if (spawnval == -1)
3680 return posix_error();
3681 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003682#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003683 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003684#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003685 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003686#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003687}
3688
3689
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003690PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003691"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003692Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003693\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003694 mode: mode of process creation\n\
3695 path: path of executable file\n\
3696 args: tuple or list of arguments\n\
3697 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003698
3699static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003700posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003701{
Victor Stinner8c62be82010-05-06 00:08:46 +00003702 PyObject *opath;
3703 char *path;
3704 PyObject *argv, *env;
3705 char **argvlist;
3706 char **envlist;
3707 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003708 int mode;
3709 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003710 Py_intptr_t spawnval;
3711 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3712 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003713
Victor Stinner8c62be82010-05-06 00:08:46 +00003714 /* spawnve has four arguments: (mode, path, argv, env), where
3715 argv is a list or tuple of strings and env is a dictionary
3716 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003717
Victor Stinner8c62be82010-05-06 00:08:46 +00003718 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3719 PyUnicode_FSConverter,
3720 &opath, &argv, &env))
3721 return NULL;
3722 path = PyBytes_AsString(opath);
3723 if (PyList_Check(argv)) {
3724 argc = PyList_Size(argv);
3725 getitem = PyList_GetItem;
3726 }
3727 else if (PyTuple_Check(argv)) {
3728 argc = PyTuple_Size(argv);
3729 getitem = PyTuple_GetItem;
3730 }
3731 else {
3732 PyErr_SetString(PyExc_TypeError,
3733 "spawnve() arg 2 must be a tuple or list");
3734 goto fail_0;
3735 }
3736 if (!PyMapping_Check(env)) {
3737 PyErr_SetString(PyExc_TypeError,
3738 "spawnve() arg 3 must be a mapping object");
3739 goto fail_0;
3740 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003741
Victor Stinner8c62be82010-05-06 00:08:46 +00003742 argvlist = PyMem_NEW(char *, argc+1);
3743 if (argvlist == NULL) {
3744 PyErr_NoMemory();
3745 goto fail_0;
3746 }
3747 for (i = 0; i < argc; i++) {
3748 if (!fsconvert_strdup((*getitem)(argv, i),
3749 &argvlist[i]))
3750 {
3751 lastarg = i;
3752 goto fail_1;
3753 }
3754 }
3755 lastarg = argc;
3756 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003757
Victor Stinner8c62be82010-05-06 00:08:46 +00003758 envlist = parse_envlist(env, &envc);
3759 if (envlist == NULL)
3760 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003761
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003762#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003763 Py_BEGIN_ALLOW_THREADS
3764 spawnval = spawnve(mode, path, argvlist, envlist);
3765 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003766#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003767 if (mode == _OLD_P_OVERLAY)
3768 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003769
Victor Stinner8c62be82010-05-06 00:08:46 +00003770 Py_BEGIN_ALLOW_THREADS
3771 spawnval = _spawnve(mode, path, argvlist, envlist);
3772 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003773#endif
Tim Peters25059d32001-12-07 20:35:43 +00003774
Victor Stinner8c62be82010-05-06 00:08:46 +00003775 if (spawnval == -1)
3776 (void) posix_error();
3777 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003778#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003779 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003780#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003781 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003782#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003783
Victor Stinner8c62be82010-05-06 00:08:46 +00003784 while (--envc >= 0)
3785 PyMem_DEL(envlist[envc]);
3786 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003787 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003788 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003789 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003790 Py_DECREF(opath);
3791 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003792}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003793
3794/* OS/2 supports spawnvp & spawnvpe natively */
3795#if defined(PYOS_OS2)
3796PyDoc_STRVAR(posix_spawnvp__doc__,
3797"spawnvp(mode, file, args)\n\n\
3798Execute the program 'file' in a new process, using the environment\n\
3799search path to find the file.\n\
3800\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003801 mode: mode of process creation\n\
3802 file: executable file name\n\
3803 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003804
3805static PyObject *
3806posix_spawnvp(PyObject *self, PyObject *args)
3807{
Victor Stinner8c62be82010-05-06 00:08:46 +00003808 PyObject *opath;
3809 char *path;
3810 PyObject *argv;
3811 char **argvlist;
3812 int mode, i, argc;
3813 Py_intptr_t spawnval;
3814 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003815
Victor Stinner8c62be82010-05-06 00:08:46 +00003816 /* spawnvp has three arguments: (mode, path, argv), where
3817 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003818
Victor Stinner8c62be82010-05-06 00:08:46 +00003819 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3820 PyUnicode_FSConverter,
3821 &opath, &argv))
3822 return NULL;
3823 path = PyBytes_AsString(opath);
3824 if (PyList_Check(argv)) {
3825 argc = PyList_Size(argv);
3826 getitem = PyList_GetItem;
3827 }
3828 else if (PyTuple_Check(argv)) {
3829 argc = PyTuple_Size(argv);
3830 getitem = PyTuple_GetItem;
3831 }
3832 else {
3833 PyErr_SetString(PyExc_TypeError,
3834 "spawnvp() arg 2 must be a tuple or list");
3835 Py_DECREF(opath);
3836 return NULL;
3837 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003838
Victor Stinner8c62be82010-05-06 00:08:46 +00003839 argvlist = PyMem_NEW(char *, argc+1);
3840 if (argvlist == NULL) {
3841 Py_DECREF(opath);
3842 return PyErr_NoMemory();
3843 }
3844 for (i = 0; i < argc; i++) {
3845 if (!fsconvert_strdup((*getitem)(argv, i),
3846 &argvlist[i])) {
3847 free_string_array(argvlist, i);
3848 PyErr_SetString(
3849 PyExc_TypeError,
3850 "spawnvp() arg 2 must contain only strings");
3851 Py_DECREF(opath);
3852 return NULL;
3853 }
3854 }
3855 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003856
Victor Stinner8c62be82010-05-06 00:08:46 +00003857 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003858#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003859 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003860#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003861 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003862#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003863 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003864
Victor Stinner8c62be82010-05-06 00:08:46 +00003865 free_string_array(argvlist, argc);
3866 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003867
Victor Stinner8c62be82010-05-06 00:08:46 +00003868 if (spawnval == -1)
3869 return posix_error();
3870 else
3871 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003872}
3873
3874
3875PyDoc_STRVAR(posix_spawnvpe__doc__,
3876"spawnvpe(mode, file, args, env)\n\n\
3877Execute the program 'file' in a new process, using the environment\n\
3878search path to find the file.\n\
3879\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003880 mode: mode of process creation\n\
3881 file: executable file name\n\
3882 args: tuple or list of arguments\n\
3883 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003884
3885static PyObject *
3886posix_spawnvpe(PyObject *self, PyObject *args)
3887{
Victor Stinner8c62be82010-05-06 00:08:46 +00003888 PyObject *opath
3889 char *path;
3890 PyObject *argv, *env;
3891 char **argvlist;
3892 char **envlist;
3893 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003894 int mode;
3895 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003896 Py_intptr_t spawnval;
3897 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3898 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003899
Victor Stinner8c62be82010-05-06 00:08:46 +00003900 /* spawnvpe has four arguments: (mode, path, argv, env), where
3901 argv is a list or tuple of strings and env is a dictionary
3902 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003903
Victor Stinner8c62be82010-05-06 00:08:46 +00003904 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3905 PyUnicode_FSConverter,
3906 &opath, &argv, &env))
3907 return NULL;
3908 path = PyBytes_AsString(opath);
3909 if (PyList_Check(argv)) {
3910 argc = PyList_Size(argv);
3911 getitem = PyList_GetItem;
3912 }
3913 else if (PyTuple_Check(argv)) {
3914 argc = PyTuple_Size(argv);
3915 getitem = PyTuple_GetItem;
3916 }
3917 else {
3918 PyErr_SetString(PyExc_TypeError,
3919 "spawnvpe() arg 2 must be a tuple or list");
3920 goto fail_0;
3921 }
3922 if (!PyMapping_Check(env)) {
3923 PyErr_SetString(PyExc_TypeError,
3924 "spawnvpe() arg 3 must be a mapping object");
3925 goto fail_0;
3926 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003927
Victor Stinner8c62be82010-05-06 00:08:46 +00003928 argvlist = PyMem_NEW(char *, argc+1);
3929 if (argvlist == NULL) {
3930 PyErr_NoMemory();
3931 goto fail_0;
3932 }
3933 for (i = 0; i < argc; i++) {
3934 if (!fsconvert_strdup((*getitem)(argv, i),
3935 &argvlist[i]))
3936 {
3937 lastarg = i;
3938 goto fail_1;
3939 }
3940 }
3941 lastarg = argc;
3942 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003943
Victor Stinner8c62be82010-05-06 00:08:46 +00003944 envlist = parse_envlist(env, &envc);
3945 if (envlist == NULL)
3946 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003947
Victor Stinner8c62be82010-05-06 00:08:46 +00003948 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003949#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003950 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003951#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003952 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003953#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003954 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003955
Victor Stinner8c62be82010-05-06 00:08:46 +00003956 if (spawnval == -1)
3957 (void) posix_error();
3958 else
3959 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003960
Victor Stinner8c62be82010-05-06 00:08:46 +00003961 while (--envc >= 0)
3962 PyMem_DEL(envlist[envc]);
3963 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003964 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003965 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003966 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003967 Py_DECREF(opath);
3968 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003969}
3970#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003971#endif /* HAVE_SPAWNV */
3972
3973
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003974#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003975PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003976"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003977Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3978\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003979Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003980
3981static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003982posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003983{
Victor Stinner8c62be82010-05-06 00:08:46 +00003984 pid_t pid;
3985 int result = 0;
3986 _PyImport_AcquireLock();
3987 pid = fork1();
3988 if (pid == 0) {
3989 /* child: this clobbers and resets the import lock. */
3990 PyOS_AfterFork();
3991 } else {
3992 /* parent: release the import lock. */
3993 result = _PyImport_ReleaseLock();
3994 }
3995 if (pid == -1)
3996 return posix_error();
3997 if (result < 0) {
3998 /* Don't clobber the OSError if the fork failed. */
3999 PyErr_SetString(PyExc_RuntimeError,
4000 "not holding the import lock");
4001 return NULL;
4002 }
4003 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004004}
4005#endif
4006
4007
Guido van Rossumad0ee831995-03-01 10:34:45 +00004008#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004009PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004010"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004011Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004012Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004013
Barry Warsaw53699e91996-12-10 23:23:01 +00004014static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004015posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004016{
Victor Stinner8c62be82010-05-06 00:08:46 +00004017 pid_t pid;
4018 int result = 0;
4019 _PyImport_AcquireLock();
4020 pid = fork();
4021 if (pid == 0) {
4022 /* child: this clobbers and resets the import lock. */
4023 PyOS_AfterFork();
4024 } else {
4025 /* parent: release the import lock. */
4026 result = _PyImport_ReleaseLock();
4027 }
4028 if (pid == -1)
4029 return posix_error();
4030 if (result < 0) {
4031 /* Don't clobber the OSError if the fork failed. */
4032 PyErr_SetString(PyExc_RuntimeError,
4033 "not holding the import lock");
4034 return NULL;
4035 }
4036 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00004037}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004038#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004039
Neal Norwitzb59798b2003-03-21 01:43:31 +00004040/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00004041/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
4042#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00004043#define DEV_PTY_FILE "/dev/ptc"
4044#define HAVE_DEV_PTMX
4045#else
4046#define DEV_PTY_FILE "/dev/ptmx"
4047#endif
4048
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004049#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004050#ifdef HAVE_PTY_H
4051#include <pty.h>
4052#else
4053#ifdef HAVE_LIBUTIL_H
4054#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00004055#else
4056#ifdef HAVE_UTIL_H
4057#include <util.h>
4058#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004059#endif /* HAVE_LIBUTIL_H */
4060#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00004061#ifdef HAVE_STROPTS_H
4062#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004063#endif
4064#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004065
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004066#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004067PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004068"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004069Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004070
4071static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004072posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004073{
Victor Stinner8c62be82010-05-06 00:08:46 +00004074 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004075#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004076 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004077#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004078#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004079 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004080#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00004081 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004082#endif
4083#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00004084
Thomas Wouters70c21a12000-07-14 14:28:33 +00004085#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004086 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
4087 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004088#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004089 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
4090 if (slave_name == NULL)
4091 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00004092
Victor Stinner8c62be82010-05-06 00:08:46 +00004093 slave_fd = open(slave_name, O_RDWR);
4094 if (slave_fd < 0)
4095 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004096#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004097 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
4098 if (master_fd < 0)
4099 return posix_error();
4100 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
4101 /* change permission of slave */
4102 if (grantpt(master_fd) < 0) {
4103 PyOS_setsig(SIGCHLD, sig_saved);
4104 return posix_error();
4105 }
4106 /* unlock slave */
4107 if (unlockpt(master_fd) < 0) {
4108 PyOS_setsig(SIGCHLD, sig_saved);
4109 return posix_error();
4110 }
4111 PyOS_setsig(SIGCHLD, sig_saved);
4112 slave_name = ptsname(master_fd); /* get name of slave */
4113 if (slave_name == NULL)
4114 return posix_error();
4115 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
4116 if (slave_fd < 0)
4117 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004118#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004119 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
4120 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00004121#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00004122 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00004123#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004124#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00004125#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00004126
Victor Stinner8c62be82010-05-06 00:08:46 +00004127 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00004128
Fred Drake8cef4cf2000-06-28 16:40:38 +00004129}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004130#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004131
4132#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004133PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004134"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00004135Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
4136Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004137To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004138
4139static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004140posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004141{
Victor Stinner8c62be82010-05-06 00:08:46 +00004142 int master_fd = -1, result = 0;
4143 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00004144
Victor Stinner8c62be82010-05-06 00:08:46 +00004145 _PyImport_AcquireLock();
4146 pid = forkpty(&master_fd, NULL, NULL, NULL);
4147 if (pid == 0) {
4148 /* child: this clobbers and resets the import lock. */
4149 PyOS_AfterFork();
4150 } else {
4151 /* parent: release the import lock. */
4152 result = _PyImport_ReleaseLock();
4153 }
4154 if (pid == -1)
4155 return posix_error();
4156 if (result < 0) {
4157 /* Don't clobber the OSError if the fork failed. */
4158 PyErr_SetString(PyExc_RuntimeError,
4159 "not holding the import lock");
4160 return NULL;
4161 }
4162 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004163}
4164#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004165
Guido van Rossumad0ee831995-03-01 10:34:45 +00004166#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004167PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004168"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004169Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004170
Barry Warsaw53699e91996-12-10 23:23:01 +00004171static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004172posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004173{
Victor Stinner8c62be82010-05-06 00:08:46 +00004174 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004175}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004176#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004177
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004178
Guido van Rossumad0ee831995-03-01 10:34:45 +00004179#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004180PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004181"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004182Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004183
Barry Warsaw53699e91996-12-10 23:23:01 +00004184static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004185posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004186{
Victor Stinner8c62be82010-05-06 00:08:46 +00004187 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004188}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004189#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004190
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004191
Guido van Rossumad0ee831995-03-01 10:34:45 +00004192#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004193PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004194"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004195Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004196
Barry Warsaw53699e91996-12-10 23:23:01 +00004197static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004198posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004199{
Victor Stinner8c62be82010-05-06 00:08:46 +00004200 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004201}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004202#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004203
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004204
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004205PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004206"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004207Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004208
Barry Warsaw53699e91996-12-10 23:23:01 +00004209static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004210posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004211{
Victor Stinner8c62be82010-05-06 00:08:46 +00004212 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004213}
4214
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004215
Fred Drakec9680921999-12-13 16:37:25 +00004216#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004217PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004218"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004219Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004220
4221static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004222posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004223{
4224 PyObject *result = NULL;
4225
Fred Drakec9680921999-12-13 16:37:25 +00004226#ifdef NGROUPS_MAX
4227#define MAX_GROUPS NGROUPS_MAX
4228#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004229 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004230#define MAX_GROUPS 64
4231#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004232 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004233
4234 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
4235 * This is a helper variable to store the intermediate result when
4236 * that happens.
4237 *
4238 * To keep the code readable the OSX behaviour is unconditional,
4239 * according to the POSIX spec this should be safe on all unix-y
4240 * systems.
4241 */
4242 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00004243 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004244
Victor Stinner8c62be82010-05-06 00:08:46 +00004245 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004246 if (n < 0) {
4247 if (errno == EINVAL) {
4248 n = getgroups(0, NULL);
4249 if (n == -1) {
4250 return posix_error();
4251 }
4252 if (n == 0) {
4253 /* Avoid malloc(0) */
4254 alt_grouplist = grouplist;
4255 } else {
4256 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4257 if (alt_grouplist == NULL) {
4258 errno = EINVAL;
4259 return posix_error();
4260 }
4261 n = getgroups(n, alt_grouplist);
4262 if (n == -1) {
4263 PyMem_Free(alt_grouplist);
4264 return posix_error();
4265 }
4266 }
4267 } else {
4268 return posix_error();
4269 }
4270 }
4271 result = PyList_New(n);
4272 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004273 int i;
4274 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004275 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00004276 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00004277 Py_DECREF(result);
4278 result = NULL;
4279 break;
Fred Drakec9680921999-12-13 16:37:25 +00004280 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004281 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004282 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004283 }
4284
4285 if (alt_grouplist != grouplist) {
4286 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00004287 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004288
Fred Drakec9680921999-12-13 16:37:25 +00004289 return result;
4290}
4291#endif
4292
Antoine Pitroub7572f02009-12-02 20:46:48 +00004293#ifdef HAVE_INITGROUPS
4294PyDoc_STRVAR(posix_initgroups__doc__,
4295"initgroups(username, gid) -> None\n\n\
4296Call the system initgroups() to initialize the group access list with all of\n\
4297the groups of which the specified username is a member, plus the specified\n\
4298group id.");
4299
4300static PyObject *
4301posix_initgroups(PyObject *self, PyObject *args)
4302{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004303 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00004304 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004305 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00004306 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004307
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004308 if (!PyArg_ParseTuple(args, "O&l:initgroups",
4309 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00004310 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004311 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004312
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004313 res = initgroups(username, (gid_t) gid);
4314 Py_DECREF(oname);
4315 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00004316 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004317
Victor Stinner8c62be82010-05-06 00:08:46 +00004318 Py_INCREF(Py_None);
4319 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004320}
4321#endif
4322
Martin v. Löwis606edc12002-06-13 21:09:11 +00004323#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004324PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004325"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004326Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004327
4328static PyObject *
4329posix_getpgid(PyObject *self, PyObject *args)
4330{
Victor Stinner8c62be82010-05-06 00:08:46 +00004331 pid_t pid, pgid;
4332 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
4333 return NULL;
4334 pgid = getpgid(pid);
4335 if (pgid < 0)
4336 return posix_error();
4337 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004338}
4339#endif /* HAVE_GETPGID */
4340
4341
Guido van Rossumb6775db1994-08-01 11:34:53 +00004342#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004343PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004344"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004345Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004346
Barry Warsaw53699e91996-12-10 23:23:01 +00004347static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004348posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004349{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004350#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004351 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004352#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004353 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004354#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004355}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004356#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004357
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004358
Guido van Rossumb6775db1994-08-01 11:34:53 +00004359#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004360PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004361"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00004362Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004363
Barry Warsaw53699e91996-12-10 23:23:01 +00004364static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004365posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004366{
Guido van Rossum64933891994-10-20 21:56:42 +00004367#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004368 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004369#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004370 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004371#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004372 return posix_error();
4373 Py_INCREF(Py_None);
4374 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004375}
4376
Guido van Rossumb6775db1994-08-01 11:34:53 +00004377#endif /* HAVE_SETPGRP */
4378
Guido van Rossumad0ee831995-03-01 10:34:45 +00004379#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004380
4381#ifdef MS_WINDOWS
4382#include <tlhelp32.h>
4383
4384static PyObject*
4385win32_getppid()
4386{
4387 HANDLE snapshot;
4388 pid_t mypid;
4389 PyObject* result = NULL;
4390 BOOL have_record;
4391 PROCESSENTRY32 pe;
4392
4393 mypid = getpid(); /* This function never fails */
4394
4395 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
4396 if (snapshot == INVALID_HANDLE_VALUE)
4397 return PyErr_SetFromWindowsErr(GetLastError());
4398
4399 pe.dwSize = sizeof(pe);
4400 have_record = Process32First(snapshot, &pe);
4401 while (have_record) {
4402 if (mypid == (pid_t)pe.th32ProcessID) {
4403 /* We could cache the ulong value in a static variable. */
4404 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
4405 break;
4406 }
4407
4408 have_record = Process32Next(snapshot, &pe);
4409 }
4410
4411 /* If our loop exits and our pid was not found (result will be NULL)
4412 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
4413 * error anyway, so let's raise it. */
4414 if (!result)
4415 result = PyErr_SetFromWindowsErr(GetLastError());
4416
4417 CloseHandle(snapshot);
4418
4419 return result;
4420}
4421#endif /*MS_WINDOWS*/
4422
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004423PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004424"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004425Return the parent's process id. If the parent process has already exited,\n\
4426Windows machines will still return its id; others systems will return the id\n\
4427of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004428
Barry Warsaw53699e91996-12-10 23:23:01 +00004429static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004430posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004431{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004432#ifdef MS_WINDOWS
4433 return win32_getppid();
4434#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004435 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00004436#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004437}
4438#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004439
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004440
Fred Drake12c6e2d1999-12-14 21:25:03 +00004441#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004442PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004443"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004444Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004445
4446static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004447posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004448{
Victor Stinner8c62be82010-05-06 00:08:46 +00004449 PyObject *result = NULL;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004450#ifdef MS_WINDOWS
4451 wchar_t user_name[UNLEN + 1];
4452 DWORD num_chars = sizeof(user_name)/sizeof(user_name[0]);
4453
4454 if (GetUserNameW(user_name, &num_chars)) {
4455 /* num_chars is the number of unicode chars plus null terminator */
4456 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
4457 }
4458 else
4459 result = PyErr_SetFromWindowsErr(GetLastError());
4460#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004461 char *name;
4462 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004463
Victor Stinner8c62be82010-05-06 00:08:46 +00004464 errno = 0;
4465 name = getlogin();
4466 if (name == NULL) {
4467 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00004468 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004469 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004470 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00004471 }
4472 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004473 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00004474 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004475#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00004476 return result;
4477}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004478#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00004479
Guido van Rossumad0ee831995-03-01 10:34:45 +00004480#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004481PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004482"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004483Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004484
Barry Warsaw53699e91996-12-10 23:23:01 +00004485static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004486posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004487{
Victor Stinner8c62be82010-05-06 00:08:46 +00004488 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004489}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004490#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004491
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004492
Guido van Rossumad0ee831995-03-01 10:34:45 +00004493#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004494PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004495"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004496Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004497
Barry Warsaw53699e91996-12-10 23:23:01 +00004498static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004499posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004500{
Victor Stinner8c62be82010-05-06 00:08:46 +00004501 pid_t pid;
4502 int sig;
4503 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
4504 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004505#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004506 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4507 APIRET rc;
4508 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004509 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004510
4511 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4512 APIRET rc;
4513 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004514 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004515
4516 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004517 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004518#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004519 if (kill(pid, sig) == -1)
4520 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004521#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004522 Py_INCREF(Py_None);
4523 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004524}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004525#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004526
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004527#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004528PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004529"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004530Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004531
4532static PyObject *
4533posix_killpg(PyObject *self, PyObject *args)
4534{
Victor Stinner8c62be82010-05-06 00:08:46 +00004535 int sig;
4536 pid_t pgid;
4537 /* XXX some man pages make the `pgid` parameter an int, others
4538 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4539 take the same type. Moreover, pid_t is always at least as wide as
4540 int (else compilation of this module fails), which is safe. */
4541 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
4542 return NULL;
4543 if (killpg(pgid, sig) == -1)
4544 return posix_error();
4545 Py_INCREF(Py_None);
4546 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004547}
4548#endif
4549
Brian Curtineb24d742010-04-12 17:16:38 +00004550#ifdef MS_WINDOWS
4551PyDoc_STRVAR(win32_kill__doc__,
4552"kill(pid, sig)\n\n\
4553Kill a process with a signal.");
4554
4555static PyObject *
4556win32_kill(PyObject *self, PyObject *args)
4557{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00004558 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004559 DWORD pid, sig, err;
4560 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00004561
Victor Stinner8c62be82010-05-06 00:08:46 +00004562 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4563 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00004564
Victor Stinner8c62be82010-05-06 00:08:46 +00004565 /* Console processes which share a common console can be sent CTRL+C or
4566 CTRL+BREAK events, provided they handle said events. */
4567 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4568 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4569 err = GetLastError();
4570 PyErr_SetFromWindowsErr(err);
4571 }
4572 else
4573 Py_RETURN_NONE;
4574 }
Brian Curtineb24d742010-04-12 17:16:38 +00004575
Victor Stinner8c62be82010-05-06 00:08:46 +00004576 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4577 attempt to open and terminate the process. */
4578 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4579 if (handle == NULL) {
4580 err = GetLastError();
4581 return PyErr_SetFromWindowsErr(err);
4582 }
Brian Curtineb24d742010-04-12 17:16:38 +00004583
Victor Stinner8c62be82010-05-06 00:08:46 +00004584 if (TerminateProcess(handle, sig) == 0) {
4585 err = GetLastError();
4586 result = PyErr_SetFromWindowsErr(err);
4587 } else {
4588 Py_INCREF(Py_None);
4589 result = Py_None;
4590 }
Brian Curtineb24d742010-04-12 17:16:38 +00004591
Victor Stinner8c62be82010-05-06 00:08:46 +00004592 CloseHandle(handle);
4593 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00004594}
4595#endif /* MS_WINDOWS */
4596
Guido van Rossumc0125471996-06-28 18:55:32 +00004597#ifdef HAVE_PLOCK
4598
4599#ifdef HAVE_SYS_LOCK_H
4600#include <sys/lock.h>
4601#endif
4602
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004603PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004604"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004605Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004606
Barry Warsaw53699e91996-12-10 23:23:01 +00004607static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004608posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004609{
Victor Stinner8c62be82010-05-06 00:08:46 +00004610 int op;
4611 if (!PyArg_ParseTuple(args, "i:plock", &op))
4612 return NULL;
4613 if (plock(op) == -1)
4614 return posix_error();
4615 Py_INCREF(Py_None);
4616 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004617}
4618#endif
4619
Guido van Rossumb6775db1994-08-01 11:34:53 +00004620#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004621PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004622"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004623Set the current process's user id.");
4624
Barry Warsaw53699e91996-12-10 23:23:01 +00004625static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004626posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004627{
Victor Stinner8c62be82010-05-06 00:08:46 +00004628 long uid_arg;
4629 uid_t uid;
4630 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
4631 return NULL;
4632 uid = uid_arg;
4633 if (uid != uid_arg) {
4634 PyErr_SetString(PyExc_OverflowError, "user id too big");
4635 return NULL;
4636 }
4637 if (setuid(uid) < 0)
4638 return posix_error();
4639 Py_INCREF(Py_None);
4640 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004641}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004642#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004643
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004644
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004645#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004646PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004647"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004648Set the current process's effective user id.");
4649
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004650static PyObject *
4651posix_seteuid (PyObject *self, PyObject *args)
4652{
Victor Stinner8c62be82010-05-06 00:08:46 +00004653 long euid_arg;
4654 uid_t euid;
4655 if (!PyArg_ParseTuple(args, "l", &euid_arg))
4656 return NULL;
4657 euid = euid_arg;
4658 if (euid != euid_arg) {
4659 PyErr_SetString(PyExc_OverflowError, "user id too big");
4660 return NULL;
4661 }
4662 if (seteuid(euid) < 0) {
4663 return posix_error();
4664 } else {
4665 Py_INCREF(Py_None);
4666 return Py_None;
4667 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004668}
4669#endif /* HAVE_SETEUID */
4670
4671#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004672PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004673"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004674Set the current process's effective group id.");
4675
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004676static PyObject *
4677posix_setegid (PyObject *self, PyObject *args)
4678{
Victor Stinner8c62be82010-05-06 00:08:46 +00004679 long egid_arg;
4680 gid_t egid;
4681 if (!PyArg_ParseTuple(args, "l", &egid_arg))
4682 return NULL;
4683 egid = egid_arg;
4684 if (egid != egid_arg) {
4685 PyErr_SetString(PyExc_OverflowError, "group id too big");
4686 return NULL;
4687 }
4688 if (setegid(egid) < 0) {
4689 return posix_error();
4690 } else {
4691 Py_INCREF(Py_None);
4692 return Py_None;
4693 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004694}
4695#endif /* HAVE_SETEGID */
4696
4697#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004698PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004699"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004700Set the current process's real and effective user ids.");
4701
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004702static PyObject *
4703posix_setreuid (PyObject *self, PyObject *args)
4704{
Victor Stinner8c62be82010-05-06 00:08:46 +00004705 long ruid_arg, euid_arg;
4706 uid_t ruid, euid;
4707 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
4708 return NULL;
4709 if (ruid_arg == -1)
4710 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
4711 else
4712 ruid = ruid_arg; /* otherwise, assign from our long */
4713 if (euid_arg == -1)
4714 euid = (uid_t)-1;
4715 else
4716 euid = euid_arg;
4717 if ((euid_arg != -1 && euid != euid_arg) ||
4718 (ruid_arg != -1 && ruid != ruid_arg)) {
4719 PyErr_SetString(PyExc_OverflowError, "user id too big");
4720 return NULL;
4721 }
4722 if (setreuid(ruid, euid) < 0) {
4723 return posix_error();
4724 } else {
4725 Py_INCREF(Py_None);
4726 return Py_None;
4727 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004728}
4729#endif /* HAVE_SETREUID */
4730
4731#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004732PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004733"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004734Set the current process's real and effective group ids.");
4735
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004736static PyObject *
4737posix_setregid (PyObject *self, PyObject *args)
4738{
Victor Stinner8c62be82010-05-06 00:08:46 +00004739 long rgid_arg, egid_arg;
4740 gid_t rgid, egid;
4741 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
4742 return NULL;
4743 if (rgid_arg == -1)
4744 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
4745 else
4746 rgid = rgid_arg; /* otherwise, assign from our long */
4747 if (egid_arg == -1)
4748 egid = (gid_t)-1;
4749 else
4750 egid = egid_arg;
4751 if ((egid_arg != -1 && egid != egid_arg) ||
4752 (rgid_arg != -1 && rgid != rgid_arg)) {
4753 PyErr_SetString(PyExc_OverflowError, "group id too big");
4754 return NULL;
4755 }
4756 if (setregid(rgid, egid) < 0) {
4757 return posix_error();
4758 } else {
4759 Py_INCREF(Py_None);
4760 return Py_None;
4761 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004762}
4763#endif /* HAVE_SETREGID */
4764
Guido van Rossumb6775db1994-08-01 11:34:53 +00004765#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004766PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004767"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004768Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004769
Barry Warsaw53699e91996-12-10 23:23:01 +00004770static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004771posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004772{
Victor Stinner8c62be82010-05-06 00:08:46 +00004773 long gid_arg;
4774 gid_t gid;
4775 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
4776 return NULL;
4777 gid = gid_arg;
4778 if (gid != gid_arg) {
4779 PyErr_SetString(PyExc_OverflowError, "group id too big");
4780 return NULL;
4781 }
4782 if (setgid(gid) < 0)
4783 return posix_error();
4784 Py_INCREF(Py_None);
4785 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004786}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004787#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004788
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004789#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004790PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004791"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004792Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004793
4794static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004795posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004796{
Victor Stinner8c62be82010-05-06 00:08:46 +00004797 int i, len;
4798 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004799
Victor Stinner8c62be82010-05-06 00:08:46 +00004800 if (!PySequence_Check(groups)) {
4801 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4802 return NULL;
4803 }
4804 len = PySequence_Size(groups);
4805 if (len > MAX_GROUPS) {
4806 PyErr_SetString(PyExc_ValueError, "too many groups");
4807 return NULL;
4808 }
4809 for(i = 0; i < len; i++) {
4810 PyObject *elem;
4811 elem = PySequence_GetItem(groups, i);
4812 if (!elem)
4813 return NULL;
4814 if (!PyLong_Check(elem)) {
4815 PyErr_SetString(PyExc_TypeError,
4816 "groups must be integers");
4817 Py_DECREF(elem);
4818 return NULL;
4819 } else {
4820 unsigned long x = PyLong_AsUnsignedLong(elem);
4821 if (PyErr_Occurred()) {
4822 PyErr_SetString(PyExc_TypeError,
4823 "group id too big");
4824 Py_DECREF(elem);
4825 return NULL;
4826 }
4827 grouplist[i] = x;
4828 /* read back the value to see if it fitted in gid_t */
4829 if (grouplist[i] != x) {
4830 PyErr_SetString(PyExc_TypeError,
4831 "group id too big");
4832 Py_DECREF(elem);
4833 return NULL;
4834 }
4835 }
4836 Py_DECREF(elem);
4837 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004838
Victor Stinner8c62be82010-05-06 00:08:46 +00004839 if (setgroups(len, grouplist) < 0)
4840 return posix_error();
4841 Py_INCREF(Py_None);
4842 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004843}
4844#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004845
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004846#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4847static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004848wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004849{
Victor Stinner8c62be82010-05-06 00:08:46 +00004850 PyObject *result;
4851 static PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004852
Victor Stinner8c62be82010-05-06 00:08:46 +00004853 if (pid == -1)
4854 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004855
Victor Stinner8c62be82010-05-06 00:08:46 +00004856 if (struct_rusage == NULL) {
4857 PyObject *m = PyImport_ImportModuleNoBlock("resource");
4858 if (m == NULL)
4859 return NULL;
4860 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4861 Py_DECREF(m);
4862 if (struct_rusage == NULL)
4863 return NULL;
4864 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004865
Victor Stinner8c62be82010-05-06 00:08:46 +00004866 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4867 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4868 if (!result)
4869 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004870
4871#ifndef doubletime
4872#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4873#endif
4874
Victor Stinner8c62be82010-05-06 00:08:46 +00004875 PyStructSequence_SET_ITEM(result, 0,
4876 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4877 PyStructSequence_SET_ITEM(result, 1,
4878 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004879#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00004880 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
4881 SET_INT(result, 2, ru->ru_maxrss);
4882 SET_INT(result, 3, ru->ru_ixrss);
4883 SET_INT(result, 4, ru->ru_idrss);
4884 SET_INT(result, 5, ru->ru_isrss);
4885 SET_INT(result, 6, ru->ru_minflt);
4886 SET_INT(result, 7, ru->ru_majflt);
4887 SET_INT(result, 8, ru->ru_nswap);
4888 SET_INT(result, 9, ru->ru_inblock);
4889 SET_INT(result, 10, ru->ru_oublock);
4890 SET_INT(result, 11, ru->ru_msgsnd);
4891 SET_INT(result, 12, ru->ru_msgrcv);
4892 SET_INT(result, 13, ru->ru_nsignals);
4893 SET_INT(result, 14, ru->ru_nvcsw);
4894 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004895#undef SET_INT
4896
Victor Stinner8c62be82010-05-06 00:08:46 +00004897 if (PyErr_Occurred()) {
4898 Py_DECREF(result);
4899 return NULL;
4900 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004901
Victor Stinner8c62be82010-05-06 00:08:46 +00004902 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004903}
4904#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4905
4906#ifdef HAVE_WAIT3
4907PyDoc_STRVAR(posix_wait3__doc__,
4908"wait3(options) -> (pid, status, rusage)\n\n\
4909Wait for completion of a child process.");
4910
4911static PyObject *
4912posix_wait3(PyObject *self, PyObject *args)
4913{
Victor Stinner8c62be82010-05-06 00:08:46 +00004914 pid_t pid;
4915 int options;
4916 struct rusage ru;
4917 WAIT_TYPE status;
4918 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004919
Victor Stinner8c62be82010-05-06 00:08:46 +00004920 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4921 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004922
Victor Stinner8c62be82010-05-06 00:08:46 +00004923 Py_BEGIN_ALLOW_THREADS
4924 pid = wait3(&status, options, &ru);
4925 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004926
Victor Stinner8c62be82010-05-06 00:08:46 +00004927 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004928}
4929#endif /* HAVE_WAIT3 */
4930
4931#ifdef HAVE_WAIT4
4932PyDoc_STRVAR(posix_wait4__doc__,
4933"wait4(pid, options) -> (pid, status, rusage)\n\n\
4934Wait for completion of a given child process.");
4935
4936static PyObject *
4937posix_wait4(PyObject *self, PyObject *args)
4938{
Victor Stinner8c62be82010-05-06 00:08:46 +00004939 pid_t pid;
4940 int options;
4941 struct rusage ru;
4942 WAIT_TYPE status;
4943 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004944
Victor Stinner8c62be82010-05-06 00:08:46 +00004945 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
4946 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004947
Victor Stinner8c62be82010-05-06 00:08:46 +00004948 Py_BEGIN_ALLOW_THREADS
4949 pid = wait4(pid, &status, options, &ru);
4950 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004951
Victor Stinner8c62be82010-05-06 00:08:46 +00004952 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004953}
4954#endif /* HAVE_WAIT4 */
4955
Guido van Rossumb6775db1994-08-01 11:34:53 +00004956#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004957PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004958"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004959Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004960
Barry Warsaw53699e91996-12-10 23:23:01 +00004961static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004962posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004963{
Victor Stinner8c62be82010-05-06 00:08:46 +00004964 pid_t pid;
4965 int options;
4966 WAIT_TYPE status;
4967 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004968
Victor Stinner8c62be82010-05-06 00:08:46 +00004969 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4970 return NULL;
4971 Py_BEGIN_ALLOW_THREADS
4972 pid = waitpid(pid, &status, options);
4973 Py_END_ALLOW_THREADS
4974 if (pid == -1)
4975 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004976
Victor Stinner8c62be82010-05-06 00:08:46 +00004977 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004978}
4979
Tim Petersab034fa2002-02-01 11:27:43 +00004980#elif defined(HAVE_CWAIT)
4981
4982/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004983PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004984"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004985"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004986
4987static PyObject *
4988posix_waitpid(PyObject *self, PyObject *args)
4989{
Victor Stinner8c62be82010-05-06 00:08:46 +00004990 Py_intptr_t pid;
4991 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004992
Victor Stinner8c62be82010-05-06 00:08:46 +00004993 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4994 return NULL;
4995 Py_BEGIN_ALLOW_THREADS
4996 pid = _cwait(&status, pid, options);
4997 Py_END_ALLOW_THREADS
4998 if (pid == -1)
4999 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005000
Victor Stinner8c62be82010-05-06 00:08:46 +00005001 /* shift the status left a byte so this is more like the POSIX waitpid */
5002 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005003}
5004#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005005
Guido van Rossumad0ee831995-03-01 10:34:45 +00005006#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005007PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005008"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005009Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005010
Barry Warsaw53699e91996-12-10 23:23:01 +00005011static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005012posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005013{
Victor Stinner8c62be82010-05-06 00:08:46 +00005014 pid_t pid;
5015 WAIT_TYPE status;
5016 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005017
Victor Stinner8c62be82010-05-06 00:08:46 +00005018 Py_BEGIN_ALLOW_THREADS
5019 pid = wait(&status);
5020 Py_END_ALLOW_THREADS
5021 if (pid == -1)
5022 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005023
Victor Stinner8c62be82010-05-06 00:08:46 +00005024 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005025}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005026#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005027
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005028
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005029PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005030"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005031Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005032
Barry Warsaw53699e91996-12-10 23:23:01 +00005033static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005034posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005035{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005036#ifdef HAVE_LSTAT
Victor Stinner8c62be82010-05-06 00:08:46 +00005037 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005038#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005039#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00005040 return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat",
5041 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005042#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005043 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005044#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005045#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005046}
5047
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005048
Guido van Rossumb6775db1994-08-01 11:34:53 +00005049#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005050PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005051"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005052Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005053
Barry Warsaw53699e91996-12-10 23:23:01 +00005054static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005055posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005056{
Victor Stinner8c62be82010-05-06 00:08:46 +00005057 PyObject* v;
5058 char buf[MAXPATHLEN];
5059 PyObject *opath;
5060 char *path;
5061 int n;
5062 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00005063
Victor Stinner8c62be82010-05-06 00:08:46 +00005064 if (!PyArg_ParseTuple(args, "O&:readlink",
5065 PyUnicode_FSConverter, &opath))
5066 return NULL;
5067 path = PyBytes_AsString(opath);
5068 v = PySequence_GetItem(args, 0);
5069 if (v == NULL) {
5070 Py_DECREF(opath);
5071 return NULL;
5072 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00005073
Victor Stinner8c62be82010-05-06 00:08:46 +00005074 if (PyUnicode_Check(v)) {
5075 arg_is_unicode = 1;
5076 }
5077 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005078
Victor Stinner8c62be82010-05-06 00:08:46 +00005079 Py_BEGIN_ALLOW_THREADS
5080 n = readlink(path, buf, (int) sizeof buf);
5081 Py_END_ALLOW_THREADS
5082 if (n < 0)
5083 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005084
Victor Stinner8c62be82010-05-06 00:08:46 +00005085 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00005086 if (arg_is_unicode)
5087 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
5088 else
5089 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005090}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005091#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005092
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005093
Guido van Rossumb6775db1994-08-01 11:34:53 +00005094#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005095PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005096"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005097Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005098
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005099static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005100posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005101{
Victor Stinner8c62be82010-05-06 00:08:46 +00005102 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005103}
5104#endif /* HAVE_SYMLINK */
5105
Brian Curtind40e6f72010-07-08 21:39:08 +00005106#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
5107
5108PyDoc_STRVAR(win_readlink__doc__,
5109"readlink(path) -> path\n\n\
5110Return a string representing the path to which the symbolic link points.");
5111
Brian Curtind40e6f72010-07-08 21:39:08 +00005112/* Windows readlink implementation */
5113static PyObject *
5114win_readlink(PyObject *self, PyObject *args)
5115{
5116 wchar_t *path;
5117 DWORD n_bytes_returned;
5118 DWORD io_result;
5119 PyObject *result;
5120 HANDLE reparse_point_handle;
5121
5122 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
5123 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
5124 wchar_t *print_name;
5125
5126 if (!PyArg_ParseTuple(args,
5127 "u:readlink",
5128 &path))
5129 return NULL;
5130
5131 /* First get a handle to the reparse point */
5132 Py_BEGIN_ALLOW_THREADS
5133 reparse_point_handle = CreateFileW(
5134 path,
5135 0,
5136 0,
5137 0,
5138 OPEN_EXISTING,
5139 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
5140 0);
5141 Py_END_ALLOW_THREADS
5142
5143 if (reparse_point_handle==INVALID_HANDLE_VALUE)
5144 {
5145 return win32_error_unicode("readlink", path);
5146 }
5147
5148 Py_BEGIN_ALLOW_THREADS
5149 /* New call DeviceIoControl to read the reparse point */
5150 io_result = DeviceIoControl(
5151 reparse_point_handle,
5152 FSCTL_GET_REPARSE_POINT,
5153 0, 0, /* in buffer */
5154 target_buffer, sizeof(target_buffer),
5155 &n_bytes_returned,
5156 0 /* we're not using OVERLAPPED_IO */
5157 );
5158 CloseHandle(reparse_point_handle);
5159 Py_END_ALLOW_THREADS
5160
5161 if (io_result==0)
5162 {
5163 return win32_error_unicode("readlink", path);
5164 }
5165
5166 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
5167 {
5168 PyErr_SetString(PyExc_ValueError,
5169 "not a symbolic link");
5170 return NULL;
5171 }
Brian Curtin74e45612010-07-09 15:58:59 +00005172 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
5173 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
5174
5175 result = PyUnicode_FromWideChar(print_name,
5176 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00005177 return result;
5178}
5179
5180#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
5181
5182#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
5183
5184/* Grab CreateSymbolicLinkW dynamically from kernel32 */
5185static int has_CreateSymbolicLinkW = 0;
5186static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
5187static int
5188check_CreateSymbolicLinkW()
5189{
5190 HINSTANCE hKernel32;
5191 /* only recheck */
5192 if (has_CreateSymbolicLinkW)
5193 return has_CreateSymbolicLinkW;
5194 hKernel32 = GetModuleHandle("KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00005195 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
5196 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00005197 if (Py_CreateSymbolicLinkW)
5198 has_CreateSymbolicLinkW = 1;
5199 return has_CreateSymbolicLinkW;
5200}
5201
5202PyDoc_STRVAR(win_symlink__doc__,
5203"symlink(src, dst, target_is_directory=False)\n\n\
5204Create a symbolic link pointing to src named dst.\n\
5205target_is_directory is required if the target is to be interpreted as\n\
5206a directory.\n\
5207This function requires Windows 6.0 or greater, and raises a\n\
5208NotImplementedError otherwise.");
5209
5210static PyObject *
5211win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
5212{
5213 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
5214 PyObject *src, *dest;
5215 int target_is_directory = 0;
5216 DWORD res;
5217 WIN32_FILE_ATTRIBUTE_DATA src_info;
5218
5219 if (!check_CreateSymbolicLinkW())
5220 {
5221 /* raise NotImplementedError */
5222 return PyErr_Format(PyExc_NotImplementedError,
5223 "CreateSymbolicLinkW not found");
5224 }
5225 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:symlink",
5226 kwlist, &src, &dest, &target_is_directory))
5227 return NULL;
5228 if (!convert_to_unicode(&src)) { return NULL; }
5229 if (!convert_to_unicode(&dest)) {
5230 Py_DECREF(src);
5231 return NULL;
5232 }
5233
5234 /* if src is a directory, ensure target_is_directory==1 */
5235 if(
5236 GetFileAttributesExW(
5237 PyUnicode_AsUnicode(src), GetFileExInfoStandard, &src_info
5238 ))
5239 {
5240 target_is_directory = target_is_directory ||
5241 (src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
5242 }
5243
5244 Py_BEGIN_ALLOW_THREADS
5245 res = Py_CreateSymbolicLinkW(
5246 PyUnicode_AsUnicode(dest),
5247 PyUnicode_AsUnicode(src),
5248 target_is_directory);
5249 Py_END_ALLOW_THREADS
5250 Py_DECREF(src);
5251 Py_DECREF(dest);
5252 if (!res)
5253 {
5254 return win32_error_unicode("symlink", PyUnicode_AsUnicode(src));
5255 }
5256
5257 Py_INCREF(Py_None);
5258 return Py_None;
5259}
5260#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005261
5262#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00005263#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5264static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005265system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005266{
5267 ULONG value = 0;
5268
5269 Py_BEGIN_ALLOW_THREADS
5270 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5271 Py_END_ALLOW_THREADS
5272
5273 return value;
5274}
5275
5276static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005277posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005278{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005279 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00005280 return Py_BuildValue("ddddd",
5281 (double)0 /* t.tms_utime / HZ */,
5282 (double)0 /* t.tms_stime / HZ */,
5283 (double)0 /* t.tms_cutime / HZ */,
5284 (double)0 /* t.tms_cstime / HZ */,
5285 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005286}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005287#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00005288#define NEED_TICKS_PER_SECOND
5289static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00005290static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005291posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005292{
Victor Stinner8c62be82010-05-06 00:08:46 +00005293 struct tms t;
5294 clock_t c;
5295 errno = 0;
5296 c = times(&t);
5297 if (c == (clock_t) -1)
5298 return posix_error();
5299 return Py_BuildValue("ddddd",
5300 (double)t.tms_utime / ticks_per_second,
5301 (double)t.tms_stime / ticks_per_second,
5302 (double)t.tms_cutime / ticks_per_second,
5303 (double)t.tms_cstime / ticks_per_second,
5304 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005305}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005306#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005307#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005308
5309
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005310#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005311#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005312static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005313posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005314{
Victor Stinner8c62be82010-05-06 00:08:46 +00005315 FILETIME create, exit, kernel, user;
5316 HANDLE hProc;
5317 hProc = GetCurrentProcess();
5318 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5319 /* The fields of a FILETIME structure are the hi and lo part
5320 of a 64-bit value expressed in 100 nanosecond units.
5321 1e7 is one second in such units; 1e-7 the inverse.
5322 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5323 */
5324 return Py_BuildValue(
5325 "ddddd",
5326 (double)(user.dwHighDateTime*429.4967296 +
5327 user.dwLowDateTime*1e-7),
5328 (double)(kernel.dwHighDateTime*429.4967296 +
5329 kernel.dwLowDateTime*1e-7),
5330 (double)0,
5331 (double)0,
5332 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005333}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005334#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005335
5336#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005337PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005338"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005339Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005340#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005341
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005342
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005343#ifdef HAVE_GETSID
5344PyDoc_STRVAR(posix_getsid__doc__,
5345"getsid(pid) -> sid\n\n\
5346Call the system call getsid().");
5347
5348static PyObject *
5349posix_getsid(PyObject *self, PyObject *args)
5350{
Victor Stinner8c62be82010-05-06 00:08:46 +00005351 pid_t pid;
5352 int sid;
5353 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
5354 return NULL;
5355 sid = getsid(pid);
5356 if (sid < 0)
5357 return posix_error();
5358 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005359}
5360#endif /* HAVE_GETSID */
5361
5362
Guido van Rossumb6775db1994-08-01 11:34:53 +00005363#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005364PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005365"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005366Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005367
Barry Warsaw53699e91996-12-10 23:23:01 +00005368static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005369posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005370{
Victor Stinner8c62be82010-05-06 00:08:46 +00005371 if (setsid() < 0)
5372 return posix_error();
5373 Py_INCREF(Py_None);
5374 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005375}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005376#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005377
Guido van Rossumb6775db1994-08-01 11:34:53 +00005378#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005379PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005380"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005381Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005382
Barry Warsaw53699e91996-12-10 23:23:01 +00005383static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005384posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005385{
Victor Stinner8c62be82010-05-06 00:08:46 +00005386 pid_t pid;
5387 int pgrp;
5388 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
5389 return NULL;
5390 if (setpgid(pid, pgrp) < 0)
5391 return posix_error();
5392 Py_INCREF(Py_None);
5393 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005394}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005395#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005396
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005397
Guido van Rossumb6775db1994-08-01 11:34:53 +00005398#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005399PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005400"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005401Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005402
Barry Warsaw53699e91996-12-10 23:23:01 +00005403static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005404posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005405{
Victor Stinner8c62be82010-05-06 00:08:46 +00005406 int fd;
5407 pid_t pgid;
5408 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
5409 return NULL;
5410 pgid = tcgetpgrp(fd);
5411 if (pgid < 0)
5412 return posix_error();
5413 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005414}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005415#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005416
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005417
Guido van Rossumb6775db1994-08-01 11:34:53 +00005418#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005419PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005420"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005421Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005422
Barry Warsaw53699e91996-12-10 23:23:01 +00005423static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005424posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005425{
Victor Stinner8c62be82010-05-06 00:08:46 +00005426 int fd;
5427 pid_t pgid;
5428 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
5429 return NULL;
5430 if (tcsetpgrp(fd, pgid) < 0)
5431 return posix_error();
5432 Py_INCREF(Py_None);
5433 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005434}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005435#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005436
Guido van Rossum687dd131993-05-17 08:34:16 +00005437/* Functions acting on file descriptors */
5438
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005439PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005440"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005441Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005442
Barry Warsaw53699e91996-12-10 23:23:01 +00005443static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005444posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005445{
Victor Stinner8c62be82010-05-06 00:08:46 +00005446 PyObject *ofile;
5447 char *file;
5448 int flag;
5449 int mode = 0777;
5450 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005451
5452#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005453 PyUnicodeObject *po;
5454 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5455 Py_BEGIN_ALLOW_THREADS
5456 /* PyUnicode_AS_UNICODE OK without thread
5457 lock as it is a simple dereference. */
5458 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5459 Py_END_ALLOW_THREADS
5460 if (fd < 0)
5461 return posix_error();
5462 return PyLong_FromLong((long)fd);
5463 }
5464 /* Drop the argument parsing error as narrow strings
5465 are also valid. */
5466 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005467#endif
5468
Victor Stinner8c62be82010-05-06 00:08:46 +00005469 if (!PyArg_ParseTuple(args, "O&i|i",
5470 PyUnicode_FSConverter, &ofile,
5471 &flag, &mode))
5472 return NULL;
5473 file = PyBytes_AsString(ofile);
5474 Py_BEGIN_ALLOW_THREADS
5475 fd = open(file, flag, mode);
5476 Py_END_ALLOW_THREADS
5477 if (fd < 0)
5478 return posix_error_with_allocated_filename(ofile);
5479 Py_DECREF(ofile);
5480 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005481}
5482
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005483
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005484PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005485"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005486Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005487
Barry Warsaw53699e91996-12-10 23:23:01 +00005488static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005489posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005490{
Victor Stinner8c62be82010-05-06 00:08:46 +00005491 int fd, res;
5492 if (!PyArg_ParseTuple(args, "i:close", &fd))
5493 return NULL;
5494 if (!_PyVerify_fd(fd))
5495 return posix_error();
5496 Py_BEGIN_ALLOW_THREADS
5497 res = close(fd);
5498 Py_END_ALLOW_THREADS
5499 if (res < 0)
5500 return posix_error();
5501 Py_INCREF(Py_None);
5502 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005503}
5504
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005505
Victor Stinner8c62be82010-05-06 00:08:46 +00005506PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00005507"closerange(fd_low, fd_high)\n\n\
5508Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
5509
5510static PyObject *
5511posix_closerange(PyObject *self, PyObject *args)
5512{
Victor Stinner8c62be82010-05-06 00:08:46 +00005513 int fd_from, fd_to, i;
5514 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
5515 return NULL;
5516 Py_BEGIN_ALLOW_THREADS
5517 for (i = fd_from; i < fd_to; i++)
5518 if (_PyVerify_fd(i))
5519 close(i);
5520 Py_END_ALLOW_THREADS
5521 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00005522}
5523
5524
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005525PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005526"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005527Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005528
Barry Warsaw53699e91996-12-10 23:23:01 +00005529static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005530posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005531{
Victor Stinner8c62be82010-05-06 00:08:46 +00005532 int fd;
5533 if (!PyArg_ParseTuple(args, "i:dup", &fd))
5534 return NULL;
5535 if (!_PyVerify_fd(fd))
5536 return posix_error();
5537 Py_BEGIN_ALLOW_THREADS
5538 fd = dup(fd);
5539 Py_END_ALLOW_THREADS
5540 if (fd < 0)
5541 return posix_error();
5542 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005543}
5544
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005545
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005546PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005547"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005548Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005549
Barry Warsaw53699e91996-12-10 23:23:01 +00005550static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005551posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005552{
Victor Stinner8c62be82010-05-06 00:08:46 +00005553 int fd, fd2, res;
5554 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5555 return NULL;
5556 if (!_PyVerify_fd_dup2(fd, fd2))
5557 return posix_error();
5558 Py_BEGIN_ALLOW_THREADS
5559 res = dup2(fd, fd2);
5560 Py_END_ALLOW_THREADS
5561 if (res < 0)
5562 return posix_error();
5563 Py_INCREF(Py_None);
5564 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005565}
5566
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005567
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005568PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005569"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005570Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005571
Barry Warsaw53699e91996-12-10 23:23:01 +00005572static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005573posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005574{
Victor Stinner8c62be82010-05-06 00:08:46 +00005575 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005576#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005577 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005578#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005579 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005580#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005581 PyObject *posobj;
5582 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5583 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005584#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00005585 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5586 switch (how) {
5587 case 0: how = SEEK_SET; break;
5588 case 1: how = SEEK_CUR; break;
5589 case 2: how = SEEK_END; break;
5590 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005591#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005592
5593#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005594 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005595#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005596 pos = PyLong_Check(posobj) ?
5597 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005598#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005599 if (PyErr_Occurred())
5600 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005601
Victor Stinner8c62be82010-05-06 00:08:46 +00005602 if (!_PyVerify_fd(fd))
5603 return posix_error();
5604 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005605#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005606 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005607#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005608 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005609#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005610 Py_END_ALLOW_THREADS
5611 if (res < 0)
5612 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005613
5614#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005615 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005616#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005617 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005618#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005619}
5620
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005621
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005622PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005623"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005624Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005625
Barry Warsaw53699e91996-12-10 23:23:01 +00005626static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005627posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005628{
Victor Stinner8c62be82010-05-06 00:08:46 +00005629 int fd, size;
5630 Py_ssize_t n;
5631 PyObject *buffer;
5632 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5633 return NULL;
5634 if (size < 0) {
5635 errno = EINVAL;
5636 return posix_error();
5637 }
5638 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
5639 if (buffer == NULL)
5640 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00005641 if (!_PyVerify_fd(fd)) {
5642 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00005643 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00005644 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005645 Py_BEGIN_ALLOW_THREADS
5646 n = read(fd, PyBytes_AS_STRING(buffer), size);
5647 Py_END_ALLOW_THREADS
5648 if (n < 0) {
5649 Py_DECREF(buffer);
5650 return posix_error();
5651 }
5652 if (n != size)
5653 _PyBytes_Resize(&buffer, n);
5654 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00005655}
5656
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005657
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005658PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005659"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005660Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005661
Barry Warsaw53699e91996-12-10 23:23:01 +00005662static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005663posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005664{
Victor Stinner8c62be82010-05-06 00:08:46 +00005665 Py_buffer pbuf;
5666 int fd;
5667 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005668
Victor Stinner8c62be82010-05-06 00:08:46 +00005669 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
5670 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00005671 if (!_PyVerify_fd(fd)) {
5672 PyBuffer_Release(&pbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00005673 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00005674 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005675 Py_BEGIN_ALLOW_THREADS
5676 size = write(fd, pbuf.buf, (size_t)pbuf.len);
5677 Py_END_ALLOW_THREADS
Stefan Krah99439262010-11-26 12:58:05 +00005678 PyBuffer_Release(&pbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00005679 if (size < 0)
5680 return posix_error();
5681 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005682}
5683
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005684
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005685PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005686"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005687Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005688
Barry Warsaw53699e91996-12-10 23:23:01 +00005689static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005690posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005691{
Victor Stinner8c62be82010-05-06 00:08:46 +00005692 int fd;
5693 STRUCT_STAT st;
5694 int res;
5695 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5696 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005697#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00005698 /* on OpenVMS we must ensure that all bytes are written to the file */
5699 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005700#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005701 if (!_PyVerify_fd(fd))
5702 return posix_error();
5703 Py_BEGIN_ALLOW_THREADS
5704 res = FSTAT(fd, &st);
5705 Py_END_ALLOW_THREADS
5706 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00005707#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005708 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00005709#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005710 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005711#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005712 }
Tim Peters5aa91602002-01-30 05:46:57 +00005713
Victor Stinner8c62be82010-05-06 00:08:46 +00005714 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005715}
5716
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005717PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005718"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005719Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005720connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005721
5722static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005723posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005724{
Victor Stinner8c62be82010-05-06 00:08:46 +00005725 int fd;
5726 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5727 return NULL;
5728 if (!_PyVerify_fd(fd))
5729 return PyBool_FromLong(0);
5730 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005731}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005732
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005733#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005734PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005735"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005736Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005737
Barry Warsaw53699e91996-12-10 23:23:01 +00005738static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005739posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005740{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005741#if defined(PYOS_OS2)
5742 HFILE read, write;
5743 APIRET rc;
5744
Victor Stinner8c62be82010-05-06 00:08:46 +00005745 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005746 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinner8c62be82010-05-06 00:08:46 +00005747 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005748 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005749 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005750
5751 return Py_BuildValue("(ii)", read, write);
5752#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005753#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005754 int fds[2];
5755 int res;
5756 Py_BEGIN_ALLOW_THREADS
5757 res = pipe(fds);
5758 Py_END_ALLOW_THREADS
5759 if (res != 0)
5760 return posix_error();
5761 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005762#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00005763 HANDLE read, write;
5764 int read_fd, write_fd;
5765 BOOL ok;
5766 Py_BEGIN_ALLOW_THREADS
5767 ok = CreatePipe(&read, &write, NULL, 0);
5768 Py_END_ALLOW_THREADS
5769 if (!ok)
5770 return win32_error("CreatePipe", NULL);
5771 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5772 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5773 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005774#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005775#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005776}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005777#endif /* HAVE_PIPE */
5778
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005779
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005780#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005781PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005782"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005783Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005784
Barry Warsaw53699e91996-12-10 23:23:01 +00005785static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005786posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005787{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005788 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005789 char *filename;
5790 int mode = 0666;
5791 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005792 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
5793 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00005794 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005795 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005796 Py_BEGIN_ALLOW_THREADS
5797 res = mkfifo(filename, mode);
5798 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005799 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005800 if (res < 0)
5801 return posix_error();
5802 Py_INCREF(Py_None);
5803 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005804}
5805#endif
5806
5807
Neal Norwitz11690112002-07-30 01:08:28 +00005808#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005809PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005810"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005811Create a filesystem node (file, device special file or named pipe)\n\
5812named filename. mode specifies both the permissions to use and the\n\
5813type of node to be created, being combined (bitwise OR) with one of\n\
5814S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005815device defines the newly created device special file (probably using\n\
5816os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005817
5818
5819static PyObject *
5820posix_mknod(PyObject *self, PyObject *args)
5821{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005822 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005823 char *filename;
5824 int mode = 0600;
5825 int device = 0;
5826 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005827 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
5828 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00005829 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005830 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005831 Py_BEGIN_ALLOW_THREADS
5832 res = mknod(filename, mode, device);
5833 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005834 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005835 if (res < 0)
5836 return posix_error();
5837 Py_INCREF(Py_None);
5838 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005839}
5840#endif
5841
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005842#ifdef HAVE_DEVICE_MACROS
5843PyDoc_STRVAR(posix_major__doc__,
5844"major(device) -> major number\n\
5845Extracts a device major number from a raw device number.");
5846
5847static PyObject *
5848posix_major(PyObject *self, PyObject *args)
5849{
Victor Stinner8c62be82010-05-06 00:08:46 +00005850 int device;
5851 if (!PyArg_ParseTuple(args, "i:major", &device))
5852 return NULL;
5853 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005854}
5855
5856PyDoc_STRVAR(posix_minor__doc__,
5857"minor(device) -> minor number\n\
5858Extracts a device minor number from a raw device number.");
5859
5860static PyObject *
5861posix_minor(PyObject *self, PyObject *args)
5862{
Victor Stinner8c62be82010-05-06 00:08:46 +00005863 int device;
5864 if (!PyArg_ParseTuple(args, "i:minor", &device))
5865 return NULL;
5866 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005867}
5868
5869PyDoc_STRVAR(posix_makedev__doc__,
5870"makedev(major, minor) -> device number\n\
5871Composes a raw device number from the major and minor device numbers.");
5872
5873static PyObject *
5874posix_makedev(PyObject *self, PyObject *args)
5875{
Victor Stinner8c62be82010-05-06 00:08:46 +00005876 int major, minor;
5877 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5878 return NULL;
5879 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005880}
5881#endif /* device macros */
5882
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005883
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005884#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005885PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005886"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005887Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005888
Barry Warsaw53699e91996-12-10 23:23:01 +00005889static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005890posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005891{
Victor Stinner8c62be82010-05-06 00:08:46 +00005892 int fd;
5893 off_t length;
5894 int res;
5895 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005896
Victor Stinner8c62be82010-05-06 00:08:46 +00005897 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
5898 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005899
5900#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005901 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005902#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005903 length = PyLong_Check(lenobj) ?
5904 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005905#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005906 if (PyErr_Occurred())
5907 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005908
Victor Stinner8c62be82010-05-06 00:08:46 +00005909 Py_BEGIN_ALLOW_THREADS
5910 res = ftruncate(fd, length);
5911 Py_END_ALLOW_THREADS
5912 if (res < 0)
5913 return posix_error();
5914 Py_INCREF(Py_None);
5915 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005916}
5917#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005918
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005919#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005920PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005921"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005922Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005923
Fred Drake762e2061999-08-26 17:23:54 +00005924/* Save putenv() parameters as values here, so we can collect them when they
5925 * get re-set with another call for the same key. */
5926static PyObject *posix_putenv_garbage;
5927
Tim Peters5aa91602002-01-30 05:46:57 +00005928static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005929posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005930{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005931#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005932 wchar_t *s1, *s2;
5933 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005934#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005935 PyObject *os1, *os2;
5936 char *s1, *s2;
5937 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005938#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005939 PyObject *newstr = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005940 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005941
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005942#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005943 if (!PyArg_ParseTuple(args,
5944 "uu:putenv",
5945 &s1, &s2))
5946 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005947#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005948 if (!PyArg_ParseTuple(args,
5949 "O&O&:putenv",
5950 PyUnicode_FSConverter, &os1,
5951 PyUnicode_FSConverter, &os2))
5952 return NULL;
5953 s1 = PyBytes_AsString(os1);
5954 s2 = PyBytes_AsString(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005955#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005956
5957#if defined(PYOS_OS2)
5958 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5959 APIRET rc;
5960
Guido van Rossumd48f2521997-12-05 22:19:34 +00005961 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005962 if (rc != NO_ERROR) {
5963 os2_error(rc);
5964 goto error;
5965 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005966
5967 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5968 APIRET rc;
5969
Guido van Rossumd48f2521997-12-05 22:19:34 +00005970 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005971 if (rc != NO_ERROR) {
5972 os2_error(rc);
5973 goto error;
5974 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005975 } else {
5976#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005977 /* XXX This can leak memory -- not easy to fix :-( */
5978 /* len includes space for a trailing \0; the size arg to
5979 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005980#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005981 len = wcslen(s1) + wcslen(s2) + 2;
5982 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005983#else
Victor Stinner84ae1182010-05-06 22:05:07 +00005984 len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2;
Victor Stinner8c62be82010-05-06 00:08:46 +00005985 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005986#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005987 if (newstr == NULL) {
5988 PyErr_NoMemory();
5989 goto error;
5990 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005991#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005992 newenv = PyUnicode_AsUnicode(newstr);
5993 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5994 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005995 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00005996 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005997 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005998#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005999 newenv = PyBytes_AS_STRING(newstr);
6000 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6001 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006002 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00006003 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006004 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006005#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006006
Victor Stinner8c62be82010-05-06 00:08:46 +00006007 /* Install the first arg and newstr in posix_putenv_garbage;
6008 * this will cause previous value to be collected. This has to
6009 * happen after the real putenv() call because the old value
6010 * was still accessible until then. */
6011 if (PyDict_SetItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00006012#ifdef MS_WINDOWS
6013 PyTuple_GET_ITEM(args, 0),
6014#else
6015 os1,
6016#endif
6017 newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006018 /* really not much we can do; just leak */
6019 PyErr_Clear();
6020 }
6021 else {
6022 Py_DECREF(newstr);
6023 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006024
6025#if defined(PYOS_OS2)
6026 }
6027#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006028
Martin v. Löwis011e8422009-05-05 04:43:17 +00006029#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006030 Py_DECREF(os1);
6031 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00006032#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006033 Py_RETURN_NONE;
6034
6035error:
6036#ifndef MS_WINDOWS
6037 Py_DECREF(os1);
6038 Py_DECREF(os2);
6039#endif
6040 Py_XDECREF(newstr);
6041 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006042}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006043#endif /* putenv */
6044
Guido van Rossumc524d952001-10-19 01:31:59 +00006045#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006046PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006047"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006048Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006049
6050static PyObject *
6051posix_unsetenv(PyObject *self, PyObject *args)
6052{
Victor Stinner84ae1182010-05-06 22:05:07 +00006053#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006054 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00006055
Victor Stinner8c62be82010-05-06 00:08:46 +00006056 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6057 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00006058#else
6059 PyObject *os1;
6060 char *s1;
6061
6062 if (!PyArg_ParseTuple(args, "O&:unsetenv",
6063 PyUnicode_FSConverter, &os1))
6064 return NULL;
6065 s1 = PyBytes_AsString(os1);
6066#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006067
Victor Stinner8c62be82010-05-06 00:08:46 +00006068 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00006069
Victor Stinner8c62be82010-05-06 00:08:46 +00006070 /* Remove the key from posix_putenv_garbage;
6071 * this will cause it to be collected. This has to
6072 * happen after the real unsetenv() call because the
6073 * old value was still accessible until then.
6074 */
6075 if (PyDict_DelItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00006076#ifdef MS_WINDOWS
6077 PyTuple_GET_ITEM(args, 0)
6078#else
6079 os1
6080#endif
6081 )) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006082 /* really not much we can do; just leak */
6083 PyErr_Clear();
6084 }
Guido van Rossumc524d952001-10-19 01:31:59 +00006085
Victor Stinner84ae1182010-05-06 22:05:07 +00006086#ifndef MS_WINDOWS
6087 Py_DECREF(os1);
6088#endif
6089 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00006090}
6091#endif /* unsetenv */
6092
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006093PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006094"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006095Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006096
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006097static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006098posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006099{
Victor Stinner8c62be82010-05-06 00:08:46 +00006100 int code;
6101 char *message;
6102 if (!PyArg_ParseTuple(args, "i:strerror", &code))
6103 return NULL;
6104 message = strerror(code);
6105 if (message == NULL) {
6106 PyErr_SetString(PyExc_ValueError,
6107 "strerror() argument out of range");
6108 return NULL;
6109 }
6110 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006111}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006112
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006113
Guido van Rossumc9641791998-08-04 15:26:23 +00006114#ifdef HAVE_SYS_WAIT_H
6115
Fred Drake106c1a02002-04-23 15:58:02 +00006116#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006117PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006118"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006119Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006120
6121static PyObject *
6122posix_WCOREDUMP(PyObject *self, PyObject *args)
6123{
Victor Stinner8c62be82010-05-06 00:08:46 +00006124 WAIT_TYPE status;
6125 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006126
Victor Stinner8c62be82010-05-06 00:08:46 +00006127 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
6128 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006129
Victor Stinner8c62be82010-05-06 00:08:46 +00006130 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006131}
6132#endif /* WCOREDUMP */
6133
6134#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006135PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006136"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006137Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006138job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006139
6140static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006141posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006142{
Victor Stinner8c62be82010-05-06 00:08:46 +00006143 WAIT_TYPE status;
6144 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006145
Victor Stinner8c62be82010-05-06 00:08:46 +00006146 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
6147 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006148
Victor Stinner8c62be82010-05-06 00:08:46 +00006149 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006150}
6151#endif /* WIFCONTINUED */
6152
Guido van Rossumc9641791998-08-04 15:26:23 +00006153#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006154PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006155"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006156Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006157
6158static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006159posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006160{
Victor Stinner8c62be82010-05-06 00:08:46 +00006161 WAIT_TYPE status;
6162 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006163
Victor Stinner8c62be82010-05-06 00:08:46 +00006164 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
6165 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006166
Victor Stinner8c62be82010-05-06 00:08:46 +00006167 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006168}
6169#endif /* WIFSTOPPED */
6170
6171#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006172PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006173"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006174Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006175
6176static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006177posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006178{
Victor Stinner8c62be82010-05-06 00:08:46 +00006179 WAIT_TYPE status;
6180 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006181
Victor Stinner8c62be82010-05-06 00:08:46 +00006182 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
6183 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006184
Victor Stinner8c62be82010-05-06 00:08:46 +00006185 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006186}
6187#endif /* WIFSIGNALED */
6188
6189#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006190PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006191"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006192Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006193system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006194
6195static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006196posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006197{
Victor Stinner8c62be82010-05-06 00:08:46 +00006198 WAIT_TYPE status;
6199 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006200
Victor Stinner8c62be82010-05-06 00:08:46 +00006201 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
6202 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006203
Victor Stinner8c62be82010-05-06 00:08:46 +00006204 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006205}
6206#endif /* WIFEXITED */
6207
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006208#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006209PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006210"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006211Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006212
6213static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006214posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006215{
Victor Stinner8c62be82010-05-06 00:08:46 +00006216 WAIT_TYPE status;
6217 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006218
Victor Stinner8c62be82010-05-06 00:08:46 +00006219 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
6220 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006221
Victor Stinner8c62be82010-05-06 00:08:46 +00006222 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006223}
6224#endif /* WEXITSTATUS */
6225
6226#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006227PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006228"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006229Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006230value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006231
6232static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006233posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006234{
Victor Stinner8c62be82010-05-06 00:08:46 +00006235 WAIT_TYPE status;
6236 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006237
Victor Stinner8c62be82010-05-06 00:08:46 +00006238 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
6239 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006240
Victor Stinner8c62be82010-05-06 00:08:46 +00006241 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006242}
6243#endif /* WTERMSIG */
6244
6245#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006246PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006247"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006248Return the signal that stopped the process that provided\n\
6249the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006250
6251static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006252posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006253{
Victor Stinner8c62be82010-05-06 00:08:46 +00006254 WAIT_TYPE status;
6255 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006256
Victor Stinner8c62be82010-05-06 00:08:46 +00006257 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
6258 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006259
Victor Stinner8c62be82010-05-06 00:08:46 +00006260 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006261}
6262#endif /* WSTOPSIG */
6263
6264#endif /* HAVE_SYS_WAIT_H */
6265
6266
Thomas Wouters477c8d52006-05-27 19:21:47 +00006267#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006268#ifdef _SCO_DS
6269/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6270 needed definitions in sys/statvfs.h */
6271#define _SVID3
6272#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006273#include <sys/statvfs.h>
6274
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006275static PyObject*
6276_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006277 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6278 if (v == NULL)
6279 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006280
6281#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006282 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6283 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6284 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
6285 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
6286 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
6287 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
6288 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
6289 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
6290 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6291 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006292#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006293 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6294 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6295 PyStructSequence_SET_ITEM(v, 2,
6296 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
6297 PyStructSequence_SET_ITEM(v, 3,
6298 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
6299 PyStructSequence_SET_ITEM(v, 4,
6300 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
6301 PyStructSequence_SET_ITEM(v, 5,
6302 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
6303 PyStructSequence_SET_ITEM(v, 6,
6304 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
6305 PyStructSequence_SET_ITEM(v, 7,
6306 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
6307 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6308 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006309#endif
6310
Victor Stinner8c62be82010-05-06 00:08:46 +00006311 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006312}
6313
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006314PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006315"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006316Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006317
6318static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006319posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006320{
Victor Stinner8c62be82010-05-06 00:08:46 +00006321 int fd, res;
6322 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006323
Victor Stinner8c62be82010-05-06 00:08:46 +00006324 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
6325 return NULL;
6326 Py_BEGIN_ALLOW_THREADS
6327 res = fstatvfs(fd, &st);
6328 Py_END_ALLOW_THREADS
6329 if (res != 0)
6330 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006331
Victor Stinner8c62be82010-05-06 00:08:46 +00006332 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006333}
Thomas Wouters477c8d52006-05-27 19:21:47 +00006334#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006335
6336
Thomas Wouters477c8d52006-05-27 19:21:47 +00006337#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006338#include <sys/statvfs.h>
6339
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006340PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006341"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006342Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006343
6344static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006345posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006346{
Victor Stinner8c62be82010-05-06 00:08:46 +00006347 char *path;
6348 int res;
6349 struct statvfs st;
6350 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
6351 return NULL;
6352 Py_BEGIN_ALLOW_THREADS
6353 res = statvfs(path, &st);
6354 Py_END_ALLOW_THREADS
6355 if (res != 0)
6356 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006357
Victor Stinner8c62be82010-05-06 00:08:46 +00006358 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006359}
6360#endif /* HAVE_STATVFS */
6361
Fred Drakec9680921999-12-13 16:37:25 +00006362/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6363 * It maps strings representing configuration variable names to
6364 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006365 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006366 * rarely-used constants. There are three separate tables that use
6367 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006368 *
6369 * This code is always included, even if none of the interfaces that
6370 * need it are included. The #if hackery needed to avoid it would be
6371 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006372 */
6373struct constdef {
6374 char *name;
6375 long value;
6376};
6377
Fred Drake12c6e2d1999-12-14 21:25:03 +00006378static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006379conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00006380 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006381{
Christian Heimes217cfd12007-12-02 14:31:20 +00006382 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006383 *valuep = PyLong_AS_LONG(arg);
6384 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006385 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00006386 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00006387 /* look up the value in the table using a binary search */
6388 size_t lo = 0;
6389 size_t mid;
6390 size_t hi = tablesize;
6391 int cmp;
6392 const char *confname;
6393 if (!PyUnicode_Check(arg)) {
6394 PyErr_SetString(PyExc_TypeError,
6395 "configuration names must be strings or integers");
6396 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006397 }
Stefan Krah0e803b32010-11-26 16:16:47 +00006398 confname = _PyUnicode_AsString(arg);
6399 if (confname == NULL)
6400 return 0;
6401 while (lo < hi) {
6402 mid = (lo + hi) / 2;
6403 cmp = strcmp(confname, table[mid].name);
6404 if (cmp < 0)
6405 hi = mid;
6406 else if (cmp > 0)
6407 lo = mid + 1;
6408 else {
6409 *valuep = table[mid].value;
6410 return 1;
6411 }
6412 }
6413 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6414 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006415 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00006416}
6417
6418
6419#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6420static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006421#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006422 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006423#endif
6424#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006425 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006426#endif
Fred Drakec9680921999-12-13 16:37:25 +00006427#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006428 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006429#endif
6430#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00006431 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00006432#endif
6433#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00006434 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00006435#endif
6436#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00006437 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00006438#endif
6439#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006440 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006441#endif
6442#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00006443 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00006444#endif
6445#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00006446 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00006447#endif
6448#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006449 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006450#endif
6451#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006452 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00006453#endif
6454#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006455 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006456#endif
6457#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006458 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00006459#endif
6460#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006461 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006462#endif
6463#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006464 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00006465#endif
6466#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006467 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006468#endif
6469#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00006470 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00006471#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00006472#ifdef _PC_ACL_ENABLED
6473 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
6474#endif
6475#ifdef _PC_MIN_HOLE_SIZE
6476 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
6477#endif
6478#ifdef _PC_ALLOC_SIZE_MIN
6479 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
6480#endif
6481#ifdef _PC_REC_INCR_XFER_SIZE
6482 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
6483#endif
6484#ifdef _PC_REC_MAX_XFER_SIZE
6485 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
6486#endif
6487#ifdef _PC_REC_MIN_XFER_SIZE
6488 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
6489#endif
6490#ifdef _PC_REC_XFER_ALIGN
6491 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
6492#endif
6493#ifdef _PC_SYMLINK_MAX
6494 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
6495#endif
6496#ifdef _PC_XATTR_ENABLED
6497 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
6498#endif
6499#ifdef _PC_XATTR_EXISTS
6500 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
6501#endif
6502#ifdef _PC_TIMESTAMP_RESOLUTION
6503 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
6504#endif
Fred Drakec9680921999-12-13 16:37:25 +00006505};
6506
Fred Drakec9680921999-12-13 16:37:25 +00006507static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006508conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006509{
6510 return conv_confname(arg, valuep, posix_constants_pathconf,
6511 sizeof(posix_constants_pathconf)
6512 / sizeof(struct constdef));
6513}
6514#endif
6515
6516#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006517PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006518"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006519Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006520If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006521
6522static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006523posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006524{
6525 PyObject *result = NULL;
6526 int name, fd;
6527
Fred Drake12c6e2d1999-12-14 21:25:03 +00006528 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6529 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006530 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006531
Stefan Krah0e803b32010-11-26 16:16:47 +00006532 errno = 0;
6533 limit = fpathconf(fd, name);
6534 if (limit == -1 && errno != 0)
6535 posix_error();
6536 else
6537 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006538 }
6539 return result;
6540}
6541#endif
6542
6543
6544#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006545PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006546"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006547Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006548If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006549
6550static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006551posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006552{
6553 PyObject *result = NULL;
6554 int name;
6555 char *path;
6556
6557 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6558 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006559 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006560
Victor Stinner8c62be82010-05-06 00:08:46 +00006561 errno = 0;
6562 limit = pathconf(path, name);
6563 if (limit == -1 && errno != 0) {
6564 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00006565 /* could be a path or name problem */
6566 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00006567 else
Stefan Krah99439262010-11-26 12:58:05 +00006568 posix_error_with_filename(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00006569 }
6570 else
6571 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006572 }
6573 return result;
6574}
6575#endif
6576
6577#ifdef HAVE_CONFSTR
6578static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006579#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00006580 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00006581#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00006582#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006583 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006584#endif
6585#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006586 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006587#endif
Fred Draked86ed291999-12-15 15:34:33 +00006588#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006589 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006590#endif
6591#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006592 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006593#endif
6594#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006595 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006596#endif
6597#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006598 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006599#endif
Fred Drakec9680921999-12-13 16:37:25 +00006600#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006601 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006602#endif
6603#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006604 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006605#endif
6606#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006607 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006608#endif
6609#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006610 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006611#endif
6612#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006613 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006614#endif
6615#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006616 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006617#endif
6618#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006619 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006620#endif
6621#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006622 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006623#endif
Fred Draked86ed291999-12-15 15:34:33 +00006624#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00006625 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00006626#endif
Fred Drakec9680921999-12-13 16:37:25 +00006627#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00006628 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00006629#endif
Fred Draked86ed291999-12-15 15:34:33 +00006630#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006631 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00006632#endif
6633#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006634 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00006635#endif
6636#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006637 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006638#endif
6639#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006640 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00006641#endif
Fred Drakec9680921999-12-13 16:37:25 +00006642#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006643 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006644#endif
6645#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006646 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006647#endif
6648#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006649 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006650#endif
6651#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006652 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006653#endif
6654#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006655 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006656#endif
6657#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006658 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006659#endif
6660#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006661 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006662#endif
6663#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006664 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006665#endif
6666#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006667 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006668#endif
6669#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006670 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006671#endif
6672#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006673 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006674#endif
6675#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006676 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006677#endif
6678#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006679 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006680#endif
6681#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006682 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006683#endif
6684#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006685 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006686#endif
6687#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006688 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006689#endif
Fred Draked86ed291999-12-15 15:34:33 +00006690#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006691 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006692#endif
6693#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006694 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00006695#endif
6696#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00006697 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00006698#endif
6699#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006700 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006701#endif
6702#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006703 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006704#endif
6705#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00006706 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00006707#endif
6708#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006709 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00006710#endif
6711#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00006712 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00006713#endif
6714#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006715 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006716#endif
6717#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006718 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006719#endif
6720#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006721 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006722#endif
6723#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006724 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006725#endif
6726#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00006727 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00006728#endif
Fred Drakec9680921999-12-13 16:37:25 +00006729};
6730
6731static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006732conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006733{
6734 return conv_confname(arg, valuep, posix_constants_confstr,
6735 sizeof(posix_constants_confstr)
6736 / sizeof(struct constdef));
6737}
6738
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006739PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006740"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006741Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006742
6743static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006744posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006745{
6746 PyObject *result = NULL;
6747 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00006748 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00006749 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006750
Victor Stinnercb043522010-09-10 23:49:04 +00006751 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
6752 return NULL;
6753
6754 errno = 0;
6755 len = confstr(name, buffer, sizeof(buffer));
6756 if (len == 0) {
6757 if (errno) {
6758 posix_error();
6759 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00006760 }
6761 else {
Victor Stinnercb043522010-09-10 23:49:04 +00006762 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00006763 }
6764 }
Victor Stinnercb043522010-09-10 23:49:04 +00006765
6766 if ((unsigned int)len >= sizeof(buffer)) {
6767 char *buf = PyMem_Malloc(len);
6768 if (buf == NULL)
6769 return PyErr_NoMemory();
6770 confstr(name, buf, len);
6771 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
6772 PyMem_Free(buf);
6773 }
6774 else
6775 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006776 return result;
6777}
6778#endif
6779
6780
6781#ifdef HAVE_SYSCONF
6782static struct constdef posix_constants_sysconf[] = {
6783#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00006784 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00006785#endif
6786#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00006787 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00006788#endif
6789#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006790 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006791#endif
6792#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006793 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006794#endif
6795#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006796 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006797#endif
6798#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00006800#endif
6801#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00006803#endif
6804#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006805 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006806#endif
6807#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00006808 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00006809#endif
6810#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006811 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006812#endif
Fred Draked86ed291999-12-15 15:34:33 +00006813#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006814 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006815#endif
6816#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00006818#endif
Fred Drakec9680921999-12-13 16:37:25 +00006819#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006820 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006821#endif
Fred Drakec9680921999-12-13 16:37:25 +00006822#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006823 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006824#endif
6825#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006827#endif
6828#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006829 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006830#endif
6831#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006832 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006833#endif
6834#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006835 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006836#endif
Fred Draked86ed291999-12-15 15:34:33 +00006837#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006838 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00006839#endif
Fred Drakec9680921999-12-13 16:37:25 +00006840#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00006841 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006842#endif
6843#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006844 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006845#endif
6846#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006847 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006848#endif
6849#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006850 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006851#endif
6852#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006853 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006854#endif
Fred Draked86ed291999-12-15 15:34:33 +00006855#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00006856 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00006857#endif
Fred Drakec9680921999-12-13 16:37:25 +00006858#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006859 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006860#endif
6861#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006862 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006863#endif
6864#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006865 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006866#endif
6867#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006869#endif
6870#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006871 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006872#endif
6873#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006874 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00006875#endif
6876#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006877 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006878#endif
6879#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006880 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006881#endif
6882#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006883 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006884#endif
6885#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006886 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006887#endif
6888#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006889 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006890#endif
6891#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006892 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006893#endif
6894#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006895 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006896#endif
6897#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006898 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006899#endif
6900#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006901 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006902#endif
6903#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006904 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006905#endif
6906#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006907 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00006908#endif
6909#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006910 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006911#endif
6912#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006913 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006914#endif
6915#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006916 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006917#endif
6918#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006919 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006920#endif
6921#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006922 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006923#endif
6924#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006925 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006926#endif
Fred Draked86ed291999-12-15 15:34:33 +00006927#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00006928 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00006929#endif
Fred Drakec9680921999-12-13 16:37:25 +00006930#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006931 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006932#endif
6933#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006934 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006935#endif
6936#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006937 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006938#endif
Fred Draked86ed291999-12-15 15:34:33 +00006939#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006940 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00006941#endif
Fred Drakec9680921999-12-13 16:37:25 +00006942#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00006943 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00006944#endif
Fred Draked86ed291999-12-15 15:34:33 +00006945#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00006946 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00006947#endif
6948#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00006949 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00006950#endif
Fred Drakec9680921999-12-13 16:37:25 +00006951#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006952 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006953#endif
6954#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006955 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006956#endif
6957#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006958 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006959#endif
6960#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006961 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006962#endif
Fred Draked86ed291999-12-15 15:34:33 +00006963#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00006964 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00006965#endif
Fred Drakec9680921999-12-13 16:37:25 +00006966#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00006967 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00006968#endif
6969#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00006970 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00006971#endif
6972#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006973 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006974#endif
6975#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006976 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00006977#endif
6978#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00006979 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00006980#endif
6981#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00006982 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00006983#endif
6984#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00006985 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00006986#endif
Fred Draked86ed291999-12-15 15:34:33 +00006987#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00006988 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00006989#endif
Fred Drakec9680921999-12-13 16:37:25 +00006990#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006991 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006992#endif
6993#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006994 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006995#endif
Fred Draked86ed291999-12-15 15:34:33 +00006996#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006997 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006998#endif
Fred Drakec9680921999-12-13 16:37:25 +00006999#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007000 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007001#endif
7002#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007003 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007004#endif
7005#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007006 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007007#endif
7008#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007009 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007010#endif
7011#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007012 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007013#endif
7014#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007015 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007016#endif
7017#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007018 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007019#endif
7020#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007021 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00007022#endif
7023#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00007024 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00007025#endif
Fred Draked86ed291999-12-15 15:34:33 +00007026#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007027 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00007028#endif
7029#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00007030 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00007031#endif
Fred Drakec9680921999-12-13 16:37:25 +00007032#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00007033 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00007034#endif
7035#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007036 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007037#endif
7038#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007039 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007040#endif
7041#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007042 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007043#endif
7044#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007045 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007046#endif
7047#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00007048 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00007049#endif
7050#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00007051 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00007052#endif
7053#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00007054 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00007055#endif
7056#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00007057 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00007058#endif
7059#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00007060 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00007061#endif
7062#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00007063 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00007064#endif
7065#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007066 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00007067#endif
7068#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007069 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00007070#endif
7071#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00007072 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00007073#endif
7074#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00007075 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00007076#endif
7077#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00007078 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00007079#endif
7080#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00007081 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00007082#endif
7083#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007084 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007085#endif
7086#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007087 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007088#endif
7089#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00007090 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00007091#endif
7092#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007093 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007094#endif
7095#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007096 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007097#endif
7098#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00007099 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00007100#endif
7101#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007102 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007103#endif
7104#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007105 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007106#endif
7107#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007108 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00007109#endif
7110#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00007111 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00007112#endif
7113#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007114 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007115#endif
7116#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007117 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007118#endif
7119#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007120 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00007121#endif
7122#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007123 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007124#endif
7125#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007126 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007127#endif
7128#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007129 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007130#endif
7131#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007132 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007133#endif
7134#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007135 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007136#endif
Fred Draked86ed291999-12-15 15:34:33 +00007137#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00007138 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00007139#endif
Fred Drakec9680921999-12-13 16:37:25 +00007140#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00007141 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00007142#endif
7143#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007144 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007145#endif
7146#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00007147 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00007148#endif
7149#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007150 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007151#endif
7152#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007153 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007154#endif
7155#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007156 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007157#endif
7158#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00007159 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00007160#endif
7161#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007162 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007163#endif
7164#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007165 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007166#endif
7167#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007168 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007169#endif
7170#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007171 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007172#endif
7173#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007174 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00007175#endif
7176#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007177 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00007178#endif
7179#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00007180 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00007181#endif
7182#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007183 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007184#endif
7185#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007186 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007187#endif
7188#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007189 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007190#endif
7191#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00007192 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00007193#endif
7194#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007195 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007196#endif
7197#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007198 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007199#endif
7200#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007201 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007202#endif
7203#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007204 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007205#endif
7206#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007207 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007208#endif
7209#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007210 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007211#endif
7212#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00007213 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00007214#endif
7215#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007216 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007217#endif
7218#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007219 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007220#endif
7221#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007222 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007223#endif
7224#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007225 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007226#endif
7227#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00007228 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00007229#endif
7230#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007231 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007232#endif
7233#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00007234 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00007235#endif
7236#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007237 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007238#endif
7239#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00007240 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00007241#endif
7242#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00007243 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00007244#endif
7245#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00007246 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00007247#endif
7248#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00007249 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00007250#endif
7251#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007252 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007253#endif
7254#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00007255 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00007256#endif
7257#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00007258 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00007259#endif
7260#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007261 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007262#endif
7263#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007264 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007265#endif
7266#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00007267 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00007268#endif
7269#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00007270 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00007271#endif
7272#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00007273 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00007274#endif
7275};
7276
7277static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007278conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007279{
7280 return conv_confname(arg, valuep, posix_constants_sysconf,
7281 sizeof(posix_constants_sysconf)
7282 / sizeof(struct constdef));
7283}
7284
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007285PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007286"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007287Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007288
7289static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007290posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007291{
7292 PyObject *result = NULL;
7293 int name;
7294
7295 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7296 int value;
7297
7298 errno = 0;
7299 value = sysconf(name);
7300 if (value == -1 && errno != 0)
7301 posix_error();
7302 else
Christian Heimes217cfd12007-12-02 14:31:20 +00007303 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00007304 }
7305 return result;
7306}
7307#endif
7308
7309
Fred Drakebec628d1999-12-15 18:31:10 +00007310/* This code is used to ensure that the tables of configuration value names
7311 * are in sorted order as required by conv_confname(), and also to build the
7312 * the exported dictionaries that are used to publish information about the
7313 * names available on the host platform.
7314 *
7315 * Sorting the table at runtime ensures that the table is properly ordered
7316 * when used, even for platforms we're not able to test on. It also makes
7317 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007318 */
Fred Drakebec628d1999-12-15 18:31:10 +00007319
7320static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007321cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007322{
7323 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007324 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00007325 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007326 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00007327
7328 return strcmp(c1->name, c2->name);
7329}
7330
7331static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007332setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00007333 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007334{
Fred Drakebec628d1999-12-15 18:31:10 +00007335 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007336 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007337
7338 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7339 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007340 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00007341 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007342
Barry Warsaw3155db32000-04-13 15:20:40 +00007343 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007344 PyObject *o = PyLong_FromLong(table[i].value);
7345 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7346 Py_XDECREF(o);
7347 Py_DECREF(d);
7348 return -1;
7349 }
7350 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007351 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007352 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007353}
7354
Fred Drakebec628d1999-12-15 18:31:10 +00007355/* Return -1 on failure, 0 on success. */
7356static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007357setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007358{
7359#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007360 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007361 sizeof(posix_constants_pathconf)
7362 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007363 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00007364 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007365#endif
7366#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007367 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007368 sizeof(posix_constants_confstr)
7369 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007370 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00007371 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007372#endif
7373#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007374 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007375 sizeof(posix_constants_sysconf)
7376 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007377 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00007378 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007379#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007380 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007381}
Fred Draked86ed291999-12-15 15:34:33 +00007382
7383
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007384PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007385"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007386Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007387in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007388
7389static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007390posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007391{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007392 abort();
7393 /*NOTREACHED*/
7394 Py_FatalError("abort() called from Python code didn't abort!");
7395 return NULL;
7396}
Fred Drakebec628d1999-12-15 18:31:10 +00007397
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007398#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007399PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007400"startfile(filepath [, operation]) - Start a file with its associated\n\
7401application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007402\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007403When \"operation\" is not specified or \"open\", this acts like\n\
7404double-clicking the file in Explorer, or giving the file name as an\n\
7405argument to the DOS \"start\" command: the file is opened with whatever\n\
7406application (if any) its extension is associated.\n\
7407When another \"operation\" is given, it specifies what should be done with\n\
7408the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007409\n\
7410startfile returns as soon as the associated application is launched.\n\
7411There is no option to wait for the application to close, and no way\n\
7412to retrieve the application's exit status.\n\
7413\n\
7414The filepath is relative to the current directory. If you want to use\n\
7415an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007416the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007417
7418static PyObject *
7419win32_startfile(PyObject *self, PyObject *args)
7420{
Victor Stinner8c62be82010-05-06 00:08:46 +00007421 PyObject *ofilepath;
7422 char *filepath;
7423 char *operation = NULL;
7424 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00007425
Victor Stinner8c62be82010-05-06 00:08:46 +00007426 PyObject *unipath, *woperation = NULL;
7427 if (!PyArg_ParseTuple(args, "U|s:startfile",
7428 &unipath, &operation)) {
7429 PyErr_Clear();
7430 goto normal;
7431 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007432
Victor Stinner8c62be82010-05-06 00:08:46 +00007433 if (operation) {
7434 woperation = PyUnicode_DecodeASCII(operation,
7435 strlen(operation), NULL);
7436 if (!woperation) {
7437 PyErr_Clear();
7438 operation = NULL;
7439 goto normal;
7440 }
7441 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007442
Victor Stinner8c62be82010-05-06 00:08:46 +00007443 Py_BEGIN_ALLOW_THREADS
7444 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
7445 PyUnicode_AS_UNICODE(unipath),
7446 NULL, NULL, SW_SHOWNORMAL);
7447 Py_END_ALLOW_THREADS
7448
7449 Py_XDECREF(woperation);
7450 if (rc <= (HINSTANCE)32) {
7451 PyObject *errval = win32_error_unicode("startfile",
7452 PyUnicode_AS_UNICODE(unipath));
7453 return errval;
7454 }
7455 Py_INCREF(Py_None);
7456 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007457
7458normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00007459 if (!PyArg_ParseTuple(args, "O&|s:startfile",
7460 PyUnicode_FSConverter, &ofilepath,
7461 &operation))
7462 return NULL;
7463 filepath = PyBytes_AsString(ofilepath);
7464 Py_BEGIN_ALLOW_THREADS
7465 rc = ShellExecute((HWND)0, operation, filepath,
7466 NULL, NULL, SW_SHOWNORMAL);
7467 Py_END_ALLOW_THREADS
7468 if (rc <= (HINSTANCE)32) {
7469 PyObject *errval = win32_error("startfile", filepath);
7470 Py_DECREF(ofilepath);
7471 return errval;
7472 }
7473 Py_DECREF(ofilepath);
7474 Py_INCREF(Py_None);
7475 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007476}
7477#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007478
Martin v. Löwis438b5342002-12-27 10:16:42 +00007479#ifdef HAVE_GETLOADAVG
7480PyDoc_STRVAR(posix_getloadavg__doc__,
7481"getloadavg() -> (float, float, float)\n\n\
7482Return the number of processes in the system run queue averaged over\n\
7483the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7484was unobtainable");
7485
7486static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007487posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007488{
7489 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007490 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00007491 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7492 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00007493 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00007494 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00007495}
7496#endif
7497
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007498#ifdef MS_WINDOWS
7499
7500PyDoc_STRVAR(win32_urandom__doc__,
7501"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007502Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007503
7504typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7505 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7506 DWORD dwFlags );
7507typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7508 BYTE *pbBuffer );
7509
7510static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00007511/* This handle is never explicitly released. Instead, the operating
7512 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007513static HCRYPTPROV hCryptProv = 0;
7514
Tim Peters4ad82172004-08-30 17:02:04 +00007515static PyObject*
7516win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007517{
Victor Stinner8c62be82010-05-06 00:08:46 +00007518 int howMany;
7519 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007520
Victor Stinner8c62be82010-05-06 00:08:46 +00007521 /* Read arguments */
7522 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7523 return NULL;
7524 if (howMany < 0)
7525 return PyErr_Format(PyExc_ValueError,
7526 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007527
Victor Stinner8c62be82010-05-06 00:08:46 +00007528 if (hCryptProv == 0) {
7529 HINSTANCE hAdvAPI32 = NULL;
7530 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007531
Victor Stinner8c62be82010-05-06 00:08:46 +00007532 /* Obtain handle to the DLL containing CryptoAPI
7533 This should not fail */
7534 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7535 if(hAdvAPI32 == NULL)
7536 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007537
Victor Stinner8c62be82010-05-06 00:08:46 +00007538 /* Obtain pointers to the CryptoAPI functions
7539 This will fail on some early versions of Win95 */
7540 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7541 hAdvAPI32,
7542 "CryptAcquireContextA");
7543 if (pCryptAcquireContext == NULL)
7544 return PyErr_Format(PyExc_NotImplementedError,
7545 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007546
Victor Stinner8c62be82010-05-06 00:08:46 +00007547 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7548 hAdvAPI32, "CryptGenRandom");
7549 if (pCryptGenRandom == NULL)
7550 return PyErr_Format(PyExc_NotImplementedError,
7551 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007552
Victor Stinner8c62be82010-05-06 00:08:46 +00007553 /* Acquire context */
7554 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7555 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7556 return win32_error("CryptAcquireContext", NULL);
7557 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007558
Victor Stinner8c62be82010-05-06 00:08:46 +00007559 /* Allocate bytes */
7560 result = PyBytes_FromStringAndSize(NULL, howMany);
7561 if (result != NULL) {
7562 /* Get random data */
7563 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
7564 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7565 PyBytes_AS_STRING(result))) {
7566 Py_DECREF(result);
7567 return win32_error("CryptGenRandom", NULL);
7568 }
7569 }
7570 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007571}
7572#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007573
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007574PyDoc_STRVAR(device_encoding__doc__,
7575"device_encoding(fd) -> str\n\n\
7576Return a string describing the encoding of the device\n\
7577if the output is a terminal; else return None.");
7578
7579static PyObject *
7580device_encoding(PyObject *self, PyObject *args)
7581{
Victor Stinner8c62be82010-05-06 00:08:46 +00007582 int fd;
7583 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
7584 return NULL;
7585 if (!_PyVerify_fd(fd) || !isatty(fd)) {
7586 Py_INCREF(Py_None);
7587 return Py_None;
7588 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007589#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner8c62be82010-05-06 00:08:46 +00007590 if (fd == 0) {
7591 char buf[100];
7592 sprintf(buf, "cp%d", GetConsoleCP());
7593 return PyUnicode_FromString(buf);
7594 }
7595 if (fd == 1 || fd == 2) {
7596 char buf[100];
7597 sprintf(buf, "cp%d", GetConsoleOutputCP());
7598 return PyUnicode_FromString(buf);
7599 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007600#elif defined(CODESET)
Victor Stinner8c62be82010-05-06 00:08:46 +00007601 {
7602 char *codeset = nl_langinfo(CODESET);
7603 if (codeset != NULL && codeset[0] != 0)
7604 return PyUnicode_FromString(codeset);
7605 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007606#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007607 Py_INCREF(Py_None);
7608 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007609}
7610
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007611#ifdef __VMS
7612/* Use openssl random routine */
7613#include <openssl/rand.h>
7614PyDoc_STRVAR(vms_urandom__doc__,
7615"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007616Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007617
7618static PyObject*
7619vms_urandom(PyObject *self, PyObject *args)
7620{
Victor Stinner8c62be82010-05-06 00:08:46 +00007621 int howMany;
7622 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007623
Victor Stinner8c62be82010-05-06 00:08:46 +00007624 /* Read arguments */
7625 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7626 return NULL;
7627 if (howMany < 0)
7628 return PyErr_Format(PyExc_ValueError,
7629 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007630
Victor Stinner8c62be82010-05-06 00:08:46 +00007631 /* Allocate bytes */
7632 result = PyBytes_FromStringAndSize(NULL, howMany);
7633 if (result != NULL) {
7634 /* Get random data */
7635 if (RAND_pseudo_bytes((unsigned char*)
7636 PyBytes_AS_STRING(result),
7637 howMany) < 0) {
7638 Py_DECREF(result);
7639 return PyErr_Format(PyExc_ValueError,
7640 "RAND_pseudo_bytes");
7641 }
7642 }
7643 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007644}
7645#endif
7646
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007647#ifdef HAVE_SETRESUID
7648PyDoc_STRVAR(posix_setresuid__doc__,
7649"setresuid(ruid, euid, suid)\n\n\
7650Set the current process's real, effective, and saved user ids.");
7651
7652static PyObject*
7653posix_setresuid (PyObject *self, PyObject *args)
7654{
Victor Stinner8c62be82010-05-06 00:08:46 +00007655 /* We assume uid_t is no larger than a long. */
7656 long ruid, euid, suid;
7657 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
7658 return NULL;
7659 if (setresuid(ruid, euid, suid) < 0)
7660 return posix_error();
7661 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007662}
7663#endif
7664
7665#ifdef HAVE_SETRESGID
7666PyDoc_STRVAR(posix_setresgid__doc__,
7667"setresgid(rgid, egid, sgid)\n\n\
7668Set the current process's real, effective, and saved group ids.");
7669
7670static PyObject*
7671posix_setresgid (PyObject *self, PyObject *args)
7672{
Victor Stinner8c62be82010-05-06 00:08:46 +00007673 /* We assume uid_t is no larger than a long. */
7674 long rgid, egid, sgid;
7675 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
7676 return NULL;
7677 if (setresgid(rgid, egid, sgid) < 0)
7678 return posix_error();
7679 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007680}
7681#endif
7682
7683#ifdef HAVE_GETRESUID
7684PyDoc_STRVAR(posix_getresuid__doc__,
7685"getresuid() -> (ruid, euid, suid)\n\n\
7686Get tuple of the current process's real, effective, and saved user ids.");
7687
7688static PyObject*
7689posix_getresuid (PyObject *self, PyObject *noargs)
7690{
Victor Stinner8c62be82010-05-06 00:08:46 +00007691 uid_t ruid, euid, suid;
7692 long l_ruid, l_euid, l_suid;
7693 if (getresuid(&ruid, &euid, &suid) < 0)
7694 return posix_error();
7695 /* Force the values into long's as we don't know the size of uid_t. */
7696 l_ruid = ruid;
7697 l_euid = euid;
7698 l_suid = suid;
7699 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007700}
7701#endif
7702
7703#ifdef HAVE_GETRESGID
7704PyDoc_STRVAR(posix_getresgid__doc__,
7705"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00007706Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007707
7708static PyObject*
7709posix_getresgid (PyObject *self, PyObject *noargs)
7710{
Victor Stinner8c62be82010-05-06 00:08:46 +00007711 uid_t rgid, egid, sgid;
7712 long l_rgid, l_egid, l_sgid;
7713 if (getresgid(&rgid, &egid, &sgid) < 0)
7714 return posix_error();
7715 /* Force the values into long's as we don't know the size of uid_t. */
7716 l_rgid = rgid;
7717 l_egid = egid;
7718 l_sgid = sgid;
7719 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007720}
7721#endif
7722
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007723static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00007724 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007725#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007726 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007727#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007728 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007729#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007730 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007731#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007732 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007733#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007734 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007735#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007736#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007737 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007738#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00007739#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007740 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007741#endif /* HAVE_LCHMOD */
7742#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007743 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007744#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00007745#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007746 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007747#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007748#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007749 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007750#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007751#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +00007752 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00007753#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007754#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +00007755 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007756#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007757#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +00007758 {"getcwd", (PyCFunction)posix_getcwd_unicode,
7759 METH_NOARGS, posix_getcwd__doc__},
7760 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
7761 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007762#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007763#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007764 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007765#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +00007766 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7767 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7768 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007769#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +00007770 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007771#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007772#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007773 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007774#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007775#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007776 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007777#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007778 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7779 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7780 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +00007781 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007782#ifdef HAVE_SYMLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007783 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007784#endif /* HAVE_SYMLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007785#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin74e45612010-07-09 15:58:59 +00007786 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
7787 win_symlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007788#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007789#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +00007790 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007791#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007792 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007793#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007794 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007795#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +00007796 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7797 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7798 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007799#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00007800 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007801#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00007802 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007803#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +00007804 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7805 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007806#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007807#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +00007808 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7809 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007810#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00007811 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7812 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007813#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007814#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007815#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +00007816 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007817#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007818#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +00007819 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007820#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007821#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +00007822 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007823#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007824#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007825 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007826#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007827#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007828 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007829#endif /* HAVE_GETEGID */
7830#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007831 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007832#endif /* HAVE_GETEUID */
7833#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007834 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007835#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007836#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007837 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007838#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007839 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007840#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007841 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007842#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007843#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +00007844 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007845#endif /* HAVE_GETPPID */
7846#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007847 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007848#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007849#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007850 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007851#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007852#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +00007853 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007854#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007855#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +00007856 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007857#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007858#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007859 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007860#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007861#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007862 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7863 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Brian Curtin1b9df392010-11-24 20:24:31 +00007864 {"link", win32_link, METH_VARARGS, win32_link__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +00007865#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007866#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007867 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007868#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007869#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007870 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007871#endif /* HAVE_SETEUID */
7872#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007873 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007874#endif /* HAVE_SETEGID */
7875#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007876 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007877#endif /* HAVE_SETREUID */
7878#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007879 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007880#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007881#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007882 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007883#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007884#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007885 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007886#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +00007887#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007888 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +00007889#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007890#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007891 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00007892#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007893#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007894 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007895#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007896#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007897 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007898#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007899#ifdef HAVE_WAIT3
Victor Stinner8c62be82010-05-06 00:08:46 +00007900 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007901#endif /* HAVE_WAIT3 */
7902#ifdef HAVE_WAIT4
Victor Stinner8c62be82010-05-06 00:08:46 +00007903 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007904#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007905#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007906 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007907#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007908#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007909 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007910#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007911#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007912 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007913#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007914#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007915 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007916#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007917#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007918 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007919#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007920#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007921 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007922#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +00007923 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7924 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7925 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
7926 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
7927 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7928 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7929 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7930 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7931 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7932 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7933 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007934#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +00007935 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007936#endif
7937#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +00007938 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007939#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007940#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +00007941 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007942#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007943#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +00007944 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7945 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7946 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007947#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007948#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +00007949 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007950#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007951#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007952 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007953#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007954#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007955 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00007956#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007957 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007958#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +00007959 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007960#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007961#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007962 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007963#endif
7964#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007965 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007966#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007967#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007968#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +00007969 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00007970#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007971#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00007972 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007973#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007974#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +00007975 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007976#endif /* WIFSTOPPED */
7977#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +00007978 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007979#endif /* WIFSIGNALED */
7980#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +00007981 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007982#endif /* WIFEXITED */
7983#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +00007984 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007985#endif /* WEXITSTATUS */
7986#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007987 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007988#endif /* WTERMSIG */
7989#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007990 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007991#endif /* WSTOPSIG */
7992#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007993#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007994 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007995#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007996#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007997 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007998#endif
Fred Drakec9680921999-12-13 16:37:25 +00007999#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +00008000 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008001#endif
8002#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008003 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008004#endif
8005#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008006 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008007#endif
8008#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008009 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008010#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008011 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008012#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008013 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +00008014 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +00008015 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Mark Hammondef8b6542001-05-13 08:04:26 +00008016#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008017#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +00008018 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008019#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008020 #ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008021 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008022 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008023 #ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008024 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008025 #endif
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008026#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008027 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008028#endif
8029#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008030 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008031#endif
8032#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008033 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008034#endif
8035#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008036 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008037#endif
8038
Victor Stinner8c62be82010-05-06 00:08:46 +00008039 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008040};
8041
8042
Barry Warsaw4a342091996-12-19 23:50:02 +00008043static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008044ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008045{
Victor Stinner8c62be82010-05-06 00:08:46 +00008046 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008047}
8048
Guido van Rossumd48f2521997-12-05 22:19:34 +00008049#if defined(PYOS_OS2)
8050/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008051static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008052{
8053 APIRET rc;
8054 ULONG values[QSV_MAX+1];
8055 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008056 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008057
8058 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008059 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008060 Py_END_ALLOW_THREADS
8061
8062 if (rc != NO_ERROR) {
8063 os2_error(rc);
8064 return -1;
8065 }
8066
Fred Drake4d1e64b2002-04-15 19:40:07 +00008067 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8068 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8069 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8070 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8071 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8072 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8073 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008074
8075 switch (values[QSV_VERSION_MINOR]) {
8076 case 0: ver = "2.00"; break;
8077 case 10: ver = "2.10"; break;
8078 case 11: ver = "2.11"; break;
8079 case 30: ver = "3.00"; break;
8080 case 40: ver = "4.00"; break;
8081 case 50: ver = "5.00"; break;
8082 default:
Tim Peters885d4572001-11-28 20:27:42 +00008083 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +00008084 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00008085 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008086 ver = &tmp[0];
8087 }
8088
8089 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008090 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008091 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008092
8093 /* Add Indicator of Which Drive was Used to Boot the System */
8094 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8095 tmp[1] = ':';
8096 tmp[2] = '\0';
8097
Fred Drake4d1e64b2002-04-15 19:40:07 +00008098 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008099}
8100#endif
8101
Barry Warsaw4a342091996-12-19 23:50:02 +00008102static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008103all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008104{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008105#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008106 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008107#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008108#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008109 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008110#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008111#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008112 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008113#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008114#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008115 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008116#endif
Fred Drakec9680921999-12-13 16:37:25 +00008117#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008118 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00008119#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008120#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008121 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008122#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008123#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00008124 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008125#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008126#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +00008127 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008128#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008129#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +00008130 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008131#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008132#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008133 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008134#endif
8135#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008136 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008137#endif
8138#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +00008139 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008140#endif
8141#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +00008142 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008143#endif
8144#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008145 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008146#endif
8147#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +00008148 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008149#endif
8150#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008151 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008152#endif
8153#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008154 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008155#endif
8156#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008157 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008158#endif
8159#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +00008160 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008161#endif
8162#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008163 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008164#endif
8165#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +00008166 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008167#endif
8168#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008169 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008170#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008171#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008172 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008173#endif
8174#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +00008175 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008176#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008177#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008178 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008179#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008180#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008181 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008182#endif
8183#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008184 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008185#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008186
Tim Peters5aa91602002-01-30 05:46:57 +00008187/* MS Windows */
8188#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008189 /* Don't inherit in child processes. */
8190 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008191#endif
8192#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +00008193 /* Optimize for short life (keep in memory). */
8194 /* MS forgot to define this one with a non-underscore form too. */
8195 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008196#endif
8197#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008198 /* Automatically delete when last handle is closed. */
8199 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008200#endif
8201#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +00008202 /* Optimize for random access. */
8203 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008204#endif
8205#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008206 /* Optimize for sequential access. */
8207 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008208#endif
8209
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008210/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008211#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008212 /* Send a SIGIO signal whenever input or output
8213 becomes available on file descriptor */
8214 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008215#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008216#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008217 /* Direct disk access. */
8218 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008219#endif
8220#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +00008221 /* Must be a directory. */
8222 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008223#endif
8224#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +00008225 /* Do not follow links. */
8226 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008227#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008228#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +00008229 /* Do not update the access time. */
8230 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008231#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008232
Victor Stinner8c62be82010-05-06 00:08:46 +00008233 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008234#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008235 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008236#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008237#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008238 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008239#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008240#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008241 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008242#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008243#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008244 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008245#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008246#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +00008247 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008248#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008249#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +00008250 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008251#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008252#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008253 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008254#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008255#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +00008256 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008257#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008258#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008259 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008260#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008261#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008262 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008263#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008264#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008265 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008266#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008267#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008268 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008269#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008270#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +00008271 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008272#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008273#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +00008274 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008275#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008276#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008277 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008278#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008279#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008280 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008281#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008282#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +00008283 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008284#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008285
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008286 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008287#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008288 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008289#endif /* ST_RDONLY */
8290#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008291 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008292#endif /* ST_NOSUID */
8293
Guido van Rossum246bc171999-02-01 23:54:31 +00008294#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008295#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00008296 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8297 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8298 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8299 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8300 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8301 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8302 if (ins(d, "P_PM", (long)P_PM)) return -1;
8303 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8304 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8305 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8306 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8307 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8308 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8309 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8310 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8311 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8312 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8313 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8314 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8315 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008316#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008317 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8318 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8319 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8320 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8321 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008322#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008323#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008324
Guido van Rossumd48f2521997-12-05 22:19:34 +00008325#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00008326 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008327#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008328 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00008329}
8330
8331
Tim Peters5aa91602002-01-30 05:46:57 +00008332#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008333#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008334#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008335
8336#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008337#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008338#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008339
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008340#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00008341#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008342#define MODNAME "posix"
8343#endif
8344
Martin v. Löwis1a214512008-06-11 05:26:20 +00008345static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +00008346 PyModuleDef_HEAD_INIT,
8347 MODNAME,
8348 posix__doc__,
8349 -1,
8350 posix_methods,
8351 NULL,
8352 NULL,
8353 NULL,
8354 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00008355};
8356
8357
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008358PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008359INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008360{
Victor Stinner8c62be82010-05-06 00:08:46 +00008361 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008362
Victor Stinner8c62be82010-05-06 00:08:46 +00008363 m = PyModule_Create(&posixmodule);
8364 if (m == NULL)
8365 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008366
Victor Stinner8c62be82010-05-06 00:08:46 +00008367 /* Initialize environ dictionary */
8368 v = convertenviron();
8369 Py_XINCREF(v);
8370 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
8371 return NULL;
8372 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008373
Victor Stinner8c62be82010-05-06 00:08:46 +00008374 if (all_ins(m))
8375 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00008376
Victor Stinner8c62be82010-05-06 00:08:46 +00008377 if (setup_confname_tables(m))
8378 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00008379
Victor Stinner8c62be82010-05-06 00:08:46 +00008380 Py_INCREF(PyExc_OSError);
8381 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008382
Guido van Rossumb3d39562000-01-31 18:41:26 +00008383#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00008384 if (posix_putenv_garbage == NULL)
8385 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008386#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008387
Victor Stinner8c62be82010-05-06 00:08:46 +00008388 if (!initialized) {
8389 stat_result_desc.name = MODNAME ".stat_result";
8390 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8391 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8392 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8393 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8394 structseq_new = StatResultType.tp_new;
8395 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008396
Victor Stinner8c62be82010-05-06 00:08:46 +00008397 statvfs_result_desc.name = MODNAME ".statvfs_result";
8398 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008399#ifdef NEED_TICKS_PER_SECOND
8400# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +00008401 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008402# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +00008403 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008404# else
Victor Stinner8c62be82010-05-06 00:08:46 +00008405 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008406# endif
8407#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008408 }
8409 Py_INCREF((PyObject*) &StatResultType);
8410 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
8411 Py_INCREF((PyObject*) &StatVFSResultType);
8412 PyModule_AddObject(m, "statvfs_result",
8413 (PyObject*) &StatVFSResultType);
8414 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008415
8416#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +00008417 /*
8418 * Step 2 of weak-linking support on Mac OS X.
8419 *
8420 * The code below removes functions that are not available on the
8421 * currently active platform.
8422 *
8423 * This block allow one to use a python binary that was build on
8424 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8425 * OSX 10.4.
8426 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008427#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008428 if (fstatvfs == NULL) {
8429 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8430 return NULL;
8431 }
8432 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008433#endif /* HAVE_FSTATVFS */
8434
8435#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008436 if (statvfs == NULL) {
8437 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8438 return NULL;
8439 }
8440 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008441#endif /* HAVE_STATVFS */
8442
8443# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00008444 if (lchown == NULL) {
8445 if (PyObject_DelAttrString(m, "lchown") == -1) {
8446 return NULL;
8447 }
8448 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008449#endif /* HAVE_LCHOWN */
8450
8451
8452#endif /* __APPLE__ */
Victor Stinner8c62be82010-05-06 00:08:46 +00008453 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008454
Guido van Rossumb6775db1994-08-01 11:34:53 +00008455}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008456
8457#ifdef __cplusplus
8458}
8459#endif