blob: 59692622dae3d82c878c9573cd34743898b69d87 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Thomas Wouters477c8d52006-05-27 19:21:47 +000016#ifdef __APPLE__
17 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000018 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000019 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
20 * at the end of this file for more information.
21 */
22# pragma weak lchown
23# pragma weak statvfs
24# pragma weak fstatvfs
25
26#endif /* __APPLE__ */
27
Thomas Wouters68bc4f92006-03-01 01:05:10 +000028#define PY_SSIZE_T_CLEAN
29
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000030#include "Python.h"
31#include "structseq.h"
32
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000034# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000035#endif /* defined(__VMS) */
36
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000037#ifdef __cplusplus
38extern "C" {
39#endif
40
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000041PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000042"This module provides access to operating system functionality that is\n\
43standardized by the C Standard and the POSIX standard (a thinly\n\
44disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000045corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000047
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000048#if defined(PYOS_OS2)
49#define INCL_DOS
50#define INCL_DOSERRORS
51#define INCL_DOSPROCESS
52#define INCL_NOPMAPI
53#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000054#if defined(PYCC_GCC)
55#include <ctype.h>
56#include <io.h>
57#include <stdio.h>
58#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000059#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000060#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000061#endif
62
Thomas Wouters0e3f5912006-08-11 14:57:12 +000063#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000064#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000065#endif /* HAVE_SYS_TYPES_H */
66
67#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000068#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000069#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000070
Guido van Rossum36bc6801995-06-14 22:54:23 +000071#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000072#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000073#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000074
Thomas Wouters0e3f5912006-08-11 14:57:12 +000075#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000076#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000077#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000078
Guido van Rossumb6775db1994-08-01 11:34:53 +000079#ifdef HAVE_FCNTL_H
80#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000081#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000082
Guido van Rossuma6535fd2001-10-18 19:44:10 +000083#ifdef HAVE_GRP_H
84#include <grp.h>
85#endif
86
Barry Warsaw5676bd12003-01-07 20:57:09 +000087#ifdef HAVE_SYSEXITS_H
88#include <sysexits.h>
89#endif /* HAVE_SYSEXITS_H */
90
Anthony Baxter8a560de2004-10-13 15:30:56 +000091#ifdef HAVE_SYS_LOADAVG_H
92#include <sys/loadavg.h>
93#endif
94
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000095#ifdef HAVE_LANGINFO_H
96#include <langinfo.h>
97#endif
98
Guido van Rossuma4916fa1996-05-23 22:58:55 +000099/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000100/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000101#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000102#include <process.h>
103#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000104#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000105#define HAVE_GETCWD 1
106#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000107#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000108#if defined(__OS2__)
109#define HAVE_EXECV 1
110#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000111#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000112#include <process.h>
113#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000114#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000115#define HAVE_EXECV 1
116#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000117#define HAVE_OPENDIR 1
118#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000119#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000120#define HAVE_WAIT 1
121#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000122#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000123#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000124#define HAVE_GETPPID 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() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000279#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000280
Guido van Rossumd48f2521997-12-05 22:19:34 +0000281#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000283#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000284
Tim Petersbc2e10e2002-03-03 23:17:02 +0000285#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000286#if defined(PATH_MAX) && PATH_MAX > 1024
287#define MAXPATHLEN PATH_MAX
288#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000289#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000290#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000291#endif /* MAXPATHLEN */
292
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000293#ifdef UNION_WAIT
294/* Emulate some macros on systems that have a union instead of macros */
295
296#ifndef WIFEXITED
297#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
298#endif
299
300#ifndef WEXITSTATUS
301#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
302#endif
303
304#ifndef WTERMSIG
305#define WTERMSIG(u_wait) ((u_wait).w_termsig)
306#endif
307
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000308#define WAIT_TYPE union wait
309#define WAIT_STATUS_INT(s) (s.w_status)
310
311#else /* !UNION_WAIT */
312#define WAIT_TYPE int
313#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000314#endif /* UNION_WAIT */
315
Greg Wardb48bc172000-03-01 21:51:56 +0000316/* Don't use the "_r" form if we don't need it (also, won't have a
317 prototype for it, at least on Solaris -- maybe others as well?). */
318#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
319#define USE_CTERMID_R
320#endif
321
Fred Drake699f3522000-06-29 21:12:41 +0000322/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000323#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000324#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000325# define STAT win32_stat
326# define FSTAT win32_fstat
327# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000328#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000329# define STAT stat
330# define FSTAT fstat
331# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000332#endif
333
Tim Peters11b23062003-04-23 02:39:17 +0000334#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000335#include <sys/mkdev.h>
336#else
337#if defined(MAJOR_IN_SYSMACROS)
338#include <sys/sysmacros.h>
339#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000340#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
341#include <sys/mkdev.h>
342#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000343#endif
Fred Drake699f3522000-06-29 21:12:41 +0000344
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000345#if defined _MSC_VER && _MSC_VER >= 1400
346/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
347 * valid and throw an assertion if it isn't.
348 * Normally, an invalid fd is likely to be a C program error and therefore
349 * an assertion can be useful, but it does contradict the POSIX standard
350 * which for write(2) states:
351 * "Otherwise, -1 shall be returned and errno set to indicate the error."
352 * "[EBADF] The fildes argument is not a valid file descriptor open for
353 * writing."
354 * Furthermore, python allows the user to enter any old integer
355 * as a fd and should merely raise a python exception on error.
356 * The Microsoft CRT doesn't provide an official way to check for the
357 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000358 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000359 * internal structures involved.
360 * The structures below must be updated for each version of visual studio
361 * according to the file internal.h in the CRT source, until MS comes
362 * up with a less hacky way to do this.
363 * (all of this is to avoid globally modifying the CRT behaviour using
364 * _set_invalid_parameter_handler() and _CrtSetReportMode())
365 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000366/* The actual size of the structure is determined at runtime.
367 * Only the first items must be present.
368 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000369typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000370 intptr_t osfhnd;
371 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000372} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000373
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000374extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000375#define IOINFO_L2E 5
376#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
377#define IOINFO_ARRAYS 64
378#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
379#define FOPEN 0x01
380#define _NO_CONSOLE_FILENO (intptr_t)-2
381
382/* This function emulates what the windows CRT does to validate file handles */
383int
384_PyVerify_fd(int fd)
385{
Victor Stinner8c62be82010-05-06 00:08:46 +0000386 const int i1 = fd >> IOINFO_L2E;
387 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000388
Antoine Pitrou22e41552010-08-15 18:07:50 +0000389 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000390
Victor Stinner8c62be82010-05-06 00:08:46 +0000391 /* Determine the actual size of the ioinfo structure,
392 * as used by the CRT loaded in memory
393 */
394 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
395 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
396 }
397 if (sizeof_ioinfo == 0) {
398 /* This should not happen... */
399 goto fail;
400 }
401
402 /* See that it isn't a special CLEAR fileno */
403 if (fd != _NO_CONSOLE_FILENO) {
404 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
405 * we check pointer validity and other info
406 */
407 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
408 /* finally, check that the file is open */
409 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
410 if (info->osfile & FOPEN) {
411 return 1;
412 }
413 }
414 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000415 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000416 errno = EBADF;
417 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000418}
419
420/* the special case of checking dup2. The target fd must be in a sensible range */
421static int
422_PyVerify_fd_dup2(int fd1, int fd2)
423{
Victor Stinner8c62be82010-05-06 00:08:46 +0000424 if (!_PyVerify_fd(fd1))
425 return 0;
426 if (fd2 == _NO_CONSOLE_FILENO)
427 return 0;
428 if ((unsigned)fd2 < _NHANDLE_)
429 return 1;
430 else
431 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000432}
433#else
434/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
435#define _PyVerify_fd_dup2(A, B) (1)
436#endif
437
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000438/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000439#ifdef WITH_NEXT_FRAMEWORK
440/* On Darwin/MacOSX a shared library or framework has no access to
441** environ directly, we must obtain it with _NSGetEnviron().
442*/
443#include <crt_externs.h>
444static char **environ;
445#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000446extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000447#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000448
Barry Warsaw53699e91996-12-10 23:23:01 +0000449static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000450convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000451{
Victor Stinner8c62be82010-05-06 00:08:46 +0000452 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000453#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000454 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000455#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000456 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000457#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000458#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000459 APIRET rc;
460 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
461#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000462
Victor Stinner8c62be82010-05-06 00:08:46 +0000463 d = PyDict_New();
464 if (d == NULL)
465 return NULL;
466#ifdef WITH_NEXT_FRAMEWORK
467 if (environ == NULL)
468 environ = *_NSGetEnviron();
469#endif
470#ifdef MS_WINDOWS
471 /* _wenviron must be initialized in this way if the program is started
472 through main() instead of wmain(). */
473 _wgetenv(L"");
474 if (_wenviron == NULL)
475 return d;
476 /* This part ignores errors */
477 for (e = _wenviron; *e != NULL; e++) {
478 PyObject *k;
479 PyObject *v;
480 wchar_t *p = wcschr(*e, L'=');
481 if (p == NULL)
482 continue;
483 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
484 if (k == NULL) {
485 PyErr_Clear();
486 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000487 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000488 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
489 if (v == NULL) {
490 PyErr_Clear();
491 Py_DECREF(k);
492 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000493 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000494 if (PyDict_GetItem(d, k) == NULL) {
495 if (PyDict_SetItem(d, k, v) != 0)
496 PyErr_Clear();
497 }
498 Py_DECREF(k);
499 Py_DECREF(v);
500 }
501#else
502 if (environ == NULL)
503 return d;
504 /* This part ignores errors */
505 for (e = environ; *e != NULL; e++) {
506 PyObject *k;
507 PyObject *v;
508 char *p = strchr(*e, '=');
509 if (p == NULL)
510 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000511 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000512 if (k == NULL) {
513 PyErr_Clear();
514 continue;
515 }
Victor Stinner84ae1182010-05-06 22:05:07 +0000516 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +0000517 if (v == NULL) {
518 PyErr_Clear();
519 Py_DECREF(k);
520 continue;
521 }
522 if (PyDict_GetItem(d, k) == NULL) {
523 if (PyDict_SetItem(d, k, v) != 0)
524 PyErr_Clear();
525 }
526 Py_DECREF(k);
527 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000528 }
529#endif
Victor Stinner8c62be82010-05-06 00:08:46 +0000530#if defined(PYOS_OS2)
531 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
532 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
533 PyObject *v = PyBytes_FromString(buffer);
534 PyDict_SetItemString(d, "BEGINLIBPATH", v);
535 Py_DECREF(v);
536 }
537 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
538 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
539 PyObject *v = PyBytes_FromString(buffer);
540 PyDict_SetItemString(d, "ENDLIBPATH", v);
541 Py_DECREF(v);
542 }
543#endif
544 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000545}
546
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000547/* Set a POSIX-specific error from errno, and return NULL */
548
Barry Warsawd58d7641998-07-23 16:14:40 +0000549static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000550posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000551{
Victor Stinner8c62be82010-05-06 00:08:46 +0000552 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000553}
Barry Warsawd58d7641998-07-23 16:14:40 +0000554static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000555posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000556{
Victor Stinner8c62be82010-05-06 00:08:46 +0000557 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000558}
559
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000560
Mark Hammondef8b6542001-05-13 08:04:26 +0000561static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000562posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000563{
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000564 PyObject *name_str, *rc;
565 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
566 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +0000567 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000568 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
569 name_str);
570 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +0000571 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000572}
573
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000574#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000575static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +0000576win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000577{
Victor Stinner8c62be82010-05-06 00:08:46 +0000578 /* XXX We should pass the function name along in the future.
579 (winreg.c also wants to pass the function name.)
580 This would however require an additional param to the
581 Windows error object, which is non-trivial.
582 */
583 errno = GetLastError();
584 if (filename)
585 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
586 else
587 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000588}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000589
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000590static PyObject *
591win32_error_unicode(char* function, Py_UNICODE* filename)
592{
Victor Stinner8c62be82010-05-06 00:08:46 +0000593 /* XXX - see win32_error for comments on 'function' */
594 errno = GetLastError();
595 if (filename)
596 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
597 else
598 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000599}
600
Thomas Wouters477c8d52006-05-27 19:21:47 +0000601static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000602convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000603{
Victor Stinner8c62be82010-05-06 00:08:46 +0000604 if (PyUnicode_CheckExact(*param))
605 Py_INCREF(*param);
606 else if (PyUnicode_Check(*param))
607 /* For a Unicode subtype that's not a Unicode object,
608 return a true Unicode object with the same data. */
609 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
610 PyUnicode_GET_SIZE(*param));
611 else
612 *param = PyUnicode_FromEncodedObject(*param,
613 Py_FileSystemDefaultEncoding,
614 "strict");
615 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000616}
617
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000618#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000619
Guido van Rossumd48f2521997-12-05 22:19:34 +0000620#if defined(PYOS_OS2)
621/**********************************************************************
622 * Helper Function to Trim and Format OS/2 Messages
623 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000624static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000625os2_formatmsg(char *msgbuf, int msglen, char *reason)
626{
627 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
628
629 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
630 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
631
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000632 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000633 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
634 }
635
636 /* Add Optional Reason Text */
637 if (reason) {
638 strcat(msgbuf, " : ");
639 strcat(msgbuf, reason);
640 }
641}
642
643/**********************************************************************
644 * Decode an OS/2 Operating System Error Code
645 *
646 * A convenience function to lookup an OS/2 error code and return a
647 * text message we can use to raise a Python exception.
648 *
649 * Notes:
650 * The messages for errors returned from the OS/2 kernel reside in
651 * the file OSO001.MSG in the \OS2 directory hierarchy.
652 *
653 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000654static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000655os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
656{
657 APIRET rc;
658 ULONG msglen;
659
660 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
661 Py_BEGIN_ALLOW_THREADS
662 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
663 errorcode, "oso001.msg", &msglen);
664 Py_END_ALLOW_THREADS
665
666 if (rc == NO_ERROR)
667 os2_formatmsg(msgbuf, msglen, reason);
668 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000669 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +0000670 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000671
672 return msgbuf;
673}
674
675/* Set an OS/2-specific error and return NULL. OS/2 kernel
676 errors are not in a global variable e.g. 'errno' nor are
677 they congruent with posix error numbers. */
678
Victor Stinner8c62be82010-05-06 00:08:46 +0000679static PyObject *
680os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000681{
682 char text[1024];
683 PyObject *v;
684
685 os2_strerror(text, sizeof(text), code, "");
686
687 v = Py_BuildValue("(is)", code, text);
688 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000689 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000690 Py_DECREF(v);
691 }
692 return NULL; /* Signal to Python that an Exception is Pending */
693}
694
695#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000696
697/* POSIX generic methods */
698
Barry Warsaw53699e91996-12-10 23:23:01 +0000699static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000700posix_fildes(PyObject *fdobj, int (*func)(int))
701{
Victor Stinner8c62be82010-05-06 00:08:46 +0000702 int fd;
703 int res;
704 fd = PyObject_AsFileDescriptor(fdobj);
705 if (fd < 0)
706 return NULL;
707 if (!_PyVerify_fd(fd))
708 return posix_error();
709 Py_BEGIN_ALLOW_THREADS
710 res = (*func)(fd);
711 Py_END_ALLOW_THREADS
712 if (res < 0)
713 return posix_error();
714 Py_INCREF(Py_None);
715 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000716}
Guido van Rossum21142a01999-01-08 21:05:37 +0000717
718static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000719posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000720{
Victor Stinner8c62be82010-05-06 00:08:46 +0000721 PyObject *opath1 = NULL;
722 char *path1;
723 int res;
724 if (!PyArg_ParseTuple(args, format,
725 PyUnicode_FSConverter, &opath1))
726 return NULL;
727 path1 = PyBytes_AsString(opath1);
728 Py_BEGIN_ALLOW_THREADS
729 res = (*func)(path1);
730 Py_END_ALLOW_THREADS
731 if (res < 0)
732 return posix_error_with_allocated_filename(opath1);
733 Py_DECREF(opath1);
734 Py_INCREF(Py_None);
735 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000736}
737
Barry Warsaw53699e91996-12-10 23:23:01 +0000738static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000739posix_2str(PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +0000740 char *format,
741 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000742{
Victor Stinner8c62be82010-05-06 00:08:46 +0000743 PyObject *opath1 = NULL, *opath2 = NULL;
744 char *path1, *path2;
745 int res;
746 if (!PyArg_ParseTuple(args, format,
747 PyUnicode_FSConverter, &opath1,
748 PyUnicode_FSConverter, &opath2)) {
749 return NULL;
750 }
751 path1 = PyBytes_AsString(opath1);
752 path2 = PyBytes_AsString(opath2);
753 Py_BEGIN_ALLOW_THREADS
754 res = (*func)(path1, path2);
755 Py_END_ALLOW_THREADS
756 Py_DECREF(opath1);
757 Py_DECREF(opath2);
758 if (res != 0)
759 /* XXX how to report both path1 and path2??? */
760 return posix_error();
761 Py_INCREF(Py_None);
762 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000763}
764
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000765#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000766static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +0000767win32_1str(PyObject* args, char* func,
768 char* format, BOOL (__stdcall *funcA)(LPCSTR),
769 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000770{
Victor Stinner8c62be82010-05-06 00:08:46 +0000771 PyObject *uni;
772 char *ansi;
773 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +0000774
Victor Stinner8c62be82010-05-06 00:08:46 +0000775 if (!PyArg_ParseTuple(args, wformat, &uni))
776 PyErr_Clear();
777 else {
778 Py_BEGIN_ALLOW_THREADS
779 result = funcW(PyUnicode_AsUnicode(uni));
780 Py_END_ALLOW_THREADS
781 if (!result)
782 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
783 Py_INCREF(Py_None);
784 return Py_None;
785 }
786 if (!PyArg_ParseTuple(args, format, &ansi))
787 return NULL;
788 Py_BEGIN_ALLOW_THREADS
789 result = funcA(ansi);
790 Py_END_ALLOW_THREADS
791 if (!result)
792 return win32_error(func, ansi);
793 Py_INCREF(Py_None);
794 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000795
796}
797
798/* This is a reimplementation of the C library's chdir function,
799 but one that produces Win32 errors instead of DOS error codes.
800 chdir is essentially a wrapper around SetCurrentDirectory; however,
801 it also needs to set "magic" environment variables indicating
802 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000803static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000804win32_chdir(LPCSTR path)
805{
Victor Stinner8c62be82010-05-06 00:08:46 +0000806 char new_path[MAX_PATH+1];
807 int result;
808 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000809
Victor Stinner8c62be82010-05-06 00:08:46 +0000810 if(!SetCurrentDirectoryA(path))
811 return FALSE;
812 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
813 if (!result)
814 return FALSE;
815 /* In the ANSI API, there should not be any paths longer
816 than MAX_PATH. */
817 assert(result <= MAX_PATH+1);
818 if (strncmp(new_path, "\\\\", 2) == 0 ||
819 strncmp(new_path, "//", 2) == 0)
820 /* UNC path, nothing to do. */
821 return TRUE;
822 env[1] = new_path[0];
823 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000824}
825
826/* The Unicode version differs from the ANSI version
827 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000828static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000829win32_wchdir(LPCWSTR path)
830{
Victor Stinner8c62be82010-05-06 00:08:46 +0000831 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
832 int result;
833 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000834
Victor Stinner8c62be82010-05-06 00:08:46 +0000835 if(!SetCurrentDirectoryW(path))
836 return FALSE;
837 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
838 if (!result)
839 return FALSE;
840 if (result > MAX_PATH+1) {
841 new_path = malloc(result * sizeof(wchar_t));
842 if (!new_path) {
843 SetLastError(ERROR_OUTOFMEMORY);
844 return FALSE;
845 }
846 result = GetCurrentDirectoryW(result, new_path);
847 if (!result) {
848 free(new_path);
849 return FALSE;
850 }
851 }
852 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
853 wcsncmp(new_path, L"//", 2) == 0)
854 /* UNC path, nothing to do. */
855 return TRUE;
856 env[1] = new_path[0];
857 result = SetEnvironmentVariableW(env, new_path);
858 if (new_path != _new_path)
859 free(new_path);
860 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000861}
862#endif
863
Martin v. Löwis14694662006-02-03 12:54:16 +0000864#ifdef MS_WINDOWS
865/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
866 - time stamps are restricted to second resolution
867 - file modification times suffer from forth-and-back conversions between
868 UTC and local time
869 Therefore, we implement our own stat, based on the Win32 API directly.
870*/
Victor Stinner8c62be82010-05-06 00:08:46 +0000871#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +0000872
873struct win32_stat{
874 int st_dev;
875 __int64 st_ino;
876 unsigned short st_mode;
877 int st_nlink;
878 int st_uid;
879 int st_gid;
880 int st_rdev;
881 __int64 st_size;
882 int st_atime;
883 int st_atime_nsec;
884 int st_mtime;
885 int st_mtime_nsec;
886 int st_ctime;
887 int st_ctime_nsec;
888};
889
890static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
891
892static void
893FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
894{
Victor Stinner8c62be82010-05-06 00:08:46 +0000895 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
896 /* Cannot simply cast and dereference in_ptr,
897 since it might not be aligned properly */
898 __int64 in;
899 memcpy(&in, in_ptr, sizeof(in));
900 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
901 /* XXX Win32 supports time stamps past 2038; we currently don't */
902 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
Martin v. Löwis14694662006-02-03 12:54:16 +0000903}
904
Thomas Wouters477c8d52006-05-27 19:21:47 +0000905static void
906time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
907{
Victor Stinner8c62be82010-05-06 00:08:46 +0000908 /* XXX endianness */
909 __int64 out;
910 out = time_in + secs_between_epochs;
911 out = out * 10000000 + nsec_in / 100;
912 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000913}
914
Martin v. Löwis14694662006-02-03 12:54:16 +0000915/* Below, we *know* that ugo+r is 0444 */
916#if _S_IREAD != 0400
917#error Unsupported C library
918#endif
919static int
920attributes_to_mode(DWORD attr)
921{
Victor Stinner8c62be82010-05-06 00:08:46 +0000922 int m = 0;
923 if (attr & FILE_ATTRIBUTE_DIRECTORY)
924 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
925 else
926 m |= _S_IFREG;
927 if (attr & FILE_ATTRIBUTE_READONLY)
928 m |= 0444;
929 else
930 m |= 0666;
931 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +0000932}
933
934static int
935attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
936{
Victor Stinner8c62be82010-05-06 00:08:46 +0000937 memset(result, 0, sizeof(*result));
938 result->st_mode = attributes_to_mode(info->dwFileAttributes);
939 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
940 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
941 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
942 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Martin v. Löwis14694662006-02-03 12:54:16 +0000943
Victor Stinner8c62be82010-05-06 00:08:46 +0000944 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +0000945}
946
Guido van Rossumd8faa362007-04-27 19:54:29 +0000947static BOOL
948attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
949{
Victor Stinner8c62be82010-05-06 00:08:46 +0000950 HANDLE hFindFile;
951 WIN32_FIND_DATAA FileData;
952 hFindFile = FindFirstFileA(pszFile, &FileData);
953 if (hFindFile == INVALID_HANDLE_VALUE)
954 return FALSE;
955 FindClose(hFindFile);
956 pfad->dwFileAttributes = FileData.dwFileAttributes;
957 pfad->ftCreationTime = FileData.ftCreationTime;
958 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
959 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
960 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
961 pfad->nFileSizeLow = FileData.nFileSizeLow;
962 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000963}
964
965static BOOL
966attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
967{
Victor Stinner8c62be82010-05-06 00:08:46 +0000968 HANDLE hFindFile;
969 WIN32_FIND_DATAW FileData;
970 hFindFile = FindFirstFileW(pszFile, &FileData);
971 if (hFindFile == INVALID_HANDLE_VALUE)
972 return FALSE;
973 FindClose(hFindFile);
974 pfad->dwFileAttributes = FileData.dwFileAttributes;
975 pfad->ftCreationTime = FileData.ftCreationTime;
976 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
977 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
978 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
979 pfad->nFileSizeLow = FileData.nFileSizeLow;
980 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000981}
982
Brian Curtind40e6f72010-07-08 21:39:08 +0000983/* About the following functions: win32_lstat, win32_lstat_w, win32_stat,
984 win32_stat_w
985
986 In Posix, stat automatically traverses symlinks and returns the stat
987 structure for the target. In Windows, the equivalent GetFileAttributes by
988 default does not traverse symlinks and instead returns attributes for
989 the symlink.
990
991 Therefore, win32_lstat will get the attributes traditionally, and
992 win32_stat will first explicitly resolve the symlink target and then will
993 call win32_lstat on that result.
994
995 The _w represent Unicode equivalents of the aformentioned ANSI functions. */
996
997static int
998win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +0000999{
Victor Stinner8c62be82010-05-06 00:08:46 +00001000 WIN32_FILE_ATTRIBUTE_DATA info;
1001 int code;
1002 char *dot;
Brian Curtind40e6f72010-07-08 21:39:08 +00001003 WIN32_FIND_DATAA find_data;
1004 HANDLE find_data_handle;
Victor Stinner8c62be82010-05-06 00:08:46 +00001005 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
1006 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1007 /* Protocol violation: we explicitly clear errno, instead of
1008 setting it to a POSIX error. Callers should use GetLastError. */
1009 errno = 0;
1010 return -1;
1011 } else {
1012 /* Could not get attributes on open file. Fall back to
1013 reading the directory. */
1014 if (!attributes_from_dir(path, &info)) {
1015 /* Very strange. This should not fail now */
1016 errno = 0;
1017 return -1;
1018 }
1019 }
1020 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001021
Victor Stinner8c62be82010-05-06 00:08:46 +00001022 code = attribute_data_to_stat(&info, result);
1023 if (code != 0)
1024 return code;
Brian Curtind40e6f72010-07-08 21:39:08 +00001025
1026 /* Get WIN32_FIND_DATA structure for the path to determine if
1027 it is a symlink */
1028 if(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1029 find_data_handle = FindFirstFileA(path, &find_data);
1030 if(find_data_handle != INVALID_HANDLE_VALUE) {
1031 if(find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
1032 /* first clear the S_IFMT bits */
1033 result->st_mode ^= (result->st_mode & 0170000);
1034 /* now set the bits that make this a symlink */
1035 result->st_mode |= 0120000;
1036 }
1037 FindClose(find_data_handle);
1038 }
1039 }
1040
Victor Stinner8c62be82010-05-06 00:08:46 +00001041 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1042 dot = strrchr(path, '.');
1043 if (dot) {
Brian Curtind40e6f72010-07-08 21:39:08 +00001044 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1045 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00001046 result->st_mode |= 0111;
1047 }
1048 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001049}
1050
Victor Stinner8c62be82010-05-06 00:08:46 +00001051static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001052win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001053{
Victor Stinner8c62be82010-05-06 00:08:46 +00001054 int code;
1055 const wchar_t *dot;
1056 WIN32_FILE_ATTRIBUTE_DATA info;
Brian Curtind40e6f72010-07-08 21:39:08 +00001057 WIN32_FIND_DATAW find_data;
1058 HANDLE find_data_handle;
Victor Stinner8c62be82010-05-06 00:08:46 +00001059 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
1060 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1061 /* Protocol violation: we explicitly clear errno, instead of
1062 setting it to a POSIX error. Callers should use GetLastError. */
1063 errno = 0;
1064 return -1;
1065 } else {
Brian Curtind40e6f72010-07-08 21:39:08 +00001066 /* Could not get attributes on open file. Fall back to reading
1067 the directory. */
1068 if (!attributes_from_dir_w(path, &info)) {
1069 /* Very strange. This should not fail now */
1070 errno = 0;
1071 return -1;
1072 }
1073 }
1074 }
1075 code = attribute_data_to_stat(&info, result);
1076 if (code < 0)
1077 return code;
1078
1079 /* Get WIN32_FIND_DATA structure for the path to determine if
1080 it is a symlink */
1081 if(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1082 find_data_handle = FindFirstFileW(path, &find_data);
1083 if(find_data_handle != INVALID_HANDLE_VALUE) {
1084 if(find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
1085 /* first clear the S_IFMT bits */
1086 result->st_mode ^= (result->st_mode & 0170000);
1087 /* now set the bits that make this a symlink */
1088 result->st_mode |= 0120000;
1089 }
1090 FindClose(find_data_handle);
1091 }
1092 }
1093
1094 /* Set IFEXEC if it is an .exe, .bat, ... */
1095 dot = wcsrchr(path, '.');
1096 if (dot) {
1097 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1098 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1099 result->st_mode |= 0111;
1100 }
1101 return code;
1102}
1103
1104/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1105static int has_GetFinalPathNameByHandle = 0;
1106static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1107 DWORD);
1108static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1109 DWORD);
1110static int
1111check_GetFinalPathNameByHandle()
1112{
1113 HINSTANCE hKernel32;
1114 /* only recheck */
1115 if (!has_GetFinalPathNameByHandle)
1116 {
1117 hKernel32 = GetModuleHandle("KERNEL32");
1118 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1119 "GetFinalPathNameByHandleA");
1120 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1121 "GetFinalPathNameByHandleW");
Brian Curtin74e45612010-07-09 15:58:59 +00001122 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1123 Py_GetFinalPathNameByHandleW;
Brian Curtind40e6f72010-07-08 21:39:08 +00001124 }
1125 return has_GetFinalPathNameByHandle;
1126}
1127
1128static int
1129win32_stat(const char* path, struct win32_stat *result)
1130{
1131 /* Traverse the symlink to the target using
1132 GetFinalPathNameByHandle()
1133 */
1134 int code;
1135 HANDLE hFile;
1136 int buf_size;
1137 char *target_path;
1138 int result_length;
1139 WIN32_FILE_ATTRIBUTE_DATA info;
1140
1141 if(!check_GetFinalPathNameByHandle()) {
1142 /* if the OS doesn't have GetFinalPathNameByHandle, it doesn't
1143 have symlinks, so just fall back to the traditional behavior
1144 found in lstat. */
1145 return win32_lstat(path, result);
1146 }
1147
1148 hFile = CreateFileA(
1149 path,
1150 0, /* desired access */
1151 0, /* share mode */
1152 NULL, /* security attributes */
1153 OPEN_EXISTING,
1154 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
1155 FILE_FLAG_BACKUP_SEMANTICS,
1156 NULL);
1157
1158 if(hFile == INVALID_HANDLE_VALUE) {
1159 /* Either the target doesn't exist, or we don't have access to
1160 get a handle to it. If the former, we need to return an error.
1161 If the latter, we can use attributes_from_dir. */
1162 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1163 /* Protocol violation: we explicitly clear errno, instead of
1164 setting it to a POSIX error. Callers should use GetLastError. */
1165 errno = 0;
1166 return -1;
1167 } else {
1168 /* Could not get attributes on open file. Fall back to
1169 reading the directory. */
1170 if (!attributes_from_dir(path, &info)) {
1171 /* Very strange. This should not fail now */
1172 errno = 0;
1173 return -1;
1174 }
1175 }
1176 code = attribute_data_to_stat(&info, result);
1177 }
1178
1179 buf_size = Py_GetFinalPathNameByHandleA(hFile, 0, 0, VOLUME_NAME_DOS);
1180 if(!buf_size) return -1;
1181 target_path = (char *)malloc((buf_size+1)*sizeof(char));
1182 result_length = Py_GetFinalPathNameByHandleA(hFile, target_path,
1183 buf_size, VOLUME_NAME_DOS);
1184
1185 if(!result_length)
1186 return -1;
1187
1188 if(!CloseHandle(hFile))
1189 return -1;
1190
1191 target_path[result_length] = 0;
1192 code = win32_lstat(target_path, result);
1193 free(target_path);
1194
1195 return code;
1196}
1197
1198static int
1199win32_stat_w(const wchar_t* path, struct win32_stat *result)
1200{
1201 /* Traverse the symlink to the target using GetFinalPathNameByHandle() */
1202 int code;
1203 HANDLE hFile;
1204 int buf_size;
1205 wchar_t *target_path;
1206 int result_length;
1207 WIN32_FILE_ATTRIBUTE_DATA info;
1208
1209 if(!check_GetFinalPathNameByHandle()) {
1210 /* If the OS doesn't have GetFinalPathNameByHandle, it doesn't have
1211 symlinks, so just fall back to the traditional behavior found
1212 in lstat. */
1213 return win32_lstat_w(path, result);
1214 }
1215
1216 hFile = CreateFileW(
1217 path,
1218 0, /* desired access */
1219 0, /* share mode */
1220 NULL, /* security attributes */
1221 OPEN_EXISTING,
1222 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
1223 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1224 NULL);
Antoine Pitroub73caab2010-08-09 23:39:31 +00001225
Brian Curtind40e6f72010-07-08 21:39:08 +00001226 if(hFile == INVALID_HANDLE_VALUE) {
1227 /* Either the target doesn't exist, or we don't have access to
1228 get a handle to it. If the former, we need to return an error.
1229 If the latter, we can use attributes_from_dir. */
1230 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1231 /* Protocol violation: we explicitly clear errno, instead of
1232 setting it to a POSIX error. Callers should use GetLastError. */
1233 errno = 0;
1234 return -1;
1235 } else {
Victor Stinner8c62be82010-05-06 00:08:46 +00001236 /* Could not get attributes on open file. Fall back to
1237 reading the directory. */
1238 if (!attributes_from_dir_w(path, &info)) {
1239 /* Very strange. This should not fail now */
1240 errno = 0;
1241 return -1;
1242 }
1243 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001244 code = attribute_data_to_stat(&info, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001245 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001246 else {
1247 /* We have a good handle to the target, use it to determine the target
1248 path name (then we'll call lstat on it). */
1249 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_DOS);
1250 if(!buf_size)
1251 return -1;
1252
1253 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
1254 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
1255 buf_size, VOLUME_NAME_DOS);
1256
1257 if(!result_length)
1258 return -1;
1259
1260 if(!CloseHandle(hFile))
1261 return -1;
1262
1263 target_path[result_length] = 0;
1264 code = win32_lstat_w(target_path, result);
1265 free(target_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001266 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001267
Victor Stinner8c62be82010-05-06 00:08:46 +00001268 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001269}
1270
1271static int
1272win32_fstat(int file_number, struct win32_stat *result)
1273{
Victor Stinner8c62be82010-05-06 00:08:46 +00001274 BY_HANDLE_FILE_INFORMATION info;
1275 HANDLE h;
1276 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001277
Victor Stinner8c62be82010-05-06 00:08:46 +00001278 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001279
Victor Stinner8c62be82010-05-06 00:08:46 +00001280 /* Protocol violation: we explicitly clear errno, instead of
1281 setting it to a POSIX error. Callers should use GetLastError. */
1282 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001283
Victor Stinner8c62be82010-05-06 00:08:46 +00001284 if (h == INVALID_HANDLE_VALUE) {
1285 /* This is really a C library error (invalid file handle).
1286 We set the Win32 error to the closes one matching. */
1287 SetLastError(ERROR_INVALID_HANDLE);
1288 return -1;
1289 }
1290 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001291
Victor Stinner8c62be82010-05-06 00:08:46 +00001292 type = GetFileType(h);
1293 if (type == FILE_TYPE_UNKNOWN) {
1294 DWORD error = GetLastError();
1295 if (error != 0) {
1296 return -1;
1297 }
1298 /* else: valid but unknown file */
1299 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001300
Victor Stinner8c62be82010-05-06 00:08:46 +00001301 if (type != FILE_TYPE_DISK) {
1302 if (type == FILE_TYPE_CHAR)
1303 result->st_mode = _S_IFCHR;
1304 else if (type == FILE_TYPE_PIPE)
1305 result->st_mode = _S_IFIFO;
1306 return 0;
1307 }
1308
1309 if (!GetFileInformationByHandle(h, &info)) {
1310 return -1;
1311 }
1312
1313 /* similar to stat() */
1314 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1315 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
Brian Curtin74e45612010-07-09 15:58:59 +00001316 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime,
1317 &result->st_ctime_nsec);
1318 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime,
1319 &result->st_mtime_nsec);
1320 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime,
1321 &result->st_atime_nsec);
Victor Stinner8c62be82010-05-06 00:08:46 +00001322 /* specific to fstat() */
1323 result->st_nlink = info.nNumberOfLinks;
1324 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1325 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001326}
1327
1328#endif /* MS_WINDOWS */
1329
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001330PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001331"stat_result: Result from stat or lstat.\n\n\
1332This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001333 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001334or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1335\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001336Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1337or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001338\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001339See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001340
1341static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001342 {"st_mode", "protection bits"},
1343 {"st_ino", "inode"},
1344 {"st_dev", "device"},
1345 {"st_nlink", "number of hard links"},
1346 {"st_uid", "user ID of owner"},
1347 {"st_gid", "group ID of owner"},
1348 {"st_size", "total size, in bytes"},
1349 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1350 {NULL, "integer time of last access"},
1351 {NULL, "integer time of last modification"},
1352 {NULL, "integer time of last change"},
1353 {"st_atime", "time of last access"},
1354 {"st_mtime", "time of last modification"},
1355 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001356#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001357 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001358#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001359#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001360 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001361#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001362#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001363 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001364#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001365#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001366 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001367#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001368#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001369 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001370#endif
1371#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001372 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001373#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001374 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001375};
1376
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001377#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001378#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001379#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001380#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001381#endif
1382
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001383#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001384#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1385#else
1386#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1387#endif
1388
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001389#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001390#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1391#else
1392#define ST_RDEV_IDX ST_BLOCKS_IDX
1393#endif
1394
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001395#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1396#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1397#else
1398#define ST_FLAGS_IDX ST_RDEV_IDX
1399#endif
1400
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001401#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001402#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001403#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001404#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001405#endif
1406
1407#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1408#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1409#else
1410#define ST_BIRTHTIME_IDX ST_GEN_IDX
1411#endif
1412
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001413static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001414 "stat_result", /* name */
1415 stat_result__doc__, /* doc */
1416 stat_result_fields,
1417 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001418};
1419
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001420PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001421"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1422This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001423 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001424or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001425\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001426See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001427
1428static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001429 {"f_bsize", },
1430 {"f_frsize", },
1431 {"f_blocks", },
1432 {"f_bfree", },
1433 {"f_bavail", },
1434 {"f_files", },
1435 {"f_ffree", },
1436 {"f_favail", },
1437 {"f_flag", },
1438 {"f_namemax",},
1439 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001440};
1441
1442static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001443 "statvfs_result", /* name */
1444 statvfs_result__doc__, /* doc */
1445 statvfs_result_fields,
1446 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001447};
1448
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001449static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001450static PyTypeObject StatResultType;
1451static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001452static newfunc structseq_new;
1453
1454static PyObject *
1455statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1456{
Victor Stinner8c62be82010-05-06 00:08:46 +00001457 PyStructSequence *result;
1458 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001459
Victor Stinner8c62be82010-05-06 00:08:46 +00001460 result = (PyStructSequence*)structseq_new(type, args, kwds);
1461 if (!result)
1462 return NULL;
1463 /* If we have been initialized from a tuple,
1464 st_?time might be set to None. Initialize it
1465 from the int slots. */
1466 for (i = 7; i <= 9; i++) {
1467 if (result->ob_item[i+3] == Py_None) {
1468 Py_DECREF(Py_None);
1469 Py_INCREF(result->ob_item[i]);
1470 result->ob_item[i+3] = result->ob_item[i];
1471 }
1472 }
1473 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001474}
1475
1476
1477
1478/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001479static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001480
1481PyDoc_STRVAR(stat_float_times__doc__,
1482"stat_float_times([newval]) -> oldval\n\n\
1483Determine whether os.[lf]stat represents time stamps as float objects.\n\
1484If newval is True, future calls to stat() return floats, if it is False,\n\
1485future calls return ints. \n\
1486If newval is omitted, return the current setting.\n");
1487
1488static PyObject*
1489stat_float_times(PyObject* self, PyObject *args)
1490{
Victor Stinner8c62be82010-05-06 00:08:46 +00001491 int newval = -1;
1492 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1493 return NULL;
1494 if (newval == -1)
1495 /* Return old value */
1496 return PyBool_FromLong(_stat_float_times);
1497 _stat_float_times = newval;
1498 Py_INCREF(Py_None);
1499 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001500}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001501
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001502static void
1503fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1504{
Victor Stinner8c62be82010-05-06 00:08:46 +00001505 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001506#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner8c62be82010-05-06 00:08:46 +00001507 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001508#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001509 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001510#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001511 if (!ival)
1512 return;
1513 if (_stat_float_times) {
1514 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1515 } else {
1516 fval = ival;
1517 Py_INCREF(fval);
1518 }
1519 PyStructSequence_SET_ITEM(v, index, ival);
1520 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001521}
1522
Tim Peters5aa91602002-01-30 05:46:57 +00001523/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001524 (used by posix_stat() and posix_fstat()) */
1525static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001526_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001527{
Victor Stinner8c62be82010-05-06 00:08:46 +00001528 unsigned long ansec, mnsec, cnsec;
1529 PyObject *v = PyStructSequence_New(&StatResultType);
1530 if (v == NULL)
1531 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001532
Victor Stinner8c62be82010-05-06 00:08:46 +00001533 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001534#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001535 PyStructSequence_SET_ITEM(v, 1,
1536 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001537#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001538 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001539#endif
1540#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001541 PyStructSequence_SET_ITEM(v, 2,
1542 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001543#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001544 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001545#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001546 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1547 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1548 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001549#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001550 PyStructSequence_SET_ITEM(v, 6,
1551 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001552#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001553 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001554#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001555
Martin v. Löwis14694662006-02-03 12:54:16 +00001556#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001557 ansec = st->st_atim.tv_nsec;
1558 mnsec = st->st_mtim.tv_nsec;
1559 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001560#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001561 ansec = st->st_atimespec.tv_nsec;
1562 mnsec = st->st_mtimespec.tv_nsec;
1563 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001564#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001565 ansec = st->st_atime_nsec;
1566 mnsec = st->st_mtime_nsec;
1567 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001568#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001569 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001570#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001571 fill_time(v, 7, st->st_atime, ansec);
1572 fill_time(v, 8, st->st_mtime, mnsec);
1573 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001574
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001575#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001576 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1577 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001578#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001579#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001580 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1581 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001582#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001583#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001584 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1585 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001586#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001587#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001588 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1589 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001590#endif
1591#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001592 {
1593 PyObject *val;
1594 unsigned long bsec,bnsec;
1595 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001596#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner8c62be82010-05-06 00:08:46 +00001597 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001598#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001599 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001600#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001601 if (_stat_float_times) {
1602 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1603 } else {
1604 val = PyLong_FromLong((long)bsec);
1605 }
1606 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1607 val);
1608 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001609#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001610#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001611 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1612 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001613#endif
Fred Drake699f3522000-06-29 21:12:41 +00001614
Victor Stinner8c62be82010-05-06 00:08:46 +00001615 if (PyErr_Occurred()) {
1616 Py_DECREF(v);
1617 return NULL;
1618 }
Fred Drake699f3522000-06-29 21:12:41 +00001619
Victor Stinner8c62be82010-05-06 00:08:46 +00001620 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001621}
1622
Barry Warsaw53699e91996-12-10 23:23:01 +00001623static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001624posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +00001625 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001626#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00001627 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001628#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001629 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001630#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001631 char *wformat,
1632 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001633{
Victor Stinner8c62be82010-05-06 00:08:46 +00001634 STRUCT_STAT st;
1635 PyObject *opath;
1636 char *path;
1637 int res;
1638 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001639
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001640#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001641 PyUnicodeObject *po;
1642 if (PyArg_ParseTuple(args, wformat, &po)) {
1643 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001644
Victor Stinner8c62be82010-05-06 00:08:46 +00001645 Py_BEGIN_ALLOW_THREADS
1646 /* PyUnicode_AS_UNICODE result OK without
1647 thread lock as it is a simple dereference. */
1648 res = wstatfunc(wpath, &st);
1649 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001650
Victor Stinner8c62be82010-05-06 00:08:46 +00001651 if (res != 0)
1652 return win32_error_unicode("stat", wpath);
1653 return _pystat_fromstructstat(&st);
1654 }
1655 /* Drop the argument parsing error as narrow strings
1656 are also valid. */
1657 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001658#endif
1659
Victor Stinner8c62be82010-05-06 00:08:46 +00001660 if (!PyArg_ParseTuple(args, format,
1661 PyUnicode_FSConverter, &opath))
1662 return NULL;
1663 path = PyBytes_AsString(opath);
1664 Py_BEGIN_ALLOW_THREADS
1665 res = (*statfunc)(path, &st);
1666 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001667
Victor Stinner8c62be82010-05-06 00:08:46 +00001668 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001669#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001670 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001671#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001672 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001673#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001674 }
1675 else
1676 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001677
Victor Stinner8c62be82010-05-06 00:08:46 +00001678 Py_DECREF(opath);
1679 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001680}
1681
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001682/* POSIX methods */
1683
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001684PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001685"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001686Use the real uid/gid to test for access to a path. Note that most\n\
1687operations will use the effective uid/gid, therefore this routine can\n\
1688be used in a suid/sgid environment to test if the invoking user has the\n\
1689specified access to the path. The mode argument can be F_OK to test\n\
1690existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001691
1692static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001693posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001694{
Victor Stinner8c62be82010-05-06 00:08:46 +00001695 PyObject *opath;
1696 char *path;
1697 int mode;
1698
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001699#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001700 DWORD attr;
1701 PyUnicodeObject *po;
1702 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1703 Py_BEGIN_ALLOW_THREADS
1704 /* PyUnicode_AS_UNICODE OK without thread lock as
1705 it is a simple dereference. */
1706 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1707 Py_END_ALLOW_THREADS
1708 goto finish;
1709 }
1710 /* Drop the argument parsing error as narrow strings
1711 are also valid. */
1712 PyErr_Clear();
1713 if (!PyArg_ParseTuple(args, "O&i:access",
1714 PyUnicode_FSConverter, &opath, &mode))
1715 return NULL;
1716 path = PyBytes_AsString(opath);
1717 Py_BEGIN_ALLOW_THREADS
1718 attr = GetFileAttributesA(path);
1719 Py_END_ALLOW_THREADS
1720 Py_DECREF(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001721finish:
Victor Stinner8c62be82010-05-06 00:08:46 +00001722 if (attr == 0xFFFFFFFF)
1723 /* File does not exist, or cannot read attributes */
1724 return PyBool_FromLong(0);
1725 /* Access is possible if either write access wasn't requested, or
1726 the file isn't read-only, or if it's a directory, as there are
1727 no read-only directories on Windows. */
1728 return PyBool_FromLong(!(mode & 2)
1729 || !(attr & FILE_ATTRIBUTE_READONLY)
1730 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001731#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001732 int res;
1733 if (!PyArg_ParseTuple(args, "O&i:access",
1734 PyUnicode_FSConverter, &opath, &mode))
1735 return NULL;
1736 path = PyBytes_AsString(opath);
1737 Py_BEGIN_ALLOW_THREADS
1738 res = access(path, mode);
1739 Py_END_ALLOW_THREADS
1740 Py_DECREF(opath);
1741 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001742#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001743}
1744
Guido van Rossumd371ff11999-01-25 16:12:23 +00001745#ifndef F_OK
1746#define F_OK 0
1747#endif
1748#ifndef R_OK
1749#define R_OK 4
1750#endif
1751#ifndef W_OK
1752#define W_OK 2
1753#endif
1754#ifndef X_OK
1755#define X_OK 1
1756#endif
1757
1758#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001759PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001760"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001761Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001762
1763static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001764posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001765{
Victor Stinner8c62be82010-05-06 00:08:46 +00001766 int id;
1767 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001768
Victor Stinner8c62be82010-05-06 00:08:46 +00001769 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1770 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001771
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001772#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001773 /* file descriptor 0 only, the default input device (stdin) */
1774 if (id == 0) {
1775 ret = ttyname();
1776 }
1777 else {
1778 ret = NULL;
1779 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001780#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001781 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001782#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001783 if (ret == NULL)
1784 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001785 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001786}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001787#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001788
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001789#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001790PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001791"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001792Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001793
1794static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001795posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001796{
Victor Stinner8c62be82010-05-06 00:08:46 +00001797 char *ret;
1798 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001799
Greg Wardb48bc172000-03-01 21:51:56 +00001800#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00001801 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001802#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001803 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001804#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001805 if (ret == NULL)
1806 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001807 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001808}
1809#endif
1810
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001811PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001812"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001813Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001814
Barry Warsaw53699e91996-12-10 23:23:01 +00001815static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001816posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001817{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001818#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001819 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001820#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001821 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001822#elif defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001823 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001824#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001825 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001826#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001827}
1828
Fred Drake4d1e64b2002-04-15 19:40:07 +00001829#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001830PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001831"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001832Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001833opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001834
1835static PyObject *
1836posix_fchdir(PyObject *self, PyObject *fdobj)
1837{
Victor Stinner8c62be82010-05-06 00:08:46 +00001838 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001839}
1840#endif /* HAVE_FCHDIR */
1841
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001842
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001843PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001844"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001845Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001846
Barry Warsaw53699e91996-12-10 23:23:01 +00001847static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001848posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001849{
Victor Stinner8c62be82010-05-06 00:08:46 +00001850 PyObject *opath = NULL;
1851 char *path = NULL;
1852 int i;
1853 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001854#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001855 DWORD attr;
1856 PyUnicodeObject *po;
1857 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1858 Py_BEGIN_ALLOW_THREADS
1859 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1860 if (attr != 0xFFFFFFFF) {
1861 if (i & _S_IWRITE)
1862 attr &= ~FILE_ATTRIBUTE_READONLY;
1863 else
1864 attr |= FILE_ATTRIBUTE_READONLY;
1865 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1866 }
1867 else
1868 res = 0;
1869 Py_END_ALLOW_THREADS
1870 if (!res)
1871 return win32_error_unicode("chmod",
1872 PyUnicode_AS_UNICODE(po));
1873 Py_INCREF(Py_None);
1874 return Py_None;
1875 }
1876 /* Drop the argument parsing error as narrow strings
1877 are also valid. */
1878 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001879
Victor Stinner8c62be82010-05-06 00:08:46 +00001880 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1881 &opath, &i))
1882 return NULL;
1883 path = PyBytes_AsString(opath);
1884 Py_BEGIN_ALLOW_THREADS
1885 attr = GetFileAttributesA(path);
1886 if (attr != 0xFFFFFFFF) {
1887 if (i & _S_IWRITE)
1888 attr &= ~FILE_ATTRIBUTE_READONLY;
1889 else
1890 attr |= FILE_ATTRIBUTE_READONLY;
1891 res = SetFileAttributesA(path, attr);
1892 }
1893 else
1894 res = 0;
1895 Py_END_ALLOW_THREADS
1896 if (!res) {
1897 win32_error("chmod", path);
1898 Py_DECREF(opath);
1899 return NULL;
1900 }
1901 Py_DECREF(opath);
1902 Py_INCREF(Py_None);
1903 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001904#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00001905 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1906 &opath, &i))
1907 return NULL;
1908 path = PyBytes_AsString(opath);
1909 Py_BEGIN_ALLOW_THREADS
1910 res = chmod(path, i);
1911 Py_END_ALLOW_THREADS
1912 if (res < 0)
1913 return posix_error_with_allocated_filename(opath);
1914 Py_DECREF(opath);
1915 Py_INCREF(Py_None);
1916 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001917#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001918}
1919
Christian Heimes4e30a842007-11-30 22:12:06 +00001920#ifdef HAVE_FCHMOD
1921PyDoc_STRVAR(posix_fchmod__doc__,
1922"fchmod(fd, mode)\n\n\
1923Change the access permissions of the file given by file\n\
1924descriptor fd.");
1925
1926static PyObject *
1927posix_fchmod(PyObject *self, PyObject *args)
1928{
Victor Stinner8c62be82010-05-06 00:08:46 +00001929 int fd, mode, res;
1930 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1931 return NULL;
1932 Py_BEGIN_ALLOW_THREADS
1933 res = fchmod(fd, mode);
1934 Py_END_ALLOW_THREADS
1935 if (res < 0)
1936 return posix_error();
1937 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001938}
1939#endif /* HAVE_FCHMOD */
1940
1941#ifdef HAVE_LCHMOD
1942PyDoc_STRVAR(posix_lchmod__doc__,
1943"lchmod(path, mode)\n\n\
1944Change the access permissions of a file. If path is a symlink, this\n\
1945affects the link itself rather than the target.");
1946
1947static PyObject *
1948posix_lchmod(PyObject *self, PyObject *args)
1949{
Victor Stinner8c62be82010-05-06 00:08:46 +00001950 PyObject *opath;
1951 char *path;
1952 int i;
1953 int res;
1954 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
1955 &opath, &i))
1956 return NULL;
1957 path = PyBytes_AsString(opath);
1958 Py_BEGIN_ALLOW_THREADS
1959 res = lchmod(path, i);
1960 Py_END_ALLOW_THREADS
1961 if (res < 0)
1962 return posix_error_with_allocated_filename(opath);
1963 Py_DECREF(opath);
1964 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001965}
1966#endif /* HAVE_LCHMOD */
1967
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001968
Thomas Wouterscf297e42007-02-23 15:07:44 +00001969#ifdef HAVE_CHFLAGS
1970PyDoc_STRVAR(posix_chflags__doc__,
1971"chflags(path, flags)\n\n\
1972Set file flags.");
1973
1974static PyObject *
1975posix_chflags(PyObject *self, PyObject *args)
1976{
Victor Stinner8c62be82010-05-06 00:08:46 +00001977 PyObject *opath;
1978 char *path;
1979 unsigned long flags;
1980 int res;
1981 if (!PyArg_ParseTuple(args, "O&k:chflags",
1982 PyUnicode_FSConverter, &opath, &flags))
1983 return NULL;
1984 path = PyBytes_AsString(opath);
1985 Py_BEGIN_ALLOW_THREADS
1986 res = chflags(path, flags);
1987 Py_END_ALLOW_THREADS
1988 if (res < 0)
1989 return posix_error_with_allocated_filename(opath);
1990 Py_DECREF(opath);
1991 Py_INCREF(Py_None);
1992 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00001993}
1994#endif /* HAVE_CHFLAGS */
1995
1996#ifdef HAVE_LCHFLAGS
1997PyDoc_STRVAR(posix_lchflags__doc__,
1998"lchflags(path, flags)\n\n\
1999Set file flags.\n\
2000This function will not follow symbolic links.");
2001
2002static PyObject *
2003posix_lchflags(PyObject *self, PyObject *args)
2004{
Victor Stinner8c62be82010-05-06 00:08:46 +00002005 PyObject *opath;
2006 char *path;
2007 unsigned long flags;
2008 int res;
2009 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2010 PyUnicode_FSConverter, &opath, &flags))
2011 return NULL;
2012 path = PyBytes_AsString(opath);
2013 Py_BEGIN_ALLOW_THREADS
2014 res = lchflags(path, flags);
2015 Py_END_ALLOW_THREADS
2016 if (res < 0)
2017 return posix_error_with_allocated_filename(opath);
2018 Py_DECREF(opath);
2019 Py_INCREF(Py_None);
2020 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002021}
2022#endif /* HAVE_LCHFLAGS */
2023
Martin v. Löwis244edc82001-10-04 22:44:26 +00002024#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002025PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002026"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002027Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002028
2029static PyObject *
2030posix_chroot(PyObject *self, PyObject *args)
2031{
Victor Stinner8c62be82010-05-06 00:08:46 +00002032 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002033}
2034#endif
2035
Guido van Rossum21142a01999-01-08 21:05:37 +00002036#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002037PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002038"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002039force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002040
2041static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002042posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002043{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002044 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002045}
2046#endif /* HAVE_FSYNC */
2047
2048#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002049
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002050#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002051extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2052#endif
2053
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002054PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002055"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002056force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002057 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002058
2059static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002060posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002061{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002062 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002063}
2064#endif /* HAVE_FDATASYNC */
2065
2066
Fredrik Lundh10723342000-07-10 16:38:09 +00002067#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002068PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002069"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002070Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002071
Barry Warsaw53699e91996-12-10 23:23:01 +00002072static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002073posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002074{
Victor Stinner8c62be82010-05-06 00:08:46 +00002075 PyObject *opath;
2076 char *path;
2077 long uid, gid;
2078 int res;
2079 if (!PyArg_ParseTuple(args, "O&ll:chown",
2080 PyUnicode_FSConverter, &opath,
2081 &uid, &gid))
2082 return NULL;
2083 path = PyBytes_AsString(opath);
2084 Py_BEGIN_ALLOW_THREADS
2085 res = chown(path, (uid_t) uid, (gid_t) gid);
2086 Py_END_ALLOW_THREADS
2087 if (res < 0)
2088 return posix_error_with_allocated_filename(opath);
2089 Py_DECREF(opath);
2090 Py_INCREF(Py_None);
2091 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002092}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002093#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002094
Christian Heimes4e30a842007-11-30 22:12:06 +00002095#ifdef HAVE_FCHOWN
2096PyDoc_STRVAR(posix_fchown__doc__,
2097"fchown(fd, uid, gid)\n\n\
2098Change the owner and group id of the file given by file descriptor\n\
2099fd to the numeric uid and gid.");
2100
2101static PyObject *
2102posix_fchown(PyObject *self, PyObject *args)
2103{
Victor Stinner8c62be82010-05-06 00:08:46 +00002104 int fd;
2105 long uid, gid;
2106 int res;
2107 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
2108 return NULL;
2109 Py_BEGIN_ALLOW_THREADS
2110 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2111 Py_END_ALLOW_THREADS
2112 if (res < 0)
2113 return posix_error();
2114 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002115}
2116#endif /* HAVE_FCHOWN */
2117
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002118#ifdef HAVE_LCHOWN
2119PyDoc_STRVAR(posix_lchown__doc__,
2120"lchown(path, uid, gid)\n\n\
2121Change the owner and group id of path to the numeric uid and gid.\n\
2122This function will not follow symbolic links.");
2123
2124static PyObject *
2125posix_lchown(PyObject *self, PyObject *args)
2126{
Victor Stinner8c62be82010-05-06 00:08:46 +00002127 PyObject *opath;
2128 char *path;
2129 long uid, gid;
2130 int res;
2131 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2132 PyUnicode_FSConverter, &opath,
2133 &uid, &gid))
2134 return NULL;
2135 path = PyBytes_AsString(opath);
2136 Py_BEGIN_ALLOW_THREADS
2137 res = lchown(path, (uid_t) uid, (gid_t) gid);
2138 Py_END_ALLOW_THREADS
2139 if (res < 0)
2140 return posix_error_with_allocated_filename(opath);
2141 Py_DECREF(opath);
2142 Py_INCREF(Py_None);
2143 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002144}
2145#endif /* HAVE_LCHOWN */
2146
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002147
Guido van Rossum36bc6801995-06-14 22:54:23 +00002148#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002149static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002150posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002151{
Victor Stinner8c62be82010-05-06 00:08:46 +00002152 char buf[1026];
2153 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002154
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002155#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002156 if (!use_bytes) {
2157 wchar_t wbuf[1026];
2158 wchar_t *wbuf2 = wbuf;
2159 PyObject *resobj;
2160 DWORD len;
2161 Py_BEGIN_ALLOW_THREADS
2162 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2163 /* If the buffer is large enough, len does not include the
2164 terminating \0. If the buffer is too small, len includes
2165 the space needed for the terminator. */
2166 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2167 wbuf2 = malloc(len * sizeof(wchar_t));
2168 if (wbuf2)
2169 len = GetCurrentDirectoryW(len, wbuf2);
2170 }
2171 Py_END_ALLOW_THREADS
2172 if (!wbuf2) {
2173 PyErr_NoMemory();
2174 return NULL;
2175 }
2176 if (!len) {
2177 if (wbuf2 != wbuf) free(wbuf2);
2178 return win32_error("getcwdu", NULL);
2179 }
2180 resobj = PyUnicode_FromWideChar(wbuf2, len);
2181 if (wbuf2 != wbuf) free(wbuf2);
2182 return resobj;
2183 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002184#endif
2185
Victor Stinner8c62be82010-05-06 00:08:46 +00002186 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002187#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002188 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002189#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002190 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002191#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002192 Py_END_ALLOW_THREADS
2193 if (res == NULL)
2194 return posix_error();
2195 if (use_bytes)
2196 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002197 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002198}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002199
2200PyDoc_STRVAR(posix_getcwd__doc__,
2201"getcwd() -> path\n\n\
2202Return a unicode string representing the current working directory.");
2203
2204static PyObject *
2205posix_getcwd_unicode(PyObject *self)
2206{
2207 return posix_getcwd(0);
2208}
2209
2210PyDoc_STRVAR(posix_getcwdb__doc__,
2211"getcwdb() -> path\n\n\
2212Return a bytes string representing the current working directory.");
2213
2214static PyObject *
2215posix_getcwd_bytes(PyObject *self)
2216{
2217 return posix_getcwd(1);
2218}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002219#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002220
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002221
Guido van Rossumb6775db1994-08-01 11:34:53 +00002222#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002223PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002224"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002225Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002226
Barry Warsaw53699e91996-12-10 23:23:01 +00002227static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002228posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002229{
Victor Stinner8c62be82010-05-06 00:08:46 +00002230 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002231}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002232#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002233
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002234
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002235PyDoc_STRVAR(posix_listdir__doc__,
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002236"listdir([path]) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002237Return a list containing the names of the entries in the directory.\n\
2238\n\
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002239 path: path of directory to list (default: '.')\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002240\n\
2241The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002242entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002243
Barry Warsaw53699e91996-12-10 23:23:01 +00002244static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002245posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002246{
Victor Stinner8c62be82010-05-06 00:08:46 +00002247 /* XXX Should redo this putting the (now four) versions of opendir
2248 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002249#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002250
Victor Stinner8c62be82010-05-06 00:08:46 +00002251 PyObject *d, *v;
2252 HANDLE hFindFile;
2253 BOOL result;
2254 WIN32_FIND_DATA FileData;
2255 PyObject *opath;
2256 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2257 char *bufptr = namebuf;
2258 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002259
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002260 PyObject *po = NULL;
2261 if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002262 WIN32_FIND_DATAW wFileData;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002263 Py_UNICODE *wnamebuf, *po_wchars;
2264
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002265 if (po == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002266 po_wchars = L".";
2267 len = 1;
2268 } else {
2269 po_wchars = PyUnicode_AS_UNICODE(po);
2270 len = PyUnicode_GET_SIZE(po);
2271 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002272 /* Overallocate for \\*.*\0 */
Victor Stinner8c62be82010-05-06 00:08:46 +00002273 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2274 if (!wnamebuf) {
2275 PyErr_NoMemory();
2276 return NULL;
2277 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002278 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00002279 if (len > 0) {
2280 Py_UNICODE wch = wnamebuf[len-1];
2281 if (wch != L'/' && wch != L'\\' && wch != L':')
2282 wnamebuf[len++] = L'\\';
2283 wcscpy(wnamebuf + len, L"*.*");
2284 }
2285 if ((d = PyList_New(0)) == NULL) {
2286 free(wnamebuf);
2287 return NULL;
2288 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00002289 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002290 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002291 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002292 if (hFindFile == INVALID_HANDLE_VALUE) {
2293 int error = GetLastError();
2294 if (error == ERROR_FILE_NOT_FOUND) {
2295 free(wnamebuf);
2296 return d;
2297 }
2298 Py_DECREF(d);
2299 win32_error_unicode("FindFirstFileW", wnamebuf);
2300 free(wnamebuf);
2301 return NULL;
2302 }
2303 do {
2304 /* Skip over . and .. */
2305 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2306 wcscmp(wFileData.cFileName, L"..") != 0) {
2307 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2308 if (v == NULL) {
2309 Py_DECREF(d);
2310 d = NULL;
2311 break;
2312 }
2313 if (PyList_Append(d, v) != 0) {
2314 Py_DECREF(v);
2315 Py_DECREF(d);
2316 d = NULL;
2317 break;
2318 }
2319 Py_DECREF(v);
2320 }
2321 Py_BEGIN_ALLOW_THREADS
2322 result = FindNextFileW(hFindFile, &wFileData);
2323 Py_END_ALLOW_THREADS
2324 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2325 it got to the end of the directory. */
2326 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2327 Py_DECREF(d);
2328 win32_error_unicode("FindNextFileW", wnamebuf);
2329 FindClose(hFindFile);
2330 free(wnamebuf);
2331 return NULL;
2332 }
2333 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002334
Victor Stinner8c62be82010-05-06 00:08:46 +00002335 if (FindClose(hFindFile) == FALSE) {
2336 Py_DECREF(d);
2337 win32_error_unicode("FindClose", wnamebuf);
2338 free(wnamebuf);
2339 return NULL;
2340 }
2341 free(wnamebuf);
2342 return d;
2343 }
2344 /* Drop the argument parsing error as narrow strings
2345 are also valid. */
2346 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002347
Victor Stinner8c62be82010-05-06 00:08:46 +00002348 if (!PyArg_ParseTuple(args, "O&:listdir",
2349 PyUnicode_FSConverter, &opath))
2350 return NULL;
2351 if (PyBytes_GET_SIZE(opath)+1 > MAX_PATH) {
2352 PyErr_SetString(PyExc_ValueError, "path too long");
2353 Py_DECREF(opath);
2354 return NULL;
2355 }
2356 strcpy(namebuf, PyBytes_AsString(opath));
2357 len = PyObject_Size(opath);
2358 if (len > 0) {
2359 char ch = namebuf[len-1];
2360 if (ch != SEP && ch != ALTSEP && ch != ':')
2361 namebuf[len++] = '/';
2362 strcpy(namebuf + len, "*.*");
2363 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002364
Victor Stinner8c62be82010-05-06 00:08:46 +00002365 if ((d = PyList_New(0)) == NULL)
2366 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002367
Antoine Pitroub73caab2010-08-09 23:39:31 +00002368 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002369 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002370 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002371 if (hFindFile == INVALID_HANDLE_VALUE) {
2372 int error = GetLastError();
2373 if (error == ERROR_FILE_NOT_FOUND)
2374 return d;
2375 Py_DECREF(d);
2376 return win32_error("FindFirstFile", namebuf);
2377 }
2378 do {
2379 /* Skip over . and .. */
2380 if (strcmp(FileData.cFileName, ".") != 0 &&
2381 strcmp(FileData.cFileName, "..") != 0) {
2382 v = PyBytes_FromString(FileData.cFileName);
2383 if (v == NULL) {
2384 Py_DECREF(d);
2385 d = NULL;
2386 break;
2387 }
2388 if (PyList_Append(d, v) != 0) {
2389 Py_DECREF(v);
2390 Py_DECREF(d);
2391 d = NULL;
2392 break;
2393 }
2394 Py_DECREF(v);
2395 }
2396 Py_BEGIN_ALLOW_THREADS
2397 result = FindNextFile(hFindFile, &FileData);
2398 Py_END_ALLOW_THREADS
2399 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2400 it got to the end of the directory. */
2401 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2402 Py_DECREF(d);
2403 win32_error("FindNextFile", namebuf);
2404 FindClose(hFindFile);
2405 return NULL;
2406 }
2407 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002408
Victor Stinner8c62be82010-05-06 00:08:46 +00002409 if (FindClose(hFindFile) == FALSE) {
2410 Py_DECREF(d);
2411 return win32_error("FindClose", namebuf);
2412 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002413
Victor Stinner8c62be82010-05-06 00:08:46 +00002414 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002415
Tim Peters0bb44a42000-09-15 07:44:49 +00002416#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002417
2418#ifndef MAX_PATH
2419#define MAX_PATH CCHMAXPATH
2420#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002421 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002422 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002423 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002424 PyObject *d, *v;
2425 char namebuf[MAX_PATH+5];
2426 HDIR hdir = 1;
2427 ULONG srchcnt = 1;
2428 FILEFINDBUF3 ep;
2429 APIRET rc;
2430
Victor Stinner8c62be82010-05-06 00:08:46 +00002431 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002432 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002433 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002434 name = PyBytes_AsString(oname);
2435 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002436 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002437 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002438 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002439 return NULL;
2440 }
2441 strcpy(namebuf, name);
2442 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002443 if (*pt == ALTSEP)
2444 *pt = SEP;
2445 if (namebuf[len-1] != SEP)
2446 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002447 strcpy(namebuf + len, "*.*");
2448
Neal Norwitz6c913782007-10-14 03:23:09 +00002449 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002450 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002451 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002452 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002453
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002454 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2455 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002456 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002457 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2458 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2459 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002460
2461 if (rc != NO_ERROR) {
2462 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002463 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002464 }
2465
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002466 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002467 do {
2468 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002469 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002470 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002471
2472 strcpy(namebuf, ep.achName);
2473
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002474 /* Leave Case of Name Alone -- In Native Form */
2475 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002476
Christian Heimes72b710a2008-05-26 13:28:38 +00002477 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002478 if (v == NULL) {
2479 Py_DECREF(d);
2480 d = NULL;
2481 break;
2482 }
2483 if (PyList_Append(d, v) != 0) {
2484 Py_DECREF(v);
2485 Py_DECREF(d);
2486 d = NULL;
2487 break;
2488 }
2489 Py_DECREF(v);
2490 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2491 }
2492
Victor Stinnerdcb24032010-04-22 12:08:36 +00002493 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002494 return d;
2495#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002496 PyObject *oname;
2497 char *name;
2498 PyObject *d, *v;
2499 DIR *dirp;
2500 struct dirent *ep;
2501 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002502
Victor Stinner8c62be82010-05-06 00:08:46 +00002503 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002504 /* v is never read, so it does not need to be initialized yet. */
2505 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002506 arg_is_unicode = 0;
2507 PyErr_Clear();
2508 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002509 oname = NULL;
2510 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
Victor Stinner8c62be82010-05-06 00:08:46 +00002511 return NULL;
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002512 if (oname == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002513 oname = PyBytes_FromString(".");
2514 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002515 name = PyBytes_AsString(oname);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002516 Py_BEGIN_ALLOW_THREADS
2517 dirp = opendir(name);
2518 Py_END_ALLOW_THREADS
2519 if (dirp == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002520 return posix_error_with_allocated_filename(oname);
2521 }
2522 if ((d = PyList_New(0)) == NULL) {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002523 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002524 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002525 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002526 Py_DECREF(oname);
2527 return NULL;
2528 }
2529 for (;;) {
2530 errno = 0;
2531 Py_BEGIN_ALLOW_THREADS
2532 ep = readdir(dirp);
2533 Py_END_ALLOW_THREADS
2534 if (ep == NULL) {
2535 if (errno == 0) {
2536 break;
2537 } else {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002538 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002539 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002540 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002541 Py_DECREF(d);
2542 return posix_error_with_allocated_filename(oname);
2543 }
2544 }
2545 if (ep->d_name[0] == '.' &&
2546 (NAMLEN(ep) == 1 ||
2547 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2548 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002549 if (arg_is_unicode)
2550 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2551 else
2552 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002553 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002554 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002555 break;
2556 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002557 if (PyList_Append(d, v) != 0) {
2558 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002559 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002560 break;
2561 }
2562 Py_DECREF(v);
2563 }
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002564 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002565 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002566 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002567 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002568
Victor Stinner8c62be82010-05-06 00:08:46 +00002569 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002570
Tim Peters0bb44a42000-09-15 07:44:49 +00002571#endif /* which OS */
2572} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002573
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002574#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002575/* A helper function for abspath on win32 */
2576static PyObject *
2577posix__getfullpathname(PyObject *self, PyObject *args)
2578{
Victor Stinner8c62be82010-05-06 00:08:46 +00002579 PyObject *opath;
2580 char *path;
2581 char outbuf[MAX_PATH*2];
2582 char *temp;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002583#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002584 PyUnicodeObject *po;
2585 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2586 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2587 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2588 Py_UNICODE *wtemp;
2589 DWORD result;
2590 PyObject *v;
2591 result = GetFullPathNameW(wpath,
2592 sizeof(woutbuf)/sizeof(woutbuf[0]),
2593 woutbuf, &wtemp);
2594 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2595 woutbufp = malloc(result * sizeof(Py_UNICODE));
2596 if (!woutbufp)
2597 return PyErr_NoMemory();
2598 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2599 }
2600 if (result)
2601 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2602 else
2603 v = win32_error_unicode("GetFullPathNameW", wpath);
2604 if (woutbufp != woutbuf)
2605 free(woutbufp);
2606 return v;
2607 }
2608 /* Drop the argument parsing error as narrow strings
2609 are also valid. */
2610 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002611
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002612#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002613 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2614 PyUnicode_FSConverter, &opath))
2615 return NULL;
2616 path = PyBytes_AsString(opath);
2617 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2618 outbuf, &temp)) {
2619 win32_error("GetFullPathName", path);
2620 Py_DECREF(opath);
2621 return NULL;
2622 }
2623 Py_DECREF(opath);
2624 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2625 return PyUnicode_Decode(outbuf, strlen(outbuf),
2626 Py_FileSystemDefaultEncoding, NULL);
2627 }
2628 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002629} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00002630
2631/* A helper function for samepath on windows */
2632static PyObject *
2633posix__getfinalpathname(PyObject *self, PyObject *args)
2634{
2635 HANDLE hFile;
2636 int buf_size;
2637 wchar_t *target_path;
2638 int result_length;
2639 PyObject *result;
2640 wchar_t *path;
2641
2642 if (!PyArg_ParseTuple(args, "u|:_getfullpathname", &path)) {
2643 return NULL;
2644 }
2645
2646 if(!check_GetFinalPathNameByHandle()) {
2647 /* If the OS doesn't have GetFinalPathNameByHandle, return a
2648 NotImplementedError. */
2649 return PyErr_Format(PyExc_NotImplementedError,
2650 "GetFinalPathNameByHandle not available on this platform");
2651 }
2652
2653 hFile = CreateFileW(
2654 path,
2655 0, /* desired access */
2656 0, /* share mode */
2657 NULL, /* security attributes */
2658 OPEN_EXISTING,
2659 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
2660 FILE_FLAG_BACKUP_SEMANTICS,
2661 NULL);
2662
2663 if(hFile == INVALID_HANDLE_VALUE) {
2664 return win32_error_unicode("GetFinalPathNamyByHandle", path);
Brian Curtin74e45612010-07-09 15:58:59 +00002665 return PyErr_Format(PyExc_RuntimeError,
2666 "Could not get a handle to file.");
Brian Curtind40e6f72010-07-08 21:39:08 +00002667 }
2668
2669 /* We have a good handle to the target, use it to determine the
2670 target path name. */
2671 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
2672
2673 if(!buf_size)
2674 return win32_error_unicode("GetFinalPathNameByHandle", path);
2675
2676 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
2677 if(!target_path)
2678 return PyErr_NoMemory();
2679
2680 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
2681 buf_size, VOLUME_NAME_DOS);
2682 if(!result_length)
2683 return win32_error_unicode("GetFinalPathNamyByHandle", path);
2684
2685 if(!CloseHandle(hFile))
2686 return win32_error_unicode("GetFinalPathNameByHandle", path);
2687
2688 target_path[result_length] = 0;
2689 result = PyUnicode_FromUnicode(target_path, result_length);
2690 free(target_path);
2691 return result;
2692
2693} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00002694
2695static PyObject *
2696posix__getfileinformation(PyObject *self, PyObject *args)
2697{
2698 HANDLE hFile;
2699 BY_HANDLE_FILE_INFORMATION info;
2700 int fd;
2701
2702 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
2703 return NULL;
2704
2705 if (!_PyVerify_fd(fd)) {
2706 PyErr_SetString(PyExc_ValueError, "received invalid file descriptor");
2707 return NULL;
2708 }
2709
2710 hFile = (HANDLE)_get_osfhandle(fd);
2711 if (hFile == INVALID_HANDLE_VALUE)
2712 return win32_error("_getfileinformation", NULL);
2713
2714 if (!GetFileInformationByHandle(hFile, &info))
2715 return win32_error("_getfileinformation", NULL);
2716
2717 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
2718 info.nFileIndexHigh,
2719 info.nFileIndexLow);
2720}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002721#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002722
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002723PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002724"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002725Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002726
Barry Warsaw53699e91996-12-10 23:23:01 +00002727static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002728posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002729{
Victor Stinner8c62be82010-05-06 00:08:46 +00002730 int res;
2731 PyObject *opath;
2732 char *path;
2733 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002734
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002735#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002736 PyUnicodeObject *po;
2737 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2738 Py_BEGIN_ALLOW_THREADS
2739 /* PyUnicode_AS_UNICODE OK without thread lock as
2740 it is a simple dereference. */
2741 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2742 Py_END_ALLOW_THREADS
2743 if (!res)
2744 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2745 Py_INCREF(Py_None);
2746 return Py_None;
2747 }
2748 /* Drop the argument parsing error as narrow strings
2749 are also valid. */
2750 PyErr_Clear();
2751 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2752 PyUnicode_FSConverter, &opath, &mode))
2753 return NULL;
2754 path = PyBytes_AsString(opath);
2755 Py_BEGIN_ALLOW_THREADS
2756 /* PyUnicode_AS_UNICODE OK without thread lock as
2757 it is a simple dereference. */
2758 res = CreateDirectoryA(path, NULL);
2759 Py_END_ALLOW_THREADS
2760 if (!res) {
2761 win32_error("mkdir", path);
2762 Py_DECREF(opath);
2763 return NULL;
2764 }
2765 Py_DECREF(opath);
2766 Py_INCREF(Py_None);
2767 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002768#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002769
Victor Stinner8c62be82010-05-06 00:08:46 +00002770 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2771 PyUnicode_FSConverter, &opath, &mode))
2772 return NULL;
2773 path = PyBytes_AsString(opath);
2774 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002775#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00002776 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002777#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002778 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002779#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002780 Py_END_ALLOW_THREADS
2781 if (res < 0)
2782 return posix_error_with_allocated_filename(opath);
2783 Py_DECREF(opath);
2784 Py_INCREF(Py_None);
2785 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002786#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002787}
2788
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002789
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002790/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2791#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002792#include <sys/resource.h>
2793#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002794
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002795
2796#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002797PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002798"nice(inc) -> new_priority\n\n\
2799Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002800
Barry Warsaw53699e91996-12-10 23:23:01 +00002801static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002802posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002803{
Victor Stinner8c62be82010-05-06 00:08:46 +00002804 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002805
Victor Stinner8c62be82010-05-06 00:08:46 +00002806 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2807 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002808
Victor Stinner8c62be82010-05-06 00:08:46 +00002809 /* There are two flavours of 'nice': one that returns the new
2810 priority (as required by almost all standards out there) and the
2811 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2812 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002813
Victor Stinner8c62be82010-05-06 00:08:46 +00002814 If we are of the nice family that returns the new priority, we
2815 need to clear errno before the call, and check if errno is filled
2816 before calling posix_error() on a returnvalue of -1, because the
2817 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002818
Victor Stinner8c62be82010-05-06 00:08:46 +00002819 errno = 0;
2820 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002821#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00002822 if (value == 0)
2823 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002824#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002825 if (value == -1 && errno != 0)
2826 /* either nice() or getpriority() returned an error */
2827 return posix_error();
2828 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002829}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002830#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002831
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002832PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002833"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002834Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002835
Barry Warsaw53699e91996-12-10 23:23:01 +00002836static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002837posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002838{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002839#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002840 PyObject *o1, *o2;
2841 char *p1, *p2;
2842 BOOL result;
2843 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2844 goto error;
2845 if (!convert_to_unicode(&o1))
2846 goto error;
2847 if (!convert_to_unicode(&o2)) {
2848 Py_DECREF(o1);
2849 goto error;
2850 }
2851 Py_BEGIN_ALLOW_THREADS
2852 result = MoveFileW(PyUnicode_AsUnicode(o1),
2853 PyUnicode_AsUnicode(o2));
2854 Py_END_ALLOW_THREADS
2855 Py_DECREF(o1);
2856 Py_DECREF(o2);
2857 if (!result)
2858 return win32_error("rename", NULL);
2859 Py_INCREF(Py_None);
2860 return Py_None;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002861error:
Victor Stinner8c62be82010-05-06 00:08:46 +00002862 PyErr_Clear();
2863 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2864 return NULL;
2865 Py_BEGIN_ALLOW_THREADS
2866 result = MoveFileA(p1, p2);
2867 Py_END_ALLOW_THREADS
2868 if (!result)
2869 return win32_error("rename", NULL);
2870 Py_INCREF(Py_None);
2871 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002872#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002873 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002874#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002875}
2876
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002877
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002878PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002879"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002880Remove a directory.");
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_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002884{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002885#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002886 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002887#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002888 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002889#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002890}
2891
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002892
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002893PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002894"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002895Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002896
Barry Warsaw53699e91996-12-10 23:23:01 +00002897static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002898posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002899{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002900#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00002901 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002902#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002903 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002904#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002905}
2906
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002907
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002908#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002909PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002910"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002911Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002912
Barry Warsaw53699e91996-12-10 23:23:01 +00002913static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002914posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002915{
Victor Stinner8c62be82010-05-06 00:08:46 +00002916 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002917#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002918 wchar_t *command;
2919 if (!PyArg_ParseTuple(args, "u:system", &command))
2920 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00002921
Victor Stinner8c62be82010-05-06 00:08:46 +00002922 Py_BEGIN_ALLOW_THREADS
2923 sts = _wsystem(command);
2924 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00002925#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002926 PyObject *command_obj;
2927 char *command;
2928 if (!PyArg_ParseTuple(args, "O&:system",
2929 PyUnicode_FSConverter, &command_obj))
2930 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00002931
Victor Stinner8c62be82010-05-06 00:08:46 +00002932 command = PyBytes_AsString(command_obj);
2933 Py_BEGIN_ALLOW_THREADS
2934 sts = system(command);
2935 Py_END_ALLOW_THREADS
2936 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00002937#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002938 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002939}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002940#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002941
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002942
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002943PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002944"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002945Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002946
Barry Warsaw53699e91996-12-10 23:23:01 +00002947static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002948posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002949{
Victor Stinner8c62be82010-05-06 00:08:46 +00002950 int i;
2951 if (!PyArg_ParseTuple(args, "i:umask", &i))
2952 return NULL;
2953 i = (int)umask(i);
2954 if (i < 0)
2955 return posix_error();
2956 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002957}
2958
Brian Curtind40e6f72010-07-08 21:39:08 +00002959#ifdef MS_WINDOWS
2960
2961/* override the default DeleteFileW behavior so that directory
2962symlinks can be removed with this function, the same as with
2963Unix symlinks */
2964BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
2965{
2966 WIN32_FILE_ATTRIBUTE_DATA info;
2967 WIN32_FIND_DATAW find_data;
2968 HANDLE find_data_handle;
2969 int is_directory = 0;
2970 int is_link = 0;
2971
2972 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
2973 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
2974
2975 /* Get WIN32_FIND_DATA structure for the path to determine if
2976 it is a symlink */
2977 if(is_directory &&
2978 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
2979 find_data_handle = FindFirstFileW(lpFileName, &find_data);
2980
2981 if(find_data_handle != INVALID_HANDLE_VALUE) {
2982 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
2983 FindClose(find_data_handle);
2984 }
2985 }
2986 }
2987
2988 if (is_directory && is_link)
2989 return RemoveDirectoryW(lpFileName);
2990
2991 return DeleteFileW(lpFileName);
2992}
2993#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002994
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002995PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002996"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002997Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002998
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002999PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003000"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003001Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003002
Barry Warsaw53699e91996-12-10 23:23:01 +00003003static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003004posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003005{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003006#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003007 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3008 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003009#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003010 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003011#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003012}
3013
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003014
Guido van Rossumb6775db1994-08-01 11:34:53 +00003015#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003016PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003017"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003018Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003019
Barry Warsaw53699e91996-12-10 23:23:01 +00003020static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003021posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003022{
Victor Stinner8c62be82010-05-06 00:08:46 +00003023 struct utsname u;
3024 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003025
Victor Stinner8c62be82010-05-06 00:08:46 +00003026 Py_BEGIN_ALLOW_THREADS
3027 res = uname(&u);
3028 Py_END_ALLOW_THREADS
3029 if (res < 0)
3030 return posix_error();
3031 return Py_BuildValue("(sssss)",
3032 u.sysname,
3033 u.nodename,
3034 u.release,
3035 u.version,
3036 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003037}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003038#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003039
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003040static int
3041extract_time(PyObject *t, long* sec, long* usec)
3042{
Victor Stinner8c62be82010-05-06 00:08:46 +00003043 long intval;
3044 if (PyFloat_Check(t)) {
3045 double tval = PyFloat_AsDouble(t);
3046 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
3047 if (!intobj)
3048 return -1;
3049 intval = PyLong_AsLong(intobj);
3050 Py_DECREF(intobj);
3051 if (intval == -1 && PyErr_Occurred())
3052 return -1;
3053 *sec = intval;
3054 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
3055 if (*usec < 0)
3056 /* If rounding gave us a negative number,
3057 truncate. */
3058 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00003059 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003060 }
3061 intval = PyLong_AsLong(t);
3062 if (intval == -1 && PyErr_Occurred())
3063 return -1;
3064 *sec = intval;
3065 *usec = 0;
3066 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003067}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003068
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003069PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00003070"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00003071utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00003072Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003073second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003074
Barry Warsaw53699e91996-12-10 23:23:01 +00003075static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003076posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003077{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003078#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003079 PyObject *arg;
3080 PyUnicodeObject *obwpath;
3081 wchar_t *wpath = NULL;
3082 PyObject *oapath;
3083 char *apath;
3084 HANDLE hFile;
3085 long atimesec, mtimesec, ausec, musec;
3086 FILETIME atime, mtime;
3087 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003088
Victor Stinner8c62be82010-05-06 00:08:46 +00003089 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
3090 wpath = PyUnicode_AS_UNICODE(obwpath);
3091 Py_BEGIN_ALLOW_THREADS
3092 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3093 NULL, OPEN_EXISTING,
3094 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3095 Py_END_ALLOW_THREADS
3096 if (hFile == INVALID_HANDLE_VALUE)
3097 return win32_error_unicode("utime", wpath);
3098 } else
3099 /* Drop the argument parsing error as narrow strings
3100 are also valid. */
3101 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003102
Victor Stinner8c62be82010-05-06 00:08:46 +00003103 if (!wpath) {
3104 if (!PyArg_ParseTuple(args, "O&O:utime",
3105 PyUnicode_FSConverter, &oapath, &arg))
3106 return NULL;
3107 apath = PyBytes_AsString(oapath);
3108 Py_BEGIN_ALLOW_THREADS
3109 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3110 NULL, OPEN_EXISTING,
3111 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3112 Py_END_ALLOW_THREADS
3113 if (hFile == INVALID_HANDLE_VALUE) {
3114 win32_error("utime", apath);
3115 Py_DECREF(oapath);
3116 return NULL;
3117 }
3118 Py_DECREF(oapath);
3119 }
3120
3121 if (arg == Py_None) {
3122 SYSTEMTIME now;
3123 GetSystemTime(&now);
3124 if (!SystemTimeToFileTime(&now, &mtime) ||
3125 !SystemTimeToFileTime(&now, &atime)) {
3126 win32_error("utime", NULL);
3127 goto done;
3128 }
3129 }
3130 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3131 PyErr_SetString(PyExc_TypeError,
3132 "utime() arg 2 must be a tuple (atime, mtime)");
3133 goto done;
3134 }
3135 else {
3136 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3137 &atimesec, &ausec) == -1)
3138 goto done;
3139 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3140 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3141 &mtimesec, &musec) == -1)
3142 goto done;
3143 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3144 }
3145 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3146 /* Avoid putting the file name into the error here,
3147 as that may confuse the user into believing that
3148 something is wrong with the file, when it also
3149 could be the time stamp that gives a problem. */
3150 win32_error("utime", NULL);
3151 }
3152 Py_INCREF(Py_None);
3153 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003154done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003155 CloseHandle(hFile);
3156 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003157#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003158
Victor Stinner8c62be82010-05-06 00:08:46 +00003159 PyObject *opath;
3160 char *path;
3161 long atime, mtime, ausec, musec;
3162 int res;
3163 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003164
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003165#if defined(HAVE_UTIMES)
Victor Stinner8c62be82010-05-06 00:08:46 +00003166 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003167#define ATIME buf[0].tv_sec
3168#define MTIME buf[1].tv_sec
3169#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003170/* XXX should define struct utimbuf instead, above */
Victor Stinner8c62be82010-05-06 00:08:46 +00003171 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003172#define ATIME buf.actime
3173#define MTIME buf.modtime
3174#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003175#else /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003176 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003177#define ATIME buf[0]
3178#define MTIME buf[1]
3179#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003180#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003181
Mark Hammond817c9292003-12-03 01:22:38 +00003182
Victor Stinner8c62be82010-05-06 00:08:46 +00003183 if (!PyArg_ParseTuple(args, "O&O:utime",
3184 PyUnicode_FSConverter, &opath, &arg))
3185 return NULL;
3186 path = PyBytes_AsString(opath);
3187 if (arg == Py_None) {
3188 /* optional time values not given */
3189 Py_BEGIN_ALLOW_THREADS
3190 res = utime(path, NULL);
3191 Py_END_ALLOW_THREADS
3192 }
3193 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3194 PyErr_SetString(PyExc_TypeError,
3195 "utime() arg 2 must be a tuple (atime, mtime)");
3196 Py_DECREF(opath);
3197 return NULL;
3198 }
3199 else {
3200 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3201 &atime, &ausec) == -1) {
3202 Py_DECREF(opath);
3203 return NULL;
3204 }
3205 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3206 &mtime, &musec) == -1) {
3207 Py_DECREF(opath);
3208 return NULL;
3209 }
3210 ATIME = atime;
3211 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003212#ifdef HAVE_UTIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00003213 buf[0].tv_usec = ausec;
3214 buf[1].tv_usec = musec;
3215 Py_BEGIN_ALLOW_THREADS
3216 res = utimes(path, buf);
3217 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003218#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003219 Py_BEGIN_ALLOW_THREADS
3220 res = utime(path, UTIME_ARG);
3221 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003222#endif /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003223 }
3224 if (res < 0) {
3225 return posix_error_with_allocated_filename(opath);
3226 }
3227 Py_DECREF(opath);
3228 Py_INCREF(Py_None);
3229 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003230#undef UTIME_ARG
3231#undef ATIME
3232#undef MTIME
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003233#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003234}
3235
Guido van Rossum85e3b011991-06-03 12:42:10 +00003236
Guido van Rossum3b066191991-06-04 19:40:25 +00003237/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003238
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003239PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003240"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003241Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003242
Barry Warsaw53699e91996-12-10 23:23:01 +00003243static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003244posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003245{
Victor Stinner8c62be82010-05-06 00:08:46 +00003246 int sts;
3247 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3248 return NULL;
3249 _exit(sts);
3250 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003251}
3252
Martin v. Löwis114619e2002-10-07 06:44:21 +00003253#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3254static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003255free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003256{
Victor Stinner8c62be82010-05-06 00:08:46 +00003257 Py_ssize_t i;
3258 for (i = 0; i < count; i++)
3259 PyMem_Free(array[i]);
3260 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003261}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003262
Antoine Pitrou69f71142009-05-24 21:25:49 +00003263static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003264int fsconvert_strdup(PyObject *o, char**out)
3265{
Victor Stinner8c62be82010-05-06 00:08:46 +00003266 PyObject *bytes;
3267 Py_ssize_t size;
3268 if (!PyUnicode_FSConverter(o, &bytes))
3269 return 0;
3270 size = PyBytes_GET_SIZE(bytes);
3271 *out = PyMem_Malloc(size+1);
3272 if (!*out)
3273 return 0;
3274 memcpy(*out, PyBytes_AsString(bytes), size+1);
3275 Py_DECREF(bytes);
3276 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003277}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003278#endif
3279
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003280
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003281#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003282PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003283"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003284Execute an executable path with arguments, replacing current process.\n\
3285\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003286 path: path of executable file\n\
3287 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003288
Barry Warsaw53699e91996-12-10 23:23:01 +00003289static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003290posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003291{
Victor Stinner8c62be82010-05-06 00:08:46 +00003292 PyObject *opath;
3293 char *path;
3294 PyObject *argv;
3295 char **argvlist;
3296 Py_ssize_t i, argc;
3297 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003298
Victor Stinner8c62be82010-05-06 00:08:46 +00003299 /* execv has two arguments: (path, argv), where
3300 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003301
Victor Stinner8c62be82010-05-06 00:08:46 +00003302 if (!PyArg_ParseTuple(args, "O&O:execv",
3303 PyUnicode_FSConverter,
3304 &opath, &argv))
3305 return NULL;
3306 path = PyBytes_AsString(opath);
3307 if (PyList_Check(argv)) {
3308 argc = PyList_Size(argv);
3309 getitem = PyList_GetItem;
3310 }
3311 else if (PyTuple_Check(argv)) {
3312 argc = PyTuple_Size(argv);
3313 getitem = PyTuple_GetItem;
3314 }
3315 else {
3316 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3317 Py_DECREF(opath);
3318 return NULL;
3319 }
3320 if (argc < 1) {
3321 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3322 Py_DECREF(opath);
3323 return NULL;
3324 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003325
Victor Stinner8c62be82010-05-06 00:08:46 +00003326 argvlist = PyMem_NEW(char *, argc+1);
3327 if (argvlist == NULL) {
3328 Py_DECREF(opath);
3329 return PyErr_NoMemory();
3330 }
3331 for (i = 0; i < argc; i++) {
3332 if (!fsconvert_strdup((*getitem)(argv, i),
3333 &argvlist[i])) {
3334 free_string_array(argvlist, i);
3335 PyErr_SetString(PyExc_TypeError,
3336 "execv() arg 2 must contain only strings");
3337 Py_DECREF(opath);
3338 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003339
Victor Stinner8c62be82010-05-06 00:08:46 +00003340 }
3341 }
3342 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003343
Victor Stinner8c62be82010-05-06 00:08:46 +00003344 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003345
Victor Stinner8c62be82010-05-06 00:08:46 +00003346 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003347
Victor Stinner8c62be82010-05-06 00:08:46 +00003348 free_string_array(argvlist, argc);
3349 Py_DECREF(opath);
3350 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003351}
3352
Victor Stinner13bb71c2010-04-23 21:41:56 +00003353static char**
3354parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3355{
Victor Stinner8c62be82010-05-06 00:08:46 +00003356 char **envlist;
3357 Py_ssize_t i, pos, envc;
3358 PyObject *keys=NULL, *vals=NULL;
3359 PyObject *key, *val, *key2, *val2;
3360 char *p, *k, *v;
3361 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003362
Victor Stinner8c62be82010-05-06 00:08:46 +00003363 i = PyMapping_Size(env);
3364 if (i < 0)
3365 return NULL;
3366 envlist = PyMem_NEW(char *, i + 1);
3367 if (envlist == NULL) {
3368 PyErr_NoMemory();
3369 return NULL;
3370 }
3371 envc = 0;
3372 keys = PyMapping_Keys(env);
3373 vals = PyMapping_Values(env);
3374 if (!keys || !vals)
3375 goto error;
3376 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3377 PyErr_Format(PyExc_TypeError,
3378 "env.keys() or env.values() is not a list");
3379 goto error;
3380 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003381
Victor Stinner8c62be82010-05-06 00:08:46 +00003382 for (pos = 0; pos < i; pos++) {
3383 key = PyList_GetItem(keys, pos);
3384 val = PyList_GetItem(vals, pos);
3385 if (!key || !val)
3386 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003387
Victor Stinner8c62be82010-05-06 00:08:46 +00003388 if (PyUnicode_FSConverter(key, &key2) == 0)
3389 goto error;
3390 if (PyUnicode_FSConverter(val, &val2) == 0) {
3391 Py_DECREF(key2);
3392 goto error;
3393 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003394
3395#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003396 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3397 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00003398#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003399 k = PyBytes_AsString(key2);
3400 v = PyBytes_AsString(val2);
3401 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003402
Victor Stinner8c62be82010-05-06 00:08:46 +00003403 p = PyMem_NEW(char, len);
3404 if (p == NULL) {
3405 PyErr_NoMemory();
3406 Py_DECREF(key2);
3407 Py_DECREF(val2);
3408 goto error;
3409 }
3410 PyOS_snprintf(p, len, "%s=%s", k, v);
3411 envlist[envc++] = p;
3412 Py_DECREF(key2);
3413 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003414#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003415 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003416#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003417 }
3418 Py_DECREF(vals);
3419 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003420
Victor Stinner8c62be82010-05-06 00:08:46 +00003421 envlist[envc] = 0;
3422 *envc_ptr = envc;
3423 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003424
3425error:
Victor Stinner8c62be82010-05-06 00:08:46 +00003426 Py_XDECREF(keys);
3427 Py_XDECREF(vals);
3428 while (--envc >= 0)
3429 PyMem_DEL(envlist[envc]);
3430 PyMem_DEL(envlist);
3431 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003432}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003433
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003434PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003435"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003436Execute a path with arguments and environment, replacing current process.\n\
3437\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003438 path: path of executable file\n\
3439 args: tuple or list of arguments\n\
3440 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003441
Barry Warsaw53699e91996-12-10 23:23:01 +00003442static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003443posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003444{
Victor Stinner8c62be82010-05-06 00:08:46 +00003445 PyObject *opath;
3446 char *path;
3447 PyObject *argv, *env;
3448 char **argvlist;
3449 char **envlist;
3450 Py_ssize_t i, argc, envc;
3451 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3452 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003453
Victor Stinner8c62be82010-05-06 00:08:46 +00003454 /* execve has three arguments: (path, argv, env), where
3455 argv is a list or tuple of strings and env is a dictionary
3456 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003457
Victor Stinner8c62be82010-05-06 00:08:46 +00003458 if (!PyArg_ParseTuple(args, "O&OO:execve",
3459 PyUnicode_FSConverter,
3460 &opath, &argv, &env))
3461 return NULL;
3462 path = PyBytes_AsString(opath);
3463 if (PyList_Check(argv)) {
3464 argc = PyList_Size(argv);
3465 getitem = PyList_GetItem;
3466 }
3467 else if (PyTuple_Check(argv)) {
3468 argc = PyTuple_Size(argv);
3469 getitem = PyTuple_GetItem;
3470 }
3471 else {
3472 PyErr_SetString(PyExc_TypeError,
3473 "execve() arg 2 must be a tuple or list");
3474 goto fail_0;
3475 }
3476 if (!PyMapping_Check(env)) {
3477 PyErr_SetString(PyExc_TypeError,
3478 "execve() arg 3 must be a mapping object");
3479 goto fail_0;
3480 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003481
Victor Stinner8c62be82010-05-06 00:08:46 +00003482 argvlist = PyMem_NEW(char *, argc+1);
3483 if (argvlist == NULL) {
3484 PyErr_NoMemory();
3485 goto fail_0;
3486 }
3487 for (i = 0; i < argc; i++) {
3488 if (!fsconvert_strdup((*getitem)(argv, i),
3489 &argvlist[i]))
3490 {
3491 lastarg = i;
3492 goto fail_1;
3493 }
3494 }
3495 lastarg = argc;
3496 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003497
Victor Stinner8c62be82010-05-06 00:08:46 +00003498 envlist = parse_envlist(env, &envc);
3499 if (envlist == NULL)
3500 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003501
Victor Stinner8c62be82010-05-06 00:08:46 +00003502 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003503
Victor Stinner8c62be82010-05-06 00:08:46 +00003504 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003505
Victor Stinner8c62be82010-05-06 00:08:46 +00003506 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003507
Victor Stinner8c62be82010-05-06 00:08:46 +00003508 while (--envc >= 0)
3509 PyMem_DEL(envlist[envc]);
3510 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003511 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003512 free_string_array(argvlist, lastarg);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003513 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003514 Py_DECREF(opath);
3515 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003516}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003517#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003518
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003519
Guido van Rossuma1065681999-01-25 23:20:23 +00003520#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003521PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003522"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003523Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003524\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003525 mode: mode of process creation\n\
3526 path: path of executable file\n\
3527 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003528
3529static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003530posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003531{
Victor Stinner8c62be82010-05-06 00:08:46 +00003532 PyObject *opath;
3533 char *path;
3534 PyObject *argv;
3535 char **argvlist;
3536 int mode, i;
3537 Py_ssize_t argc;
3538 Py_intptr_t spawnval;
3539 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003540
Victor Stinner8c62be82010-05-06 00:08:46 +00003541 /* spawnv has three arguments: (mode, path, argv), where
3542 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003543
Victor Stinner8c62be82010-05-06 00:08:46 +00003544 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3545 PyUnicode_FSConverter,
3546 &opath, &argv))
3547 return NULL;
3548 path = PyBytes_AsString(opath);
3549 if (PyList_Check(argv)) {
3550 argc = PyList_Size(argv);
3551 getitem = PyList_GetItem;
3552 }
3553 else if (PyTuple_Check(argv)) {
3554 argc = PyTuple_Size(argv);
3555 getitem = PyTuple_GetItem;
3556 }
3557 else {
3558 PyErr_SetString(PyExc_TypeError,
3559 "spawnv() arg 2 must be a tuple or list");
3560 Py_DECREF(opath);
3561 return NULL;
3562 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003563
Victor Stinner8c62be82010-05-06 00:08:46 +00003564 argvlist = PyMem_NEW(char *, argc+1);
3565 if (argvlist == NULL) {
3566 Py_DECREF(opath);
3567 return PyErr_NoMemory();
3568 }
3569 for (i = 0; i < argc; i++) {
3570 if (!fsconvert_strdup((*getitem)(argv, i),
3571 &argvlist[i])) {
3572 free_string_array(argvlist, i);
3573 PyErr_SetString(
3574 PyExc_TypeError,
3575 "spawnv() arg 2 must contain only strings");
3576 Py_DECREF(opath);
3577 return NULL;
3578 }
3579 }
3580 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003581
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003582#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003583 Py_BEGIN_ALLOW_THREADS
3584 spawnval = spawnv(mode, path, argvlist);
3585 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003586#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003587 if (mode == _OLD_P_OVERLAY)
3588 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003589
Victor Stinner8c62be82010-05-06 00:08:46 +00003590 Py_BEGIN_ALLOW_THREADS
3591 spawnval = _spawnv(mode, path, argvlist);
3592 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003593#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003594
Victor Stinner8c62be82010-05-06 00:08:46 +00003595 free_string_array(argvlist, argc);
3596 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003597
Victor Stinner8c62be82010-05-06 00:08:46 +00003598 if (spawnval == -1)
3599 return posix_error();
3600 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003601#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003602 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003603#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003604 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003605#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003606}
3607
3608
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003609PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003610"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003611Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003612\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003613 mode: mode of process creation\n\
3614 path: path of executable file\n\
3615 args: tuple or list of arguments\n\
3616 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003617
3618static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003619posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003620{
Victor Stinner8c62be82010-05-06 00:08:46 +00003621 PyObject *opath;
3622 char *path;
3623 PyObject *argv, *env;
3624 char **argvlist;
3625 char **envlist;
3626 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003627 int mode;
3628 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003629 Py_intptr_t spawnval;
3630 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3631 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003632
Victor Stinner8c62be82010-05-06 00:08:46 +00003633 /* spawnve has four arguments: (mode, path, argv, env), where
3634 argv is a list or tuple of strings and env is a dictionary
3635 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003636
Victor Stinner8c62be82010-05-06 00:08:46 +00003637 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3638 PyUnicode_FSConverter,
3639 &opath, &argv, &env))
3640 return NULL;
3641 path = PyBytes_AsString(opath);
3642 if (PyList_Check(argv)) {
3643 argc = PyList_Size(argv);
3644 getitem = PyList_GetItem;
3645 }
3646 else if (PyTuple_Check(argv)) {
3647 argc = PyTuple_Size(argv);
3648 getitem = PyTuple_GetItem;
3649 }
3650 else {
3651 PyErr_SetString(PyExc_TypeError,
3652 "spawnve() arg 2 must be a tuple or list");
3653 goto fail_0;
3654 }
3655 if (!PyMapping_Check(env)) {
3656 PyErr_SetString(PyExc_TypeError,
3657 "spawnve() arg 3 must be a mapping object");
3658 goto fail_0;
3659 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003660
Victor Stinner8c62be82010-05-06 00:08:46 +00003661 argvlist = PyMem_NEW(char *, argc+1);
3662 if (argvlist == NULL) {
3663 PyErr_NoMemory();
3664 goto fail_0;
3665 }
3666 for (i = 0; i < argc; i++) {
3667 if (!fsconvert_strdup((*getitem)(argv, i),
3668 &argvlist[i]))
3669 {
3670 lastarg = i;
3671 goto fail_1;
3672 }
3673 }
3674 lastarg = argc;
3675 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003676
Victor Stinner8c62be82010-05-06 00:08:46 +00003677 envlist = parse_envlist(env, &envc);
3678 if (envlist == NULL)
3679 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003680
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003681#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003682 Py_BEGIN_ALLOW_THREADS
3683 spawnval = spawnve(mode, path, argvlist, envlist);
3684 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003685#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003686 if (mode == _OLD_P_OVERLAY)
3687 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003688
Victor Stinner8c62be82010-05-06 00:08:46 +00003689 Py_BEGIN_ALLOW_THREADS
3690 spawnval = _spawnve(mode, path, argvlist, envlist);
3691 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003692#endif
Tim Peters25059d32001-12-07 20:35:43 +00003693
Victor Stinner8c62be82010-05-06 00:08:46 +00003694 if (spawnval == -1)
3695 (void) posix_error();
3696 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003697#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003698 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003699#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003700 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003701#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003702
Victor Stinner8c62be82010-05-06 00:08:46 +00003703 while (--envc >= 0)
3704 PyMem_DEL(envlist[envc]);
3705 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003706 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003707 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003708 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003709 Py_DECREF(opath);
3710 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003711}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003712
3713/* OS/2 supports spawnvp & spawnvpe natively */
3714#if defined(PYOS_OS2)
3715PyDoc_STRVAR(posix_spawnvp__doc__,
3716"spawnvp(mode, file, args)\n\n\
3717Execute the program 'file' in a new process, using the environment\n\
3718search path to find the file.\n\
3719\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003720 mode: mode of process creation\n\
3721 file: executable file name\n\
3722 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003723
3724static PyObject *
3725posix_spawnvp(PyObject *self, PyObject *args)
3726{
Victor Stinner8c62be82010-05-06 00:08:46 +00003727 PyObject *opath;
3728 char *path;
3729 PyObject *argv;
3730 char **argvlist;
3731 int mode, i, argc;
3732 Py_intptr_t spawnval;
3733 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003734
Victor Stinner8c62be82010-05-06 00:08:46 +00003735 /* spawnvp has three arguments: (mode, path, argv), where
3736 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003737
Victor Stinner8c62be82010-05-06 00:08:46 +00003738 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3739 PyUnicode_FSConverter,
3740 &opath, &argv))
3741 return NULL;
3742 path = PyBytes_AsString(opath);
3743 if (PyList_Check(argv)) {
3744 argc = PyList_Size(argv);
3745 getitem = PyList_GetItem;
3746 }
3747 else if (PyTuple_Check(argv)) {
3748 argc = PyTuple_Size(argv);
3749 getitem = PyTuple_GetItem;
3750 }
3751 else {
3752 PyErr_SetString(PyExc_TypeError,
3753 "spawnvp() arg 2 must be a tuple or list");
3754 Py_DECREF(opath);
3755 return NULL;
3756 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003757
Victor Stinner8c62be82010-05-06 00:08:46 +00003758 argvlist = PyMem_NEW(char *, argc+1);
3759 if (argvlist == NULL) {
3760 Py_DECREF(opath);
3761 return PyErr_NoMemory();
3762 }
3763 for (i = 0; i < argc; i++) {
3764 if (!fsconvert_strdup((*getitem)(argv, i),
3765 &argvlist[i])) {
3766 free_string_array(argvlist, i);
3767 PyErr_SetString(
3768 PyExc_TypeError,
3769 "spawnvp() arg 2 must contain only strings");
3770 Py_DECREF(opath);
3771 return NULL;
3772 }
3773 }
3774 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003775
Victor Stinner8c62be82010-05-06 00:08:46 +00003776 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003777#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003778 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003779#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003780 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003781#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003782 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003783
Victor Stinner8c62be82010-05-06 00:08:46 +00003784 free_string_array(argvlist, argc);
3785 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003786
Victor Stinner8c62be82010-05-06 00:08:46 +00003787 if (spawnval == -1)
3788 return posix_error();
3789 else
3790 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003791}
3792
3793
3794PyDoc_STRVAR(posix_spawnvpe__doc__,
3795"spawnvpe(mode, file, args, env)\n\n\
3796Execute the program 'file' in a new process, using the environment\n\
3797search path to find the file.\n\
3798\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003799 mode: mode of process creation\n\
3800 file: executable file name\n\
3801 args: tuple or list of arguments\n\
3802 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003803
3804static PyObject *
3805posix_spawnvpe(PyObject *self, PyObject *args)
3806{
Victor Stinner8c62be82010-05-06 00:08:46 +00003807 PyObject *opath
3808 char *path;
3809 PyObject *argv, *env;
3810 char **argvlist;
3811 char **envlist;
3812 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003813 int mode;
3814 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003815 Py_intptr_t spawnval;
3816 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3817 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003818
Victor Stinner8c62be82010-05-06 00:08:46 +00003819 /* spawnvpe has four arguments: (mode, path, argv, env), where
3820 argv is a list or tuple of strings and env is a dictionary
3821 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003822
Victor Stinner8c62be82010-05-06 00:08:46 +00003823 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3824 PyUnicode_FSConverter,
3825 &opath, &argv, &env))
3826 return NULL;
3827 path = PyBytes_AsString(opath);
3828 if (PyList_Check(argv)) {
3829 argc = PyList_Size(argv);
3830 getitem = PyList_GetItem;
3831 }
3832 else if (PyTuple_Check(argv)) {
3833 argc = PyTuple_Size(argv);
3834 getitem = PyTuple_GetItem;
3835 }
3836 else {
3837 PyErr_SetString(PyExc_TypeError,
3838 "spawnvpe() arg 2 must be a tuple or list");
3839 goto fail_0;
3840 }
3841 if (!PyMapping_Check(env)) {
3842 PyErr_SetString(PyExc_TypeError,
3843 "spawnvpe() arg 3 must be a mapping object");
3844 goto fail_0;
3845 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003846
Victor Stinner8c62be82010-05-06 00:08:46 +00003847 argvlist = PyMem_NEW(char *, argc+1);
3848 if (argvlist == NULL) {
3849 PyErr_NoMemory();
3850 goto fail_0;
3851 }
3852 for (i = 0; i < argc; i++) {
3853 if (!fsconvert_strdup((*getitem)(argv, i),
3854 &argvlist[i]))
3855 {
3856 lastarg = i;
3857 goto fail_1;
3858 }
3859 }
3860 lastarg = argc;
3861 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003862
Victor Stinner8c62be82010-05-06 00:08:46 +00003863 envlist = parse_envlist(env, &envc);
3864 if (envlist == NULL)
3865 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003866
Victor Stinner8c62be82010-05-06 00:08:46 +00003867 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003868#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003869 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003870#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003871 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003872#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003873 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003874
Victor Stinner8c62be82010-05-06 00:08:46 +00003875 if (spawnval == -1)
3876 (void) posix_error();
3877 else
3878 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003879
Victor Stinner8c62be82010-05-06 00:08:46 +00003880 while (--envc >= 0)
3881 PyMem_DEL(envlist[envc]);
3882 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003883 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003884 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003885 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003886 Py_DECREF(opath);
3887 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003888}
3889#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003890#endif /* HAVE_SPAWNV */
3891
3892
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003893#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003894PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003895"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003896Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3897\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003898Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003899
3900static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003901posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003902{
Victor Stinner8c62be82010-05-06 00:08:46 +00003903 pid_t pid;
3904 int result = 0;
3905 _PyImport_AcquireLock();
3906 pid = fork1();
3907 if (pid == 0) {
3908 /* child: this clobbers and resets the import lock. */
3909 PyOS_AfterFork();
3910 } else {
3911 /* parent: release the import lock. */
3912 result = _PyImport_ReleaseLock();
3913 }
3914 if (pid == -1)
3915 return posix_error();
3916 if (result < 0) {
3917 /* Don't clobber the OSError if the fork failed. */
3918 PyErr_SetString(PyExc_RuntimeError,
3919 "not holding the import lock");
3920 return NULL;
3921 }
3922 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003923}
3924#endif
3925
3926
Guido van Rossumad0ee831995-03-01 10:34:45 +00003927#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003928PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003929"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003930Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003931Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003932
Barry Warsaw53699e91996-12-10 23:23:01 +00003933static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003934posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003935{
Victor Stinner8c62be82010-05-06 00:08:46 +00003936 pid_t pid;
3937 int result = 0;
3938 _PyImport_AcquireLock();
3939 pid = fork();
3940 if (pid == 0) {
3941 /* child: this clobbers and resets the import lock. */
3942 PyOS_AfterFork();
3943 } else {
3944 /* parent: release the import lock. */
3945 result = _PyImport_ReleaseLock();
3946 }
3947 if (pid == -1)
3948 return posix_error();
3949 if (result < 0) {
3950 /* Don't clobber the OSError if the fork failed. */
3951 PyErr_SetString(PyExc_RuntimeError,
3952 "not holding the import lock");
3953 return NULL;
3954 }
3955 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003956}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003957#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003958
Neal Norwitzb59798b2003-03-21 01:43:31 +00003959/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003960/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3961#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003962#define DEV_PTY_FILE "/dev/ptc"
3963#define HAVE_DEV_PTMX
3964#else
3965#define DEV_PTY_FILE "/dev/ptmx"
3966#endif
3967
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003968#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003969#ifdef HAVE_PTY_H
3970#include <pty.h>
3971#else
3972#ifdef HAVE_LIBUTIL_H
3973#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00003974#else
3975#ifdef HAVE_UTIL_H
3976#include <util.h>
3977#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003978#endif /* HAVE_LIBUTIL_H */
3979#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003980#ifdef HAVE_STROPTS_H
3981#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003982#endif
3983#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003984
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003985#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003986PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003987"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003988Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003989
3990static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003991posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003992{
Victor Stinner8c62be82010-05-06 00:08:46 +00003993 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003994#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00003995 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003996#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003997#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003998 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003999#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00004000 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004001#endif
4002#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00004003
Thomas Wouters70c21a12000-07-14 14:28:33 +00004004#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004005 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
4006 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004007#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004008 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
4009 if (slave_name == NULL)
4010 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00004011
Victor Stinner8c62be82010-05-06 00:08:46 +00004012 slave_fd = open(slave_name, O_RDWR);
4013 if (slave_fd < 0)
4014 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004015#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004016 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
4017 if (master_fd < 0)
4018 return posix_error();
4019 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
4020 /* change permission of slave */
4021 if (grantpt(master_fd) < 0) {
4022 PyOS_setsig(SIGCHLD, sig_saved);
4023 return posix_error();
4024 }
4025 /* unlock slave */
4026 if (unlockpt(master_fd) < 0) {
4027 PyOS_setsig(SIGCHLD, sig_saved);
4028 return posix_error();
4029 }
4030 PyOS_setsig(SIGCHLD, sig_saved);
4031 slave_name = ptsname(master_fd); /* get name of slave */
4032 if (slave_name == NULL)
4033 return posix_error();
4034 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
4035 if (slave_fd < 0)
4036 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004037#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004038 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
4039 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00004040#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00004041 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00004042#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004043#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00004044#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00004045
Victor Stinner8c62be82010-05-06 00:08:46 +00004046 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00004047
Fred Drake8cef4cf2000-06-28 16:40:38 +00004048}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004049#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004050
4051#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004052PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004053"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00004054Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
4055Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004056To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004057
4058static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004059posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004060{
Victor Stinner8c62be82010-05-06 00:08:46 +00004061 int master_fd = -1, result = 0;
4062 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00004063
Victor Stinner8c62be82010-05-06 00:08:46 +00004064 _PyImport_AcquireLock();
4065 pid = forkpty(&master_fd, NULL, NULL, NULL);
4066 if (pid == 0) {
4067 /* child: this clobbers and resets the import lock. */
4068 PyOS_AfterFork();
4069 } else {
4070 /* parent: release the import lock. */
4071 result = _PyImport_ReleaseLock();
4072 }
4073 if (pid == -1)
4074 return posix_error();
4075 if (result < 0) {
4076 /* Don't clobber the OSError if the fork failed. */
4077 PyErr_SetString(PyExc_RuntimeError,
4078 "not holding the import lock");
4079 return NULL;
4080 }
4081 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004082}
4083#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004084
Guido van Rossumad0ee831995-03-01 10:34:45 +00004085#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004086PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004087"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004088Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004089
Barry Warsaw53699e91996-12-10 23:23:01 +00004090static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004091posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004092{
Victor Stinner8c62be82010-05-06 00:08:46 +00004093 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004094}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004095#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004096
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004097
Guido van Rossumad0ee831995-03-01 10:34:45 +00004098#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004099PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004100"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004101Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004102
Barry Warsaw53699e91996-12-10 23:23:01 +00004103static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004104posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004105{
Victor Stinner8c62be82010-05-06 00:08:46 +00004106 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004107}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004108#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004109
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004110
Guido van Rossumad0ee831995-03-01 10:34:45 +00004111#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004112PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004113"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004114Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004115
Barry Warsaw53699e91996-12-10 23:23:01 +00004116static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004117posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004118{
Victor Stinner8c62be82010-05-06 00:08:46 +00004119 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004120}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004121#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004122
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004123
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004124PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004125"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004126Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004127
Barry Warsaw53699e91996-12-10 23:23:01 +00004128static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004129posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004130{
Victor Stinner8c62be82010-05-06 00:08:46 +00004131 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004132}
4133
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004134
Fred Drakec9680921999-12-13 16:37:25 +00004135#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004136PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004137"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004138Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004139
4140static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004141posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004142{
4143 PyObject *result = NULL;
4144
Fred Drakec9680921999-12-13 16:37:25 +00004145#ifdef NGROUPS_MAX
4146#define MAX_GROUPS NGROUPS_MAX
4147#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004148 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004149#define MAX_GROUPS 64
4150#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004151 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004152
4153 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
4154 * This is a helper variable to store the intermediate result when
4155 * that happens.
4156 *
4157 * To keep the code readable the OSX behaviour is unconditional,
4158 * according to the POSIX spec this should be safe on all unix-y
4159 * systems.
4160 */
4161 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00004162 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004163
Victor Stinner8c62be82010-05-06 00:08:46 +00004164 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004165 if (n < 0) {
4166 if (errno == EINVAL) {
4167 n = getgroups(0, NULL);
4168 if (n == -1) {
4169 return posix_error();
4170 }
4171 if (n == 0) {
4172 /* Avoid malloc(0) */
4173 alt_grouplist = grouplist;
4174 } else {
4175 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4176 if (alt_grouplist == NULL) {
4177 errno = EINVAL;
4178 return posix_error();
4179 }
4180 n = getgroups(n, alt_grouplist);
4181 if (n == -1) {
4182 PyMem_Free(alt_grouplist);
4183 return posix_error();
4184 }
4185 }
4186 } else {
4187 return posix_error();
4188 }
4189 }
4190 result = PyList_New(n);
4191 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004192 int i;
4193 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004194 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00004195 if (o == NULL) {
4196 Py_DECREF(result);
4197 result = NULL;
4198 break;
Fred Drakec9680921999-12-13 16:37:25 +00004199 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004200 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004201 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004202 }
4203
4204 if (alt_grouplist != grouplist) {
4205 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00004206 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004207
Fred Drakec9680921999-12-13 16:37:25 +00004208 return result;
4209}
4210#endif
4211
Antoine Pitroub7572f02009-12-02 20:46:48 +00004212#ifdef HAVE_INITGROUPS
4213PyDoc_STRVAR(posix_initgroups__doc__,
4214"initgroups(username, gid) -> None\n\n\
4215Call the system initgroups() to initialize the group access list with all of\n\
4216the groups of which the specified username is a member, plus the specified\n\
4217group id.");
4218
4219static PyObject *
4220posix_initgroups(PyObject *self, PyObject *args)
4221{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004222 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00004223 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004224 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00004225 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004226
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004227 if (!PyArg_ParseTuple(args, "O&l:initgroups",
4228 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00004229 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004230 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004231
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004232 res = initgroups(username, (gid_t) gid);
4233 Py_DECREF(oname);
4234 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00004235 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004236
Victor Stinner8c62be82010-05-06 00:08:46 +00004237 Py_INCREF(Py_None);
4238 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004239}
4240#endif
4241
Martin v. Löwis606edc12002-06-13 21:09:11 +00004242#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004243PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004244"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004245Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004246
4247static PyObject *
4248posix_getpgid(PyObject *self, PyObject *args)
4249{
Victor Stinner8c62be82010-05-06 00:08:46 +00004250 pid_t pid, pgid;
4251 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
4252 return NULL;
4253 pgid = getpgid(pid);
4254 if (pgid < 0)
4255 return posix_error();
4256 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004257}
4258#endif /* HAVE_GETPGID */
4259
4260
Guido van Rossumb6775db1994-08-01 11:34:53 +00004261#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004262PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004263"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004264Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004265
Barry Warsaw53699e91996-12-10 23:23:01 +00004266static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004267posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004268{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004269#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004270 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004271#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004272 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004273#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004274}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004275#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004276
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004277
Guido van Rossumb6775db1994-08-01 11:34:53 +00004278#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004279PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004280"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00004281Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004282
Barry Warsaw53699e91996-12-10 23:23:01 +00004283static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004284posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004285{
Guido van Rossum64933891994-10-20 21:56:42 +00004286#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004287 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004288#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004289 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004290#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004291 return posix_error();
4292 Py_INCREF(Py_None);
4293 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004294}
4295
Guido van Rossumb6775db1994-08-01 11:34:53 +00004296#endif /* HAVE_SETPGRP */
4297
Guido van Rossumad0ee831995-03-01 10:34:45 +00004298#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004299
4300#ifdef MS_WINDOWS
4301#include <tlhelp32.h>
4302
4303static PyObject*
4304win32_getppid()
4305{
4306 HANDLE snapshot;
4307 pid_t mypid;
4308 PyObject* result = NULL;
4309 BOOL have_record;
4310 PROCESSENTRY32 pe;
4311
4312 mypid = getpid(); /* This function never fails */
4313
4314 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
4315 if (snapshot == INVALID_HANDLE_VALUE)
4316 return PyErr_SetFromWindowsErr(GetLastError());
4317
4318 pe.dwSize = sizeof(pe);
4319 have_record = Process32First(snapshot, &pe);
4320 while (have_record) {
4321 if (mypid == (pid_t)pe.th32ProcessID) {
4322 /* We could cache the ulong value in a static variable. */
4323 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
4324 break;
4325 }
4326
4327 have_record = Process32Next(snapshot, &pe);
4328 }
4329
4330 /* If our loop exits and our pid was not found (result will be NULL)
4331 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
4332 * error anyway, so let's raise it. */
4333 if (!result)
4334 result = PyErr_SetFromWindowsErr(GetLastError());
4335
4336 CloseHandle(snapshot);
4337
4338 return result;
4339}
4340#endif /*MS_WINDOWS*/
4341
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004342PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004343"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004344Return the parent's process id. If the parent process has already exited,\n\
4345Windows machines will still return its id; others systems will return the id\n\
4346of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004347
Barry Warsaw53699e91996-12-10 23:23:01 +00004348static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004349posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004350{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004351#ifdef MS_WINDOWS
4352 return win32_getppid();
4353#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004354 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00004355#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004356}
4357#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004358
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004359
Fred Drake12c6e2d1999-12-14 21:25:03 +00004360#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004361PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004362"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004363Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004364
4365static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004366posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004367{
Victor Stinner8c62be82010-05-06 00:08:46 +00004368 PyObject *result = NULL;
4369 char *name;
4370 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004371
Victor Stinner8c62be82010-05-06 00:08:46 +00004372 errno = 0;
4373 name = getlogin();
4374 if (name == NULL) {
4375 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00004376 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004377 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004378 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00004379 }
4380 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004381 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00004382 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004383
Fred Drake12c6e2d1999-12-14 21:25:03 +00004384 return result;
4385}
4386#endif
4387
Guido van Rossumad0ee831995-03-01 10:34:45 +00004388#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004389PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004390"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004391Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004392
Barry Warsaw53699e91996-12-10 23:23:01 +00004393static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004394posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004395{
Victor Stinner8c62be82010-05-06 00:08:46 +00004396 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004397}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004398#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004399
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004400
Guido van Rossumad0ee831995-03-01 10:34:45 +00004401#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004402PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004403"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004404Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004405
Barry Warsaw53699e91996-12-10 23:23:01 +00004406static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004407posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004408{
Victor Stinner8c62be82010-05-06 00:08:46 +00004409 pid_t pid;
4410 int sig;
4411 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
4412 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004413#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004414 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4415 APIRET rc;
4416 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004417 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004418
4419 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4420 APIRET rc;
4421 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004422 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004423
4424 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004425 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004426#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004427 if (kill(pid, sig) == -1)
4428 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004429#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004430 Py_INCREF(Py_None);
4431 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004432}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004433#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004434
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004435#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004436PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004437"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004438Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004439
4440static PyObject *
4441posix_killpg(PyObject *self, PyObject *args)
4442{
Victor Stinner8c62be82010-05-06 00:08:46 +00004443 int sig;
4444 pid_t pgid;
4445 /* XXX some man pages make the `pgid` parameter an int, others
4446 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4447 take the same type. Moreover, pid_t is always at least as wide as
4448 int (else compilation of this module fails), which is safe. */
4449 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
4450 return NULL;
4451 if (killpg(pgid, sig) == -1)
4452 return posix_error();
4453 Py_INCREF(Py_None);
4454 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004455}
4456#endif
4457
Brian Curtineb24d742010-04-12 17:16:38 +00004458#ifdef MS_WINDOWS
4459PyDoc_STRVAR(win32_kill__doc__,
4460"kill(pid, sig)\n\n\
4461Kill a process with a signal.");
4462
4463static PyObject *
4464win32_kill(PyObject *self, PyObject *args)
4465{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00004466 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004467 DWORD pid, sig, err;
4468 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00004469
Victor Stinner8c62be82010-05-06 00:08:46 +00004470 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4471 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00004472
Victor Stinner8c62be82010-05-06 00:08:46 +00004473 /* Console processes which share a common console can be sent CTRL+C or
4474 CTRL+BREAK events, provided they handle said events. */
4475 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4476 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4477 err = GetLastError();
4478 PyErr_SetFromWindowsErr(err);
4479 }
4480 else
4481 Py_RETURN_NONE;
4482 }
Brian Curtineb24d742010-04-12 17:16:38 +00004483
Victor Stinner8c62be82010-05-06 00:08:46 +00004484 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4485 attempt to open and terminate the process. */
4486 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4487 if (handle == NULL) {
4488 err = GetLastError();
4489 return PyErr_SetFromWindowsErr(err);
4490 }
Brian Curtineb24d742010-04-12 17:16:38 +00004491
Victor Stinner8c62be82010-05-06 00:08:46 +00004492 if (TerminateProcess(handle, sig) == 0) {
4493 err = GetLastError();
4494 result = PyErr_SetFromWindowsErr(err);
4495 } else {
4496 Py_INCREF(Py_None);
4497 result = Py_None;
4498 }
Brian Curtineb24d742010-04-12 17:16:38 +00004499
Victor Stinner8c62be82010-05-06 00:08:46 +00004500 CloseHandle(handle);
4501 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00004502}
4503#endif /* MS_WINDOWS */
4504
Guido van Rossumc0125471996-06-28 18:55:32 +00004505#ifdef HAVE_PLOCK
4506
4507#ifdef HAVE_SYS_LOCK_H
4508#include <sys/lock.h>
4509#endif
4510
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004511PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004512"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004513Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004514
Barry Warsaw53699e91996-12-10 23:23:01 +00004515static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004516posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004517{
Victor Stinner8c62be82010-05-06 00:08:46 +00004518 int op;
4519 if (!PyArg_ParseTuple(args, "i:plock", &op))
4520 return NULL;
4521 if (plock(op) == -1)
4522 return posix_error();
4523 Py_INCREF(Py_None);
4524 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004525}
4526#endif
4527
Guido van Rossumb6775db1994-08-01 11:34:53 +00004528#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004529PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004530"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004531Set the current process's user id.");
4532
Barry Warsaw53699e91996-12-10 23:23:01 +00004533static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004534posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004535{
Victor Stinner8c62be82010-05-06 00:08:46 +00004536 long uid_arg;
4537 uid_t uid;
4538 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
4539 return NULL;
4540 uid = uid_arg;
4541 if (uid != uid_arg) {
4542 PyErr_SetString(PyExc_OverflowError, "user id too big");
4543 return NULL;
4544 }
4545 if (setuid(uid) < 0)
4546 return posix_error();
4547 Py_INCREF(Py_None);
4548 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004549}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004550#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004551
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004552
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004553#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004554PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004555"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004556Set the current process's effective user id.");
4557
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004558static PyObject *
4559posix_seteuid (PyObject *self, PyObject *args)
4560{
Victor Stinner8c62be82010-05-06 00:08:46 +00004561 long euid_arg;
4562 uid_t euid;
4563 if (!PyArg_ParseTuple(args, "l", &euid_arg))
4564 return NULL;
4565 euid = euid_arg;
4566 if (euid != euid_arg) {
4567 PyErr_SetString(PyExc_OverflowError, "user id too big");
4568 return NULL;
4569 }
4570 if (seteuid(euid) < 0) {
4571 return posix_error();
4572 } else {
4573 Py_INCREF(Py_None);
4574 return Py_None;
4575 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004576}
4577#endif /* HAVE_SETEUID */
4578
4579#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004580PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004581"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004582Set the current process's effective group id.");
4583
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004584static PyObject *
4585posix_setegid (PyObject *self, PyObject *args)
4586{
Victor Stinner8c62be82010-05-06 00:08:46 +00004587 long egid_arg;
4588 gid_t egid;
4589 if (!PyArg_ParseTuple(args, "l", &egid_arg))
4590 return NULL;
4591 egid = egid_arg;
4592 if (egid != egid_arg) {
4593 PyErr_SetString(PyExc_OverflowError, "group id too big");
4594 return NULL;
4595 }
4596 if (setegid(egid) < 0) {
4597 return posix_error();
4598 } else {
4599 Py_INCREF(Py_None);
4600 return Py_None;
4601 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004602}
4603#endif /* HAVE_SETEGID */
4604
4605#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004606PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004607"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004608Set the current process's real and effective user ids.");
4609
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004610static PyObject *
4611posix_setreuid (PyObject *self, PyObject *args)
4612{
Victor Stinner8c62be82010-05-06 00:08:46 +00004613 long ruid_arg, euid_arg;
4614 uid_t ruid, euid;
4615 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
4616 return NULL;
4617 if (ruid_arg == -1)
4618 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
4619 else
4620 ruid = ruid_arg; /* otherwise, assign from our long */
4621 if (euid_arg == -1)
4622 euid = (uid_t)-1;
4623 else
4624 euid = euid_arg;
4625 if ((euid_arg != -1 && euid != euid_arg) ||
4626 (ruid_arg != -1 && ruid != ruid_arg)) {
4627 PyErr_SetString(PyExc_OverflowError, "user id too big");
4628 return NULL;
4629 }
4630 if (setreuid(ruid, euid) < 0) {
4631 return posix_error();
4632 } else {
4633 Py_INCREF(Py_None);
4634 return Py_None;
4635 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004636}
4637#endif /* HAVE_SETREUID */
4638
4639#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004640PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004641"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004642Set the current process's real and effective group ids.");
4643
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004644static PyObject *
4645posix_setregid (PyObject *self, PyObject *args)
4646{
Victor Stinner8c62be82010-05-06 00:08:46 +00004647 long rgid_arg, egid_arg;
4648 gid_t rgid, egid;
4649 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
4650 return NULL;
4651 if (rgid_arg == -1)
4652 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
4653 else
4654 rgid = rgid_arg; /* otherwise, assign from our long */
4655 if (egid_arg == -1)
4656 egid = (gid_t)-1;
4657 else
4658 egid = egid_arg;
4659 if ((egid_arg != -1 && egid != egid_arg) ||
4660 (rgid_arg != -1 && rgid != rgid_arg)) {
4661 PyErr_SetString(PyExc_OverflowError, "group id too big");
4662 return NULL;
4663 }
4664 if (setregid(rgid, egid) < 0) {
4665 return posix_error();
4666 } else {
4667 Py_INCREF(Py_None);
4668 return Py_None;
4669 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004670}
4671#endif /* HAVE_SETREGID */
4672
Guido van Rossumb6775db1994-08-01 11:34:53 +00004673#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004674PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004675"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004676Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004677
Barry Warsaw53699e91996-12-10 23:23:01 +00004678static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004679posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004680{
Victor Stinner8c62be82010-05-06 00:08:46 +00004681 long gid_arg;
4682 gid_t gid;
4683 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
4684 return NULL;
4685 gid = gid_arg;
4686 if (gid != gid_arg) {
4687 PyErr_SetString(PyExc_OverflowError, "group id too big");
4688 return NULL;
4689 }
4690 if (setgid(gid) < 0)
4691 return posix_error();
4692 Py_INCREF(Py_None);
4693 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004694}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004695#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004696
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004697#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004698PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004699"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004700Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004701
4702static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004703posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004704{
Victor Stinner8c62be82010-05-06 00:08:46 +00004705 int i, len;
4706 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004707
Victor Stinner8c62be82010-05-06 00:08:46 +00004708 if (!PySequence_Check(groups)) {
4709 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4710 return NULL;
4711 }
4712 len = PySequence_Size(groups);
4713 if (len > MAX_GROUPS) {
4714 PyErr_SetString(PyExc_ValueError, "too many groups");
4715 return NULL;
4716 }
4717 for(i = 0; i < len; i++) {
4718 PyObject *elem;
4719 elem = PySequence_GetItem(groups, i);
4720 if (!elem)
4721 return NULL;
4722 if (!PyLong_Check(elem)) {
4723 PyErr_SetString(PyExc_TypeError,
4724 "groups must be integers");
4725 Py_DECREF(elem);
4726 return NULL;
4727 } else {
4728 unsigned long x = PyLong_AsUnsignedLong(elem);
4729 if (PyErr_Occurred()) {
4730 PyErr_SetString(PyExc_TypeError,
4731 "group id too big");
4732 Py_DECREF(elem);
4733 return NULL;
4734 }
4735 grouplist[i] = x;
4736 /* read back the value to see if it fitted in gid_t */
4737 if (grouplist[i] != x) {
4738 PyErr_SetString(PyExc_TypeError,
4739 "group id too big");
4740 Py_DECREF(elem);
4741 return NULL;
4742 }
4743 }
4744 Py_DECREF(elem);
4745 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004746
Victor Stinner8c62be82010-05-06 00:08:46 +00004747 if (setgroups(len, grouplist) < 0)
4748 return posix_error();
4749 Py_INCREF(Py_None);
4750 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004751}
4752#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004753
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004754#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4755static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004756wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004757{
Victor Stinner8c62be82010-05-06 00:08:46 +00004758 PyObject *result;
4759 static PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004760
Victor Stinner8c62be82010-05-06 00:08:46 +00004761 if (pid == -1)
4762 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004763
Victor Stinner8c62be82010-05-06 00:08:46 +00004764 if (struct_rusage == NULL) {
4765 PyObject *m = PyImport_ImportModuleNoBlock("resource");
4766 if (m == NULL)
4767 return NULL;
4768 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4769 Py_DECREF(m);
4770 if (struct_rusage == NULL)
4771 return NULL;
4772 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004773
Victor Stinner8c62be82010-05-06 00:08:46 +00004774 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4775 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4776 if (!result)
4777 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004778
4779#ifndef doubletime
4780#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4781#endif
4782
Victor Stinner8c62be82010-05-06 00:08:46 +00004783 PyStructSequence_SET_ITEM(result, 0,
4784 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4785 PyStructSequence_SET_ITEM(result, 1,
4786 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004787#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00004788 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
4789 SET_INT(result, 2, ru->ru_maxrss);
4790 SET_INT(result, 3, ru->ru_ixrss);
4791 SET_INT(result, 4, ru->ru_idrss);
4792 SET_INT(result, 5, ru->ru_isrss);
4793 SET_INT(result, 6, ru->ru_minflt);
4794 SET_INT(result, 7, ru->ru_majflt);
4795 SET_INT(result, 8, ru->ru_nswap);
4796 SET_INT(result, 9, ru->ru_inblock);
4797 SET_INT(result, 10, ru->ru_oublock);
4798 SET_INT(result, 11, ru->ru_msgsnd);
4799 SET_INT(result, 12, ru->ru_msgrcv);
4800 SET_INT(result, 13, ru->ru_nsignals);
4801 SET_INT(result, 14, ru->ru_nvcsw);
4802 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004803#undef SET_INT
4804
Victor Stinner8c62be82010-05-06 00:08:46 +00004805 if (PyErr_Occurred()) {
4806 Py_DECREF(result);
4807 return NULL;
4808 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004809
Victor Stinner8c62be82010-05-06 00:08:46 +00004810 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004811}
4812#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4813
4814#ifdef HAVE_WAIT3
4815PyDoc_STRVAR(posix_wait3__doc__,
4816"wait3(options) -> (pid, status, rusage)\n\n\
4817Wait for completion of a child process.");
4818
4819static PyObject *
4820posix_wait3(PyObject *self, PyObject *args)
4821{
Victor Stinner8c62be82010-05-06 00:08:46 +00004822 pid_t pid;
4823 int options;
4824 struct rusage ru;
4825 WAIT_TYPE status;
4826 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004827
Victor Stinner8c62be82010-05-06 00:08:46 +00004828 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4829 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004830
Victor Stinner8c62be82010-05-06 00:08:46 +00004831 Py_BEGIN_ALLOW_THREADS
4832 pid = wait3(&status, options, &ru);
4833 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004834
Victor Stinner8c62be82010-05-06 00:08:46 +00004835 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004836}
4837#endif /* HAVE_WAIT3 */
4838
4839#ifdef HAVE_WAIT4
4840PyDoc_STRVAR(posix_wait4__doc__,
4841"wait4(pid, options) -> (pid, status, rusage)\n\n\
4842Wait for completion of a given child process.");
4843
4844static PyObject *
4845posix_wait4(PyObject *self, PyObject *args)
4846{
Victor Stinner8c62be82010-05-06 00:08:46 +00004847 pid_t pid;
4848 int options;
4849 struct rusage ru;
4850 WAIT_TYPE status;
4851 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004852
Victor Stinner8c62be82010-05-06 00:08:46 +00004853 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
4854 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004855
Victor Stinner8c62be82010-05-06 00:08:46 +00004856 Py_BEGIN_ALLOW_THREADS
4857 pid = wait4(pid, &status, options, &ru);
4858 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004859
Victor Stinner8c62be82010-05-06 00:08:46 +00004860 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004861}
4862#endif /* HAVE_WAIT4 */
4863
Guido van Rossumb6775db1994-08-01 11:34:53 +00004864#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004865PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004866"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004867Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004868
Barry Warsaw53699e91996-12-10 23:23:01 +00004869static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004870posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004871{
Victor Stinner8c62be82010-05-06 00:08:46 +00004872 pid_t pid;
4873 int options;
4874 WAIT_TYPE status;
4875 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004876
Victor Stinner8c62be82010-05-06 00:08:46 +00004877 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4878 return NULL;
4879 Py_BEGIN_ALLOW_THREADS
4880 pid = waitpid(pid, &status, options);
4881 Py_END_ALLOW_THREADS
4882 if (pid == -1)
4883 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004884
Victor Stinner8c62be82010-05-06 00:08:46 +00004885 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004886}
4887
Tim Petersab034fa2002-02-01 11:27:43 +00004888#elif defined(HAVE_CWAIT)
4889
4890/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004891PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004892"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004893"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004894
4895static PyObject *
4896posix_waitpid(PyObject *self, PyObject *args)
4897{
Victor Stinner8c62be82010-05-06 00:08:46 +00004898 Py_intptr_t pid;
4899 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004900
Victor Stinner8c62be82010-05-06 00:08:46 +00004901 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4902 return NULL;
4903 Py_BEGIN_ALLOW_THREADS
4904 pid = _cwait(&status, pid, options);
4905 Py_END_ALLOW_THREADS
4906 if (pid == -1)
4907 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004908
Victor Stinner8c62be82010-05-06 00:08:46 +00004909 /* shift the status left a byte so this is more like the POSIX waitpid */
4910 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004911}
4912#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004913
Guido van Rossumad0ee831995-03-01 10:34:45 +00004914#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004915PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004916"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004917Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004918
Barry Warsaw53699e91996-12-10 23:23:01 +00004919static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004920posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004921{
Victor Stinner8c62be82010-05-06 00:08:46 +00004922 pid_t pid;
4923 WAIT_TYPE status;
4924 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004925
Victor Stinner8c62be82010-05-06 00:08:46 +00004926 Py_BEGIN_ALLOW_THREADS
4927 pid = wait(&status);
4928 Py_END_ALLOW_THREADS
4929 if (pid == -1)
4930 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004931
Victor Stinner8c62be82010-05-06 00:08:46 +00004932 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00004933}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004934#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004935
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004936
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004937PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004938"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004939Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004940
Barry Warsaw53699e91996-12-10 23:23:01 +00004941static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004942posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004943{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004944#ifdef HAVE_LSTAT
Victor Stinner8c62be82010-05-06 00:08:46 +00004945 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004946#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004947#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00004948 return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat",
4949 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004950#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004951 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004952#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004953#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004954}
4955
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004956
Guido van Rossumb6775db1994-08-01 11:34:53 +00004957#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004958PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004959"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004960Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004961
Barry Warsaw53699e91996-12-10 23:23:01 +00004962static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004963posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004964{
Victor Stinner8c62be82010-05-06 00:08:46 +00004965 PyObject* v;
4966 char buf[MAXPATHLEN];
4967 PyObject *opath;
4968 char *path;
4969 int n;
4970 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004971
Victor Stinner8c62be82010-05-06 00:08:46 +00004972 if (!PyArg_ParseTuple(args, "O&:readlink",
4973 PyUnicode_FSConverter, &opath))
4974 return NULL;
4975 path = PyBytes_AsString(opath);
4976 v = PySequence_GetItem(args, 0);
4977 if (v == NULL) {
4978 Py_DECREF(opath);
4979 return NULL;
4980 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004981
Victor Stinner8c62be82010-05-06 00:08:46 +00004982 if (PyUnicode_Check(v)) {
4983 arg_is_unicode = 1;
4984 }
4985 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004986
Victor Stinner8c62be82010-05-06 00:08:46 +00004987 Py_BEGIN_ALLOW_THREADS
4988 n = readlink(path, buf, (int) sizeof buf);
4989 Py_END_ALLOW_THREADS
4990 if (n < 0)
4991 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004992
Victor Stinner8c62be82010-05-06 00:08:46 +00004993 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00004994 if (arg_is_unicode)
4995 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
4996 else
4997 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004998}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004999#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005000
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005001
Guido van Rossumb6775db1994-08-01 11:34:53 +00005002#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005003PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005004"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005005Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005006
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005007static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005008posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005009{
Victor Stinner8c62be82010-05-06 00:08:46 +00005010 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005011}
5012#endif /* HAVE_SYMLINK */
5013
Brian Curtind40e6f72010-07-08 21:39:08 +00005014#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
5015
5016PyDoc_STRVAR(win_readlink__doc__,
5017"readlink(path) -> path\n\n\
5018Return a string representing the path to which the symbolic link points.");
5019
5020/* The following structure was copied from
5021 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
5022 include doesn't seem to be present in the Windows SDK (at least as included
5023 with Visual Studio Express). */
5024typedef struct _REPARSE_DATA_BUFFER {
5025 ULONG ReparseTag;
5026 USHORT ReparseDataLength;
5027 USHORT Reserved;
5028 union {
5029 struct {
5030 USHORT SubstituteNameOffset;
5031 USHORT SubstituteNameLength;
5032 USHORT PrintNameOffset;
5033 USHORT PrintNameLength;
5034 ULONG Flags;
5035 WCHAR PathBuffer[1];
5036 } SymbolicLinkReparseBuffer;
5037
5038 struct {
5039 USHORT SubstituteNameOffset;
5040 USHORT SubstituteNameLength;
5041 USHORT PrintNameOffset;
5042 USHORT PrintNameLength;
5043 WCHAR PathBuffer[1];
5044 } MountPointReparseBuffer;
5045
5046 struct {
5047 UCHAR DataBuffer[1];
5048 } GenericReparseBuffer;
5049 };
5050} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
5051
Brian Curtin74e45612010-07-09 15:58:59 +00005052#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
5053 GenericReparseBuffer)
Brian Curtind40e6f72010-07-08 21:39:08 +00005054
5055#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
5056
5057/* Windows readlink implementation */
5058static PyObject *
5059win_readlink(PyObject *self, PyObject *args)
5060{
5061 wchar_t *path;
5062 DWORD n_bytes_returned;
5063 DWORD io_result;
5064 PyObject *result;
5065 HANDLE reparse_point_handle;
5066
5067 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
5068 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
5069 wchar_t *print_name;
5070
5071 if (!PyArg_ParseTuple(args,
5072 "u:readlink",
5073 &path))
5074 return NULL;
5075
5076 /* First get a handle to the reparse point */
5077 Py_BEGIN_ALLOW_THREADS
5078 reparse_point_handle = CreateFileW(
5079 path,
5080 0,
5081 0,
5082 0,
5083 OPEN_EXISTING,
5084 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
5085 0);
5086 Py_END_ALLOW_THREADS
5087
5088 if (reparse_point_handle==INVALID_HANDLE_VALUE)
5089 {
5090 return win32_error_unicode("readlink", path);
5091 }
5092
5093 Py_BEGIN_ALLOW_THREADS
5094 /* New call DeviceIoControl to read the reparse point */
5095 io_result = DeviceIoControl(
5096 reparse_point_handle,
5097 FSCTL_GET_REPARSE_POINT,
5098 0, 0, /* in buffer */
5099 target_buffer, sizeof(target_buffer),
5100 &n_bytes_returned,
5101 0 /* we're not using OVERLAPPED_IO */
5102 );
5103 CloseHandle(reparse_point_handle);
5104 Py_END_ALLOW_THREADS
5105
5106 if (io_result==0)
5107 {
5108 return win32_error_unicode("readlink", path);
5109 }
5110
5111 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
5112 {
5113 PyErr_SetString(PyExc_ValueError,
5114 "not a symbolic link");
5115 return NULL;
5116 }
Brian Curtin74e45612010-07-09 15:58:59 +00005117 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
5118 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
5119
5120 result = PyUnicode_FromWideChar(print_name,
5121 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00005122 return result;
5123}
5124
5125#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
5126
5127#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
5128
5129/* Grab CreateSymbolicLinkW dynamically from kernel32 */
5130static int has_CreateSymbolicLinkW = 0;
5131static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
5132static int
5133check_CreateSymbolicLinkW()
5134{
5135 HINSTANCE hKernel32;
5136 /* only recheck */
5137 if (has_CreateSymbolicLinkW)
5138 return has_CreateSymbolicLinkW;
5139 hKernel32 = GetModuleHandle("KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00005140 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
5141 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00005142 if (Py_CreateSymbolicLinkW)
5143 has_CreateSymbolicLinkW = 1;
5144 return has_CreateSymbolicLinkW;
5145}
5146
5147PyDoc_STRVAR(win_symlink__doc__,
5148"symlink(src, dst, target_is_directory=False)\n\n\
5149Create a symbolic link pointing to src named dst.\n\
5150target_is_directory is required if the target is to be interpreted as\n\
5151a directory.\n\
5152This function requires Windows 6.0 or greater, and raises a\n\
5153NotImplementedError otherwise.");
5154
5155static PyObject *
5156win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
5157{
5158 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
5159 PyObject *src, *dest;
5160 int target_is_directory = 0;
5161 DWORD res;
5162 WIN32_FILE_ATTRIBUTE_DATA src_info;
5163
5164 if (!check_CreateSymbolicLinkW())
5165 {
5166 /* raise NotImplementedError */
5167 return PyErr_Format(PyExc_NotImplementedError,
5168 "CreateSymbolicLinkW not found");
5169 }
5170 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:symlink",
5171 kwlist, &src, &dest, &target_is_directory))
5172 return NULL;
5173 if (!convert_to_unicode(&src)) { return NULL; }
5174 if (!convert_to_unicode(&dest)) {
5175 Py_DECREF(src);
5176 return NULL;
5177 }
5178
5179 /* if src is a directory, ensure target_is_directory==1 */
5180 if(
5181 GetFileAttributesExW(
5182 PyUnicode_AsUnicode(src), GetFileExInfoStandard, &src_info
5183 ))
5184 {
5185 target_is_directory = target_is_directory ||
5186 (src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
5187 }
5188
5189 Py_BEGIN_ALLOW_THREADS
5190 res = Py_CreateSymbolicLinkW(
5191 PyUnicode_AsUnicode(dest),
5192 PyUnicode_AsUnicode(src),
5193 target_is_directory);
5194 Py_END_ALLOW_THREADS
5195 Py_DECREF(src);
5196 Py_DECREF(dest);
5197 if (!res)
5198 {
5199 return win32_error_unicode("symlink", PyUnicode_AsUnicode(src));
5200 }
5201
5202 Py_INCREF(Py_None);
5203 return Py_None;
5204}
5205#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005206
5207#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00005208#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5209static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005210system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005211{
5212 ULONG value = 0;
5213
5214 Py_BEGIN_ALLOW_THREADS
5215 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5216 Py_END_ALLOW_THREADS
5217
5218 return value;
5219}
5220
5221static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005222posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005223{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005224 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00005225 return Py_BuildValue("ddddd",
5226 (double)0 /* t.tms_utime / HZ */,
5227 (double)0 /* t.tms_stime / HZ */,
5228 (double)0 /* t.tms_cutime / HZ */,
5229 (double)0 /* t.tms_cstime / HZ */,
5230 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005231}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005232#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00005233#define NEED_TICKS_PER_SECOND
5234static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00005235static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005236posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005237{
Victor Stinner8c62be82010-05-06 00:08:46 +00005238 struct tms t;
5239 clock_t c;
5240 errno = 0;
5241 c = times(&t);
5242 if (c == (clock_t) -1)
5243 return posix_error();
5244 return Py_BuildValue("ddddd",
5245 (double)t.tms_utime / ticks_per_second,
5246 (double)t.tms_stime / ticks_per_second,
5247 (double)t.tms_cutime / ticks_per_second,
5248 (double)t.tms_cstime / ticks_per_second,
5249 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005250}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005251#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005252#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005253
5254
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005255#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005256#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005257static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005258posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005259{
Victor Stinner8c62be82010-05-06 00:08:46 +00005260 FILETIME create, exit, kernel, user;
5261 HANDLE hProc;
5262 hProc = GetCurrentProcess();
5263 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5264 /* The fields of a FILETIME structure are the hi and lo part
5265 of a 64-bit value expressed in 100 nanosecond units.
5266 1e7 is one second in such units; 1e-7 the inverse.
5267 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5268 */
5269 return Py_BuildValue(
5270 "ddddd",
5271 (double)(user.dwHighDateTime*429.4967296 +
5272 user.dwLowDateTime*1e-7),
5273 (double)(kernel.dwHighDateTime*429.4967296 +
5274 kernel.dwLowDateTime*1e-7),
5275 (double)0,
5276 (double)0,
5277 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005278}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005279#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005280
5281#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005282PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005283"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005284Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005285#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005286
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005287
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005288#ifdef HAVE_GETSID
5289PyDoc_STRVAR(posix_getsid__doc__,
5290"getsid(pid) -> sid\n\n\
5291Call the system call getsid().");
5292
5293static PyObject *
5294posix_getsid(PyObject *self, PyObject *args)
5295{
Victor Stinner8c62be82010-05-06 00:08:46 +00005296 pid_t pid;
5297 int sid;
5298 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
5299 return NULL;
5300 sid = getsid(pid);
5301 if (sid < 0)
5302 return posix_error();
5303 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005304}
5305#endif /* HAVE_GETSID */
5306
5307
Guido van Rossumb6775db1994-08-01 11:34:53 +00005308#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005309PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005310"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005311Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005312
Barry Warsaw53699e91996-12-10 23:23:01 +00005313static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005314posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005315{
Victor Stinner8c62be82010-05-06 00:08:46 +00005316 if (setsid() < 0)
5317 return posix_error();
5318 Py_INCREF(Py_None);
5319 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005320}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005321#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005322
Guido van Rossumb6775db1994-08-01 11:34:53 +00005323#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005324PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005325"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005326Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005327
Barry Warsaw53699e91996-12-10 23:23:01 +00005328static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005329posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005330{
Victor Stinner8c62be82010-05-06 00:08:46 +00005331 pid_t pid;
5332 int pgrp;
5333 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
5334 return NULL;
5335 if (setpgid(pid, pgrp) < 0)
5336 return posix_error();
5337 Py_INCREF(Py_None);
5338 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005339}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005340#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005341
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005342
Guido van Rossumb6775db1994-08-01 11:34:53 +00005343#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005344PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005345"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005346Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005347
Barry Warsaw53699e91996-12-10 23:23:01 +00005348static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005349posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005350{
Victor Stinner8c62be82010-05-06 00:08:46 +00005351 int fd;
5352 pid_t pgid;
5353 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
5354 return NULL;
5355 pgid = tcgetpgrp(fd);
5356 if (pgid < 0)
5357 return posix_error();
5358 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005359}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005360#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005361
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005362
Guido van Rossumb6775db1994-08-01 11:34:53 +00005363#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005364PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005365"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005366Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005367
Barry Warsaw53699e91996-12-10 23:23:01 +00005368static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005369posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005370{
Victor Stinner8c62be82010-05-06 00:08:46 +00005371 int fd;
5372 pid_t pgid;
5373 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
5374 return NULL;
5375 if (tcsetpgrp(fd, pgid) < 0)
5376 return posix_error();
5377 Py_INCREF(Py_None);
5378 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005379}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005380#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005381
Guido van Rossum687dd131993-05-17 08:34:16 +00005382/* Functions acting on file descriptors */
5383
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005384PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005385"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005386Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005387
Barry Warsaw53699e91996-12-10 23:23:01 +00005388static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005389posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005390{
Victor Stinner8c62be82010-05-06 00:08:46 +00005391 PyObject *ofile;
5392 char *file;
5393 int flag;
5394 int mode = 0777;
5395 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005396
5397#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005398 PyUnicodeObject *po;
5399 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5400 Py_BEGIN_ALLOW_THREADS
5401 /* PyUnicode_AS_UNICODE OK without thread
5402 lock as it is a simple dereference. */
5403 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5404 Py_END_ALLOW_THREADS
5405 if (fd < 0)
5406 return posix_error();
5407 return PyLong_FromLong((long)fd);
5408 }
5409 /* Drop the argument parsing error as narrow strings
5410 are also valid. */
5411 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005412#endif
5413
Victor Stinner8c62be82010-05-06 00:08:46 +00005414 if (!PyArg_ParseTuple(args, "O&i|i",
5415 PyUnicode_FSConverter, &ofile,
5416 &flag, &mode))
5417 return NULL;
5418 file = PyBytes_AsString(ofile);
5419 Py_BEGIN_ALLOW_THREADS
5420 fd = open(file, flag, mode);
5421 Py_END_ALLOW_THREADS
5422 if (fd < 0)
5423 return posix_error_with_allocated_filename(ofile);
5424 Py_DECREF(ofile);
5425 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005426}
5427
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005428
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005429PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005430"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005431Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005432
Barry Warsaw53699e91996-12-10 23:23:01 +00005433static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005434posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005435{
Victor Stinner8c62be82010-05-06 00:08:46 +00005436 int fd, res;
5437 if (!PyArg_ParseTuple(args, "i:close", &fd))
5438 return NULL;
5439 if (!_PyVerify_fd(fd))
5440 return posix_error();
5441 Py_BEGIN_ALLOW_THREADS
5442 res = close(fd);
5443 Py_END_ALLOW_THREADS
5444 if (res < 0)
5445 return posix_error();
5446 Py_INCREF(Py_None);
5447 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005448}
5449
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005450
Victor Stinner8c62be82010-05-06 00:08:46 +00005451PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00005452"closerange(fd_low, fd_high)\n\n\
5453Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
5454
5455static PyObject *
5456posix_closerange(PyObject *self, PyObject *args)
5457{
Victor Stinner8c62be82010-05-06 00:08:46 +00005458 int fd_from, fd_to, i;
5459 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
5460 return NULL;
5461 Py_BEGIN_ALLOW_THREADS
5462 for (i = fd_from; i < fd_to; i++)
5463 if (_PyVerify_fd(i))
5464 close(i);
5465 Py_END_ALLOW_THREADS
5466 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00005467}
5468
5469
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005470PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005471"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005472Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005473
Barry Warsaw53699e91996-12-10 23:23:01 +00005474static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005475posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005476{
Victor Stinner8c62be82010-05-06 00:08:46 +00005477 int fd;
5478 if (!PyArg_ParseTuple(args, "i:dup", &fd))
5479 return NULL;
5480 if (!_PyVerify_fd(fd))
5481 return posix_error();
5482 Py_BEGIN_ALLOW_THREADS
5483 fd = dup(fd);
5484 Py_END_ALLOW_THREADS
5485 if (fd < 0)
5486 return posix_error();
5487 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005488}
5489
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005490
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005491PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005492"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005493Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005494
Barry Warsaw53699e91996-12-10 23:23:01 +00005495static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005496posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005497{
Victor Stinner8c62be82010-05-06 00:08:46 +00005498 int fd, fd2, res;
5499 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5500 return NULL;
5501 if (!_PyVerify_fd_dup2(fd, fd2))
5502 return posix_error();
5503 Py_BEGIN_ALLOW_THREADS
5504 res = dup2(fd, fd2);
5505 Py_END_ALLOW_THREADS
5506 if (res < 0)
5507 return posix_error();
5508 Py_INCREF(Py_None);
5509 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005510}
5511
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005512
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005513PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005514"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005515Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005516
Barry Warsaw53699e91996-12-10 23:23:01 +00005517static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005518posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005519{
Victor Stinner8c62be82010-05-06 00:08:46 +00005520 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005521#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005522 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005523#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005524 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005525#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005526 PyObject *posobj;
5527 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5528 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005529#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00005530 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5531 switch (how) {
5532 case 0: how = SEEK_SET; break;
5533 case 1: how = SEEK_CUR; break;
5534 case 2: how = SEEK_END; break;
5535 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005536#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005537
5538#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005539 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005540#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005541 pos = PyLong_Check(posobj) ?
5542 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005543#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005544 if (PyErr_Occurred())
5545 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005546
Victor Stinner8c62be82010-05-06 00:08:46 +00005547 if (!_PyVerify_fd(fd))
5548 return posix_error();
5549 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005550#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005551 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005552#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005553 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005554#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005555 Py_END_ALLOW_THREADS
5556 if (res < 0)
5557 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005558
5559#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005560 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005561#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005562 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005563#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005564}
5565
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005566
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005567PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005568"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005569Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005570
Barry Warsaw53699e91996-12-10 23:23:01 +00005571static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005572posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005573{
Victor Stinner8c62be82010-05-06 00:08:46 +00005574 int fd, size;
5575 Py_ssize_t n;
5576 PyObject *buffer;
5577 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5578 return NULL;
5579 if (size < 0) {
5580 errno = EINVAL;
5581 return posix_error();
5582 }
5583 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
5584 if (buffer == NULL)
5585 return NULL;
5586 if (!_PyVerify_fd(fd))
5587 return posix_error();
5588 Py_BEGIN_ALLOW_THREADS
5589 n = read(fd, PyBytes_AS_STRING(buffer), size);
5590 Py_END_ALLOW_THREADS
5591 if (n < 0) {
5592 Py_DECREF(buffer);
5593 return posix_error();
5594 }
5595 if (n != size)
5596 _PyBytes_Resize(&buffer, n);
5597 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00005598}
5599
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005600
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005601PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005602"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005603Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005604
Barry Warsaw53699e91996-12-10 23:23:01 +00005605static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005606posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005607{
Victor Stinner8c62be82010-05-06 00:08:46 +00005608 Py_buffer pbuf;
5609 int fd;
5610 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005611
Victor Stinner8c62be82010-05-06 00:08:46 +00005612 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
5613 return NULL;
5614 if (!_PyVerify_fd(fd))
5615 return posix_error();
5616 Py_BEGIN_ALLOW_THREADS
5617 size = write(fd, pbuf.buf, (size_t)pbuf.len);
5618 Py_END_ALLOW_THREADS
5619 PyBuffer_Release(&pbuf);
5620 if (size < 0)
5621 return posix_error();
5622 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005623}
5624
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005625
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005626PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005627"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005628Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005629
Barry Warsaw53699e91996-12-10 23:23:01 +00005630static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005631posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005632{
Victor Stinner8c62be82010-05-06 00:08:46 +00005633 int fd;
5634 STRUCT_STAT st;
5635 int res;
5636 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5637 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005638#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00005639 /* on OpenVMS we must ensure that all bytes are written to the file */
5640 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005641#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005642 if (!_PyVerify_fd(fd))
5643 return posix_error();
5644 Py_BEGIN_ALLOW_THREADS
5645 res = FSTAT(fd, &st);
5646 Py_END_ALLOW_THREADS
5647 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00005648#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005649 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00005650#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005651 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005652#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005653 }
Tim Peters5aa91602002-01-30 05:46:57 +00005654
Victor Stinner8c62be82010-05-06 00:08:46 +00005655 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005656}
5657
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005658PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005659"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005660Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005661connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005662
5663static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005664posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005665{
Victor Stinner8c62be82010-05-06 00:08:46 +00005666 int fd;
5667 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5668 return NULL;
5669 if (!_PyVerify_fd(fd))
5670 return PyBool_FromLong(0);
5671 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005672}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005673
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005674#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005675PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005676"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005677Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005678
Barry Warsaw53699e91996-12-10 23:23:01 +00005679static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005680posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005681{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005682#if defined(PYOS_OS2)
5683 HFILE read, write;
5684 APIRET rc;
5685
Victor Stinner8c62be82010-05-06 00:08:46 +00005686 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005687 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinner8c62be82010-05-06 00:08:46 +00005688 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005689 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005690 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005691
5692 return Py_BuildValue("(ii)", read, write);
5693#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005694#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005695 int fds[2];
5696 int res;
5697 Py_BEGIN_ALLOW_THREADS
5698 res = pipe(fds);
5699 Py_END_ALLOW_THREADS
5700 if (res != 0)
5701 return posix_error();
5702 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005703#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00005704 HANDLE read, write;
5705 int read_fd, write_fd;
5706 BOOL ok;
5707 Py_BEGIN_ALLOW_THREADS
5708 ok = CreatePipe(&read, &write, NULL, 0);
5709 Py_END_ALLOW_THREADS
5710 if (!ok)
5711 return win32_error("CreatePipe", NULL);
5712 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5713 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5714 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005715#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005716#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005717}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005718#endif /* HAVE_PIPE */
5719
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005720
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005721#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005722PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005723"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005724Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005725
Barry Warsaw53699e91996-12-10 23:23:01 +00005726static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005727posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005728{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005729 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005730 char *filename;
5731 int mode = 0666;
5732 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005733 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
5734 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00005735 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005736 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005737 Py_BEGIN_ALLOW_THREADS
5738 res = mkfifo(filename, mode);
5739 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005740 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005741 if (res < 0)
5742 return posix_error();
5743 Py_INCREF(Py_None);
5744 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005745}
5746#endif
5747
5748
Neal Norwitz11690112002-07-30 01:08:28 +00005749#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005750PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005751"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005752Create a filesystem node (file, device special file or named pipe)\n\
5753named filename. mode specifies both the permissions to use and the\n\
5754type of node to be created, being combined (bitwise OR) with one of\n\
5755S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005756device defines the newly created device special file (probably using\n\
5757os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005758
5759
5760static PyObject *
5761posix_mknod(PyObject *self, PyObject *args)
5762{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005763 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005764 char *filename;
5765 int mode = 0600;
5766 int device = 0;
5767 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005768 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
5769 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00005770 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005771 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005772 Py_BEGIN_ALLOW_THREADS
5773 res = mknod(filename, mode, device);
5774 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005775 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005776 if (res < 0)
5777 return posix_error();
5778 Py_INCREF(Py_None);
5779 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005780}
5781#endif
5782
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005783#ifdef HAVE_DEVICE_MACROS
5784PyDoc_STRVAR(posix_major__doc__,
5785"major(device) -> major number\n\
5786Extracts a device major number from a raw device number.");
5787
5788static PyObject *
5789posix_major(PyObject *self, PyObject *args)
5790{
Victor Stinner8c62be82010-05-06 00:08:46 +00005791 int device;
5792 if (!PyArg_ParseTuple(args, "i:major", &device))
5793 return NULL;
5794 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005795}
5796
5797PyDoc_STRVAR(posix_minor__doc__,
5798"minor(device) -> minor number\n\
5799Extracts a device minor number from a raw device number.");
5800
5801static PyObject *
5802posix_minor(PyObject *self, PyObject *args)
5803{
Victor Stinner8c62be82010-05-06 00:08:46 +00005804 int device;
5805 if (!PyArg_ParseTuple(args, "i:minor", &device))
5806 return NULL;
5807 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005808}
5809
5810PyDoc_STRVAR(posix_makedev__doc__,
5811"makedev(major, minor) -> device number\n\
5812Composes a raw device number from the major and minor device numbers.");
5813
5814static PyObject *
5815posix_makedev(PyObject *self, PyObject *args)
5816{
Victor Stinner8c62be82010-05-06 00:08:46 +00005817 int major, minor;
5818 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5819 return NULL;
5820 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005821}
5822#endif /* device macros */
5823
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005824
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005825#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005826PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005827"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005828Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005829
Barry Warsaw53699e91996-12-10 23:23:01 +00005830static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005831posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005832{
Victor Stinner8c62be82010-05-06 00:08:46 +00005833 int fd;
5834 off_t length;
5835 int res;
5836 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005837
Victor Stinner8c62be82010-05-06 00:08:46 +00005838 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
5839 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005840
5841#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005842 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005843#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005844 length = PyLong_Check(lenobj) ?
5845 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005846#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005847 if (PyErr_Occurred())
5848 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005849
Victor Stinner8c62be82010-05-06 00:08:46 +00005850 Py_BEGIN_ALLOW_THREADS
5851 res = ftruncate(fd, length);
5852 Py_END_ALLOW_THREADS
5853 if (res < 0)
5854 return posix_error();
5855 Py_INCREF(Py_None);
5856 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005857}
5858#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005859
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005860#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005861PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005862"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005863Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005864
Fred Drake762e2061999-08-26 17:23:54 +00005865/* Save putenv() parameters as values here, so we can collect them when they
5866 * get re-set with another call for the same key. */
5867static PyObject *posix_putenv_garbage;
5868
Tim Peters5aa91602002-01-30 05:46:57 +00005869static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005870posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005871{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005872#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005873 wchar_t *s1, *s2;
5874 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005875#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005876 PyObject *os1, *os2;
5877 char *s1, *s2;
5878 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005879#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005880 PyObject *newstr = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005881 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005882
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005883#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005884 if (!PyArg_ParseTuple(args,
5885 "uu:putenv",
5886 &s1, &s2))
5887 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005888#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005889 if (!PyArg_ParseTuple(args,
5890 "O&O&:putenv",
5891 PyUnicode_FSConverter, &os1,
5892 PyUnicode_FSConverter, &os2))
5893 return NULL;
5894 s1 = PyBytes_AsString(os1);
5895 s2 = PyBytes_AsString(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005896#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005897
5898#if defined(PYOS_OS2)
5899 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5900 APIRET rc;
5901
Guido van Rossumd48f2521997-12-05 22:19:34 +00005902 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005903 if (rc != NO_ERROR) {
5904 os2_error(rc);
5905 goto error;
5906 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005907
5908 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5909 APIRET rc;
5910
Guido van Rossumd48f2521997-12-05 22:19:34 +00005911 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005912 if (rc != NO_ERROR) {
5913 os2_error(rc);
5914 goto error;
5915 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005916 } else {
5917#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005918 /* XXX This can leak memory -- not easy to fix :-( */
5919 /* len includes space for a trailing \0; the size arg to
5920 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005921#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005922 len = wcslen(s1) + wcslen(s2) + 2;
5923 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005924#else
Victor Stinner84ae1182010-05-06 22:05:07 +00005925 len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2;
Victor Stinner8c62be82010-05-06 00:08:46 +00005926 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005927#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005928 if (newstr == NULL) {
5929 PyErr_NoMemory();
5930 goto error;
5931 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005932#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005933 newenv = PyUnicode_AsUnicode(newstr);
5934 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5935 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005936 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00005937 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005938 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005939#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005940 newenv = PyBytes_AS_STRING(newstr);
5941 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5942 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005943 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00005944 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005945 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005946#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005947
Victor Stinner8c62be82010-05-06 00:08:46 +00005948 /* Install the first arg and newstr in posix_putenv_garbage;
5949 * this will cause previous value to be collected. This has to
5950 * happen after the real putenv() call because the old value
5951 * was still accessible until then. */
5952 if (PyDict_SetItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00005953#ifdef MS_WINDOWS
5954 PyTuple_GET_ITEM(args, 0),
5955#else
5956 os1,
5957#endif
5958 newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005959 /* really not much we can do; just leak */
5960 PyErr_Clear();
5961 }
5962 else {
5963 Py_DECREF(newstr);
5964 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005965
5966#if defined(PYOS_OS2)
5967 }
5968#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005969
Martin v. Löwis011e8422009-05-05 04:43:17 +00005970#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005971 Py_DECREF(os1);
5972 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005973#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005974 Py_RETURN_NONE;
5975
5976error:
5977#ifndef MS_WINDOWS
5978 Py_DECREF(os1);
5979 Py_DECREF(os2);
5980#endif
5981 Py_XDECREF(newstr);
5982 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005983}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005984#endif /* putenv */
5985
Guido van Rossumc524d952001-10-19 01:31:59 +00005986#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005987PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005988"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005989Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005990
5991static PyObject *
5992posix_unsetenv(PyObject *self, PyObject *args)
5993{
Victor Stinner84ae1182010-05-06 22:05:07 +00005994#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005995 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00005996
Victor Stinner8c62be82010-05-06 00:08:46 +00005997 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5998 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00005999#else
6000 PyObject *os1;
6001 char *s1;
6002
6003 if (!PyArg_ParseTuple(args, "O&:unsetenv",
6004 PyUnicode_FSConverter, &os1))
6005 return NULL;
6006 s1 = PyBytes_AsString(os1);
6007#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006008
Victor Stinner8c62be82010-05-06 00:08:46 +00006009 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00006010
Victor Stinner8c62be82010-05-06 00:08:46 +00006011 /* Remove the key from posix_putenv_garbage;
6012 * this will cause it to be collected. This has to
6013 * happen after the real unsetenv() call because the
6014 * old value was still accessible until then.
6015 */
6016 if (PyDict_DelItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00006017#ifdef MS_WINDOWS
6018 PyTuple_GET_ITEM(args, 0)
6019#else
6020 os1
6021#endif
6022 )) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006023 /* really not much we can do; just leak */
6024 PyErr_Clear();
6025 }
Guido van Rossumc524d952001-10-19 01:31:59 +00006026
Victor Stinner84ae1182010-05-06 22:05:07 +00006027#ifndef MS_WINDOWS
6028 Py_DECREF(os1);
6029#endif
6030 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00006031}
6032#endif /* unsetenv */
6033
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006034PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006035"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006036Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006037
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006038static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006039posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006040{
Victor Stinner8c62be82010-05-06 00:08:46 +00006041 int code;
6042 char *message;
6043 if (!PyArg_ParseTuple(args, "i:strerror", &code))
6044 return NULL;
6045 message = strerror(code);
6046 if (message == NULL) {
6047 PyErr_SetString(PyExc_ValueError,
6048 "strerror() argument out of range");
6049 return NULL;
6050 }
6051 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006052}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006053
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006054
Guido van Rossumc9641791998-08-04 15:26:23 +00006055#ifdef HAVE_SYS_WAIT_H
6056
Fred Drake106c1a02002-04-23 15:58:02 +00006057#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006058PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006059"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006060Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006061
6062static PyObject *
6063posix_WCOREDUMP(PyObject *self, PyObject *args)
6064{
Victor Stinner8c62be82010-05-06 00:08:46 +00006065 WAIT_TYPE status;
6066 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006067
Victor Stinner8c62be82010-05-06 00:08:46 +00006068 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
6069 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006070
Victor Stinner8c62be82010-05-06 00:08:46 +00006071 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006072}
6073#endif /* WCOREDUMP */
6074
6075#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006076PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006077"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006078Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006079job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006080
6081static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006082posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006083{
Victor Stinner8c62be82010-05-06 00:08:46 +00006084 WAIT_TYPE status;
6085 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006086
Victor Stinner8c62be82010-05-06 00:08:46 +00006087 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
6088 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006089
Victor Stinner8c62be82010-05-06 00:08:46 +00006090 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006091}
6092#endif /* WIFCONTINUED */
6093
Guido van Rossumc9641791998-08-04 15:26:23 +00006094#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006095PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006096"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006097Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006098
6099static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006100posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006101{
Victor Stinner8c62be82010-05-06 00:08:46 +00006102 WAIT_TYPE status;
6103 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006104
Victor Stinner8c62be82010-05-06 00:08:46 +00006105 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
6106 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006107
Victor Stinner8c62be82010-05-06 00:08:46 +00006108 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006109}
6110#endif /* WIFSTOPPED */
6111
6112#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006113PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006114"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006115Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006116
6117static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006118posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006119{
Victor Stinner8c62be82010-05-06 00:08:46 +00006120 WAIT_TYPE status;
6121 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006122
Victor Stinner8c62be82010-05-06 00:08:46 +00006123 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
6124 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006125
Victor Stinner8c62be82010-05-06 00:08:46 +00006126 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006127}
6128#endif /* WIFSIGNALED */
6129
6130#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006131PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006132"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006133Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006134system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006135
6136static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006137posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006138{
Victor Stinner8c62be82010-05-06 00:08:46 +00006139 WAIT_TYPE status;
6140 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006141
Victor Stinner8c62be82010-05-06 00:08:46 +00006142 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
6143 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006144
Victor Stinner8c62be82010-05-06 00:08:46 +00006145 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006146}
6147#endif /* WIFEXITED */
6148
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006149#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006150PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006151"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006152Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006153
6154static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006155posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006156{
Victor Stinner8c62be82010-05-06 00:08:46 +00006157 WAIT_TYPE status;
6158 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006159
Victor Stinner8c62be82010-05-06 00:08:46 +00006160 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
6161 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006162
Victor Stinner8c62be82010-05-06 00:08:46 +00006163 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006164}
6165#endif /* WEXITSTATUS */
6166
6167#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006168PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006169"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006170Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006171value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006172
6173static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006174posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006175{
Victor Stinner8c62be82010-05-06 00:08:46 +00006176 WAIT_TYPE status;
6177 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006178
Victor Stinner8c62be82010-05-06 00:08:46 +00006179 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
6180 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006181
Victor Stinner8c62be82010-05-06 00:08:46 +00006182 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006183}
6184#endif /* WTERMSIG */
6185
6186#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006187PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006188"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006189Return the signal that stopped the process that provided\n\
6190the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006191
6192static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006193posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006194{
Victor Stinner8c62be82010-05-06 00:08:46 +00006195 WAIT_TYPE status;
6196 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006197
Victor Stinner8c62be82010-05-06 00:08:46 +00006198 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
6199 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006200
Victor Stinner8c62be82010-05-06 00:08:46 +00006201 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006202}
6203#endif /* WSTOPSIG */
6204
6205#endif /* HAVE_SYS_WAIT_H */
6206
6207
Thomas Wouters477c8d52006-05-27 19:21:47 +00006208#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006209#ifdef _SCO_DS
6210/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6211 needed definitions in sys/statvfs.h */
6212#define _SVID3
6213#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006214#include <sys/statvfs.h>
6215
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006216static PyObject*
6217_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006218 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6219 if (v == NULL)
6220 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006221
6222#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006223 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6224 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6225 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
6226 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
6227 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
6228 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
6229 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
6230 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
6231 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6232 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006233#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006234 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6235 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6236 PyStructSequence_SET_ITEM(v, 2,
6237 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
6238 PyStructSequence_SET_ITEM(v, 3,
6239 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
6240 PyStructSequence_SET_ITEM(v, 4,
6241 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
6242 PyStructSequence_SET_ITEM(v, 5,
6243 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
6244 PyStructSequence_SET_ITEM(v, 6,
6245 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
6246 PyStructSequence_SET_ITEM(v, 7,
6247 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
6248 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6249 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006250#endif
6251
Victor Stinner8c62be82010-05-06 00:08:46 +00006252 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006253}
6254
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006255PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006256"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006257Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006258
6259static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006260posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006261{
Victor Stinner8c62be82010-05-06 00:08:46 +00006262 int fd, res;
6263 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006264
Victor Stinner8c62be82010-05-06 00:08:46 +00006265 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
6266 return NULL;
6267 Py_BEGIN_ALLOW_THREADS
6268 res = fstatvfs(fd, &st);
6269 Py_END_ALLOW_THREADS
6270 if (res != 0)
6271 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006272
Victor Stinner8c62be82010-05-06 00:08:46 +00006273 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006274}
Thomas Wouters477c8d52006-05-27 19:21:47 +00006275#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006276
6277
Thomas Wouters477c8d52006-05-27 19:21:47 +00006278#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006279#include <sys/statvfs.h>
6280
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006281PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006282"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006283Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006284
6285static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006286posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006287{
Victor Stinner8c62be82010-05-06 00:08:46 +00006288 char *path;
6289 int res;
6290 struct statvfs st;
6291 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
6292 return NULL;
6293 Py_BEGIN_ALLOW_THREADS
6294 res = statvfs(path, &st);
6295 Py_END_ALLOW_THREADS
6296 if (res != 0)
6297 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006298
Victor Stinner8c62be82010-05-06 00:08:46 +00006299 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006300}
6301#endif /* HAVE_STATVFS */
6302
Fred Drakec9680921999-12-13 16:37:25 +00006303/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6304 * It maps strings representing configuration variable names to
6305 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006306 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006307 * rarely-used constants. There are three separate tables that use
6308 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006309 *
6310 * This code is always included, even if none of the interfaces that
6311 * need it are included. The #if hackery needed to avoid it would be
6312 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006313 */
6314struct constdef {
6315 char *name;
6316 long value;
6317};
6318
Fred Drake12c6e2d1999-12-14 21:25:03 +00006319static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006320conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00006321 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006322{
Christian Heimes217cfd12007-12-02 14:31:20 +00006323 if (PyLong_Check(arg)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006324 *valuep = PyLong_AS_LONG(arg);
6325 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006326 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00006327 else {
Victor Stinner8c62be82010-05-06 00:08:46 +00006328 /* look up the value in the table using a binary search */
6329 size_t lo = 0;
6330 size_t mid;
6331 size_t hi = tablesize;
6332 int cmp;
6333 const char *confname;
6334 if (!PyUnicode_Check(arg)) {
6335 PyErr_SetString(PyExc_TypeError,
6336 "configuration names must be strings or integers");
Guido van Rossumbce56a62007-05-10 18:04:33 +00006337 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006338 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006339 confname = _PyUnicode_AsString(arg);
6340 if (confname == NULL)
6341 return 0;
6342 while (lo < hi) {
6343 mid = (lo + hi) / 2;
6344 cmp = strcmp(confname, table[mid].name);
6345 if (cmp < 0)
6346 hi = mid;
6347 else if (cmp > 0)
6348 lo = mid + 1;
6349 else {
6350 *valuep = table[mid].value;
6351 return 1;
6352 }
6353 }
6354 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6355 return 0;
6356 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00006357}
6358
6359
6360#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6361static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006362#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006363 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006364#endif
6365#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006366 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006367#endif
Fred Drakec9680921999-12-13 16:37:25 +00006368#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006369 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006370#endif
6371#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00006372 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00006373#endif
6374#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00006375 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00006376#endif
6377#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00006378 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00006379#endif
6380#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006381 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006382#endif
6383#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00006384 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00006385#endif
6386#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00006387 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00006388#endif
6389#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006390 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006391#endif
6392#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006393 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00006394#endif
6395#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006396 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006397#endif
6398#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006399 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00006400#endif
6401#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006402 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006403#endif
6404#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006405 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00006406#endif
6407#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006408 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006409#endif
6410#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00006411 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00006412#endif
6413};
6414
Fred Drakec9680921999-12-13 16:37:25 +00006415static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006416conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006417{
6418 return conv_confname(arg, valuep, posix_constants_pathconf,
6419 sizeof(posix_constants_pathconf)
6420 / sizeof(struct constdef));
6421}
6422#endif
6423
6424#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006425PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006426"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006427Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006428If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006429
6430static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006431posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006432{
6433 PyObject *result = NULL;
6434 int name, fd;
6435
Fred Drake12c6e2d1999-12-14 21:25:03 +00006436 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6437 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006438 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006439
Victor Stinner8c62be82010-05-06 00:08:46 +00006440 errno = 0;
6441 limit = fpathconf(fd, name);
6442 if (limit == -1 && errno != 0)
6443 posix_error();
6444 else
6445 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006446 }
6447 return result;
6448}
6449#endif
6450
6451
6452#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006453PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006454"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006455Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006456If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006457
6458static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006459posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006460{
6461 PyObject *result = NULL;
6462 int name;
6463 char *path;
6464
6465 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6466 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006467 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006468
Victor Stinner8c62be82010-05-06 00:08:46 +00006469 errno = 0;
6470 limit = pathconf(path, name);
6471 if (limit == -1 && errno != 0) {
6472 if (errno == EINVAL)
6473 /* could be a path or name problem */
6474 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00006475 else
Victor Stinner8c62be82010-05-06 00:08:46 +00006476 posix_error_with_filename(path);
6477 }
6478 else
6479 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006480 }
6481 return result;
6482}
6483#endif
6484
6485#ifdef HAVE_CONFSTR
6486static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006487#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00006488 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00006489#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00006490#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006491 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006492#endif
6493#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006494 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006495#endif
Fred Draked86ed291999-12-15 15:34:33 +00006496#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006497 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006498#endif
6499#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006500 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006501#endif
6502#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006503 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006504#endif
6505#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006506 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006507#endif
Fred Drakec9680921999-12-13 16:37:25 +00006508#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006509 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006510#endif
6511#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006512 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006513#endif
6514#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006515 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006516#endif
6517#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006518 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006519#endif
6520#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006521 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006522#endif
6523#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006524 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006525#endif
6526#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006527 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006528#endif
6529#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006530 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006531#endif
Fred Draked86ed291999-12-15 15:34:33 +00006532#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00006533 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00006534#endif
Fred Drakec9680921999-12-13 16:37:25 +00006535#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00006536 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00006537#endif
Fred Draked86ed291999-12-15 15:34:33 +00006538#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006539 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00006540#endif
6541#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006542 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00006543#endif
6544#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006545 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006546#endif
6547#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006548 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00006549#endif
Fred Drakec9680921999-12-13 16:37:25 +00006550#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006551 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006552#endif
6553#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006554 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006555#endif
6556#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006557 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006558#endif
6559#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006560 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006561#endif
6562#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006563 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006564#endif
6565#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006566 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006567#endif
6568#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006569 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006570#endif
6571#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006572 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006573#endif
6574#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006575 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006576#endif
6577#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006578 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006579#endif
6580#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006581 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006582#endif
6583#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006584 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006585#endif
6586#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006587 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006588#endif
6589#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006590 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006591#endif
6592#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006593 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006594#endif
6595#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006596 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006597#endif
Fred Draked86ed291999-12-15 15:34:33 +00006598#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006599 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006600#endif
6601#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006602 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00006603#endif
6604#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00006605 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00006606#endif
6607#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006608 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006609#endif
6610#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006611 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006612#endif
6613#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00006614 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00006615#endif
6616#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006617 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00006618#endif
6619#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00006620 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00006621#endif
6622#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006623 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006624#endif
6625#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006626 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006627#endif
6628#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006629 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006630#endif
6631#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006632 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006633#endif
6634#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00006635 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00006636#endif
Fred Drakec9680921999-12-13 16:37:25 +00006637};
6638
6639static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006640conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006641{
6642 return conv_confname(arg, valuep, posix_constants_confstr,
6643 sizeof(posix_constants_confstr)
6644 / sizeof(struct constdef));
6645}
6646
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006647PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006648"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006649Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006650
6651static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006652posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006653{
6654 PyObject *result = NULL;
6655 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00006656 char buffer[255];
Victor Stinner8c62be82010-05-06 00:08:46 +00006657 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006658
Victor Stinnercb043522010-09-10 23:49:04 +00006659 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
6660 return NULL;
6661
6662 errno = 0;
6663 len = confstr(name, buffer, sizeof(buffer));
6664 if (len == 0) {
6665 if (errno) {
6666 posix_error();
6667 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00006668 }
6669 else {
Victor Stinnercb043522010-09-10 23:49:04 +00006670 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00006671 }
6672 }
Victor Stinnercb043522010-09-10 23:49:04 +00006673
6674 if ((unsigned int)len >= sizeof(buffer)) {
6675 char *buf = PyMem_Malloc(len);
6676 if (buf == NULL)
6677 return PyErr_NoMemory();
6678 confstr(name, buf, len);
6679 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
6680 PyMem_Free(buf);
6681 }
6682 else
6683 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006684 return result;
6685}
6686#endif
6687
6688
6689#ifdef HAVE_SYSCONF
6690static struct constdef posix_constants_sysconf[] = {
6691#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00006692 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00006693#endif
6694#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00006695 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00006696#endif
6697#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006698 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006699#endif
6700#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006701 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006702#endif
6703#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006704 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006705#endif
6706#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00006707 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00006708#endif
6709#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00006710 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00006711#endif
6712#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006713 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006714#endif
6715#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00006716 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00006717#endif
6718#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006719 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006720#endif
Fred Draked86ed291999-12-15 15:34:33 +00006721#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006722 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006723#endif
6724#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00006725 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00006726#endif
Fred Drakec9680921999-12-13 16:37:25 +00006727#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006728 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006729#endif
Fred Drakec9680921999-12-13 16:37:25 +00006730#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006731 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006732#endif
6733#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006734 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006735#endif
6736#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006737 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006738#endif
6739#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006740 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006741#endif
6742#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006743 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006744#endif
Fred Draked86ed291999-12-15 15:34:33 +00006745#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006746 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00006747#endif
Fred Drakec9680921999-12-13 16:37:25 +00006748#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00006749 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006750#endif
6751#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006752 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006753#endif
6754#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006755 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006756#endif
6757#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006758 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006759#endif
6760#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006761 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006762#endif
Fred Draked86ed291999-12-15 15:34:33 +00006763#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00006764 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00006765#endif
Fred Drakec9680921999-12-13 16:37:25 +00006766#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006767 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006768#endif
6769#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006770 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006771#endif
6772#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006773 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006774#endif
6775#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006776 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006777#endif
6778#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006779 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006780#endif
6781#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006782 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00006783#endif
6784#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006785 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006786#endif
6787#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006788 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006789#endif
6790#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006791 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006792#endif
6793#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006794 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006795#endif
6796#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006797 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006798#endif
6799#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006801#endif
6802#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006803 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006804#endif
6805#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006806 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006807#endif
6808#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006809 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006810#endif
6811#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006812 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006813#endif
6814#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006815 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00006816#endif
6817#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006818 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006819#endif
6820#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006821 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006822#endif
6823#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006824 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006825#endif
6826#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006827 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006828#endif
6829#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006830 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006831#endif
6832#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006833 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006834#endif
Fred Draked86ed291999-12-15 15:34:33 +00006835#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00006836 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00006837#endif
Fred Drakec9680921999-12-13 16:37:25 +00006838#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006839 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006840#endif
6841#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006842 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006843#endif
6844#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006845 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006846#endif
Fred Draked86ed291999-12-15 15:34:33 +00006847#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006848 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00006849#endif
Fred Drakec9680921999-12-13 16:37:25 +00006850#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00006851 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00006852#endif
Fred Draked86ed291999-12-15 15:34:33 +00006853#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00006854 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00006855#endif
6856#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00006857 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00006858#endif
Fred Drakec9680921999-12-13 16:37:25 +00006859#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006860 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006861#endif
6862#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006863 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006864#endif
6865#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006866 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006867#endif
6868#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006869 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006870#endif
Fred Draked86ed291999-12-15 15:34:33 +00006871#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00006872 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00006873#endif
Fred Drakec9680921999-12-13 16:37:25 +00006874#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00006875 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00006876#endif
6877#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00006878 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00006879#endif
6880#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006881 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006882#endif
6883#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006884 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00006885#endif
6886#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00006887 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00006888#endif
6889#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00006890 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00006891#endif
6892#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00006893 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00006894#endif
Fred Draked86ed291999-12-15 15:34:33 +00006895#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00006896 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00006897#endif
Fred Drakec9680921999-12-13 16:37:25 +00006898#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006899 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006900#endif
6901#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006902 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006903#endif
Fred Draked86ed291999-12-15 15:34:33 +00006904#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006905 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006906#endif
Fred Drakec9680921999-12-13 16:37:25 +00006907#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006908 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006909#endif
6910#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006911 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006912#endif
6913#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006914 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006915#endif
6916#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006917 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006918#endif
6919#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006920 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006921#endif
6922#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006923 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006924#endif
6925#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006926 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006927#endif
6928#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00006929 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00006930#endif
6931#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00006932 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00006933#endif
Fred Draked86ed291999-12-15 15:34:33 +00006934#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00006935 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00006936#endif
6937#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00006938 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00006939#endif
Fred Drakec9680921999-12-13 16:37:25 +00006940#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00006941 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00006942#endif
6943#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006944 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006945#endif
6946#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00006947 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006948#endif
6949#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00006950 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006951#endif
6952#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006953 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006954#endif
6955#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00006956 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006957#endif
6958#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00006959 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00006960#endif
6961#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00006962 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00006963#endif
6964#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00006965 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00006966#endif
6967#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00006968 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00006969#endif
6970#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00006971 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00006972#endif
6973#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006974 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00006975#endif
6976#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006977 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00006978#endif
6979#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00006980 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00006981#endif
6982#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00006983 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00006984#endif
6985#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00006986 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00006987#endif
6988#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00006989 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00006990#endif
6991#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006992 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006993#endif
6994#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00006995 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00006996#endif
6997#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00006998 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00006999#endif
7000#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007001 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007002#endif
7003#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007004 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007005#endif
7006#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00007007 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00007008#endif
7009#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007010 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007011#endif
7012#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007013 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007014#endif
7015#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007016 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00007017#endif
7018#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00007019 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00007020#endif
7021#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007022 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007023#endif
7024#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007025 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007026#endif
7027#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007028 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00007029#endif
7030#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007031 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007032#endif
7033#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007034 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007035#endif
7036#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007037 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007038#endif
7039#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007040 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007041#endif
7042#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007043 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007044#endif
Fred Draked86ed291999-12-15 15:34:33 +00007045#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00007046 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00007047#endif
Fred Drakec9680921999-12-13 16:37:25 +00007048#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00007049 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00007050#endif
7051#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007052 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007053#endif
7054#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00007055 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00007056#endif
7057#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007058 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007059#endif
7060#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007061 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007062#endif
7063#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007064 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007065#endif
7066#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00007067 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00007068#endif
7069#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007070 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007071#endif
7072#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007073 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007074#endif
7075#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007076 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007077#endif
7078#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007079 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007080#endif
7081#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007082 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00007083#endif
7084#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007085 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00007086#endif
7087#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00007088 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00007089#endif
7090#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007091 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007092#endif
7093#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007094 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007095#endif
7096#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007097 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007098#endif
7099#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00007100 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00007101#endif
7102#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007103 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007104#endif
7105#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007106 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007107#endif
7108#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007109 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007110#endif
7111#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007112 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007113#endif
7114#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007115 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007116#endif
7117#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007118 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007119#endif
7120#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00007121 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00007122#endif
7123#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007124 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007125#endif
7126#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007127 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007128#endif
7129#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007130 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007131#endif
7132#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007133 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007134#endif
7135#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00007136 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00007137#endif
7138#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007139 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007140#endif
7141#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00007142 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00007143#endif
7144#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007145 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007146#endif
7147#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00007148 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00007149#endif
7150#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00007151 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00007152#endif
7153#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00007154 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00007155#endif
7156#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00007157 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00007158#endif
7159#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007160 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007161#endif
7162#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00007163 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00007164#endif
7165#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00007166 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00007167#endif
7168#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007169 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007170#endif
7171#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007172 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007173#endif
7174#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00007175 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00007176#endif
7177#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00007178 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00007179#endif
7180#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00007181 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00007182#endif
7183};
7184
7185static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007186conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007187{
7188 return conv_confname(arg, valuep, posix_constants_sysconf,
7189 sizeof(posix_constants_sysconf)
7190 / sizeof(struct constdef));
7191}
7192
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007193PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007194"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007195Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007196
7197static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007198posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007199{
7200 PyObject *result = NULL;
7201 int name;
7202
7203 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7204 int value;
7205
7206 errno = 0;
7207 value = sysconf(name);
7208 if (value == -1 && errno != 0)
7209 posix_error();
7210 else
Christian Heimes217cfd12007-12-02 14:31:20 +00007211 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00007212 }
7213 return result;
7214}
7215#endif
7216
7217
Fred Drakebec628d1999-12-15 18:31:10 +00007218/* This code is used to ensure that the tables of configuration value names
7219 * are in sorted order as required by conv_confname(), and also to build the
7220 * the exported dictionaries that are used to publish information about the
7221 * names available on the host platform.
7222 *
7223 * Sorting the table at runtime ensures that the table is properly ordered
7224 * when used, even for platforms we're not able to test on. It also makes
7225 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007226 */
Fred Drakebec628d1999-12-15 18:31:10 +00007227
7228static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007229cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007230{
7231 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007232 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00007233 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007234 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00007235
7236 return strcmp(c1->name, c2->name);
7237}
7238
7239static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007240setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00007241 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007242{
Fred Drakebec628d1999-12-15 18:31:10 +00007243 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007244 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007245
7246 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7247 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007248 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00007249 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007250
Barry Warsaw3155db32000-04-13 15:20:40 +00007251 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007252 PyObject *o = PyLong_FromLong(table[i].value);
7253 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7254 Py_XDECREF(o);
7255 Py_DECREF(d);
7256 return -1;
7257 }
7258 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007259 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007260 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007261}
7262
Fred Drakebec628d1999-12-15 18:31:10 +00007263/* Return -1 on failure, 0 on success. */
7264static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007265setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007266{
7267#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007268 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007269 sizeof(posix_constants_pathconf)
7270 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007271 "pathconf_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007272 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007273#endif
7274#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007275 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007276 sizeof(posix_constants_confstr)
7277 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007278 "confstr_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007279 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007280#endif
7281#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007282 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007283 sizeof(posix_constants_sysconf)
7284 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007285 "sysconf_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007286 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007287#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007288 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007289}
Fred Draked86ed291999-12-15 15:34:33 +00007290
7291
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007292PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007293"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007294Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007295in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007296
7297static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007298posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007299{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007300 abort();
7301 /*NOTREACHED*/
7302 Py_FatalError("abort() called from Python code didn't abort!");
7303 return NULL;
7304}
Fred Drakebec628d1999-12-15 18:31:10 +00007305
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007306#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007307PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007308"startfile(filepath [, operation]) - Start a file with its associated\n\
7309application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007310\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007311When \"operation\" is not specified or \"open\", this acts like\n\
7312double-clicking the file in Explorer, or giving the file name as an\n\
7313argument to the DOS \"start\" command: the file is opened with whatever\n\
7314application (if any) its extension is associated.\n\
7315When another \"operation\" is given, it specifies what should be done with\n\
7316the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007317\n\
7318startfile returns as soon as the associated application is launched.\n\
7319There is no option to wait for the application to close, and no way\n\
7320to retrieve the application's exit status.\n\
7321\n\
7322The filepath is relative to the current directory. If you want to use\n\
7323an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007324the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007325
7326static PyObject *
7327win32_startfile(PyObject *self, PyObject *args)
7328{
Victor Stinner8c62be82010-05-06 00:08:46 +00007329 PyObject *ofilepath;
7330 char *filepath;
7331 char *operation = NULL;
7332 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00007333
Victor Stinner8c62be82010-05-06 00:08:46 +00007334 PyObject *unipath, *woperation = NULL;
7335 if (!PyArg_ParseTuple(args, "U|s:startfile",
7336 &unipath, &operation)) {
7337 PyErr_Clear();
7338 goto normal;
7339 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007340
Victor Stinner8c62be82010-05-06 00:08:46 +00007341 if (operation) {
7342 woperation = PyUnicode_DecodeASCII(operation,
7343 strlen(operation), NULL);
7344 if (!woperation) {
7345 PyErr_Clear();
7346 operation = NULL;
7347 goto normal;
7348 }
7349 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007350
Victor Stinner8c62be82010-05-06 00:08:46 +00007351 Py_BEGIN_ALLOW_THREADS
7352 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
7353 PyUnicode_AS_UNICODE(unipath),
7354 NULL, NULL, SW_SHOWNORMAL);
7355 Py_END_ALLOW_THREADS
7356
7357 Py_XDECREF(woperation);
7358 if (rc <= (HINSTANCE)32) {
7359 PyObject *errval = win32_error_unicode("startfile",
7360 PyUnicode_AS_UNICODE(unipath));
7361 return errval;
7362 }
7363 Py_INCREF(Py_None);
7364 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007365
7366normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00007367 if (!PyArg_ParseTuple(args, "O&|s:startfile",
7368 PyUnicode_FSConverter, &ofilepath,
7369 &operation))
7370 return NULL;
7371 filepath = PyBytes_AsString(ofilepath);
7372 Py_BEGIN_ALLOW_THREADS
7373 rc = ShellExecute((HWND)0, operation, filepath,
7374 NULL, NULL, SW_SHOWNORMAL);
7375 Py_END_ALLOW_THREADS
7376 if (rc <= (HINSTANCE)32) {
7377 PyObject *errval = win32_error("startfile", filepath);
7378 Py_DECREF(ofilepath);
7379 return errval;
7380 }
7381 Py_DECREF(ofilepath);
7382 Py_INCREF(Py_None);
7383 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007384}
7385#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007386
Martin v. Löwis438b5342002-12-27 10:16:42 +00007387#ifdef HAVE_GETLOADAVG
7388PyDoc_STRVAR(posix_getloadavg__doc__,
7389"getloadavg() -> (float, float, float)\n\n\
7390Return the number of processes in the system run queue averaged over\n\
7391the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7392was unobtainable");
7393
7394static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007395posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007396{
7397 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007398 if (getloadavg(loadavg, 3)!=3) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007399 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7400 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00007401 } else
Victor Stinner8c62be82010-05-06 00:08:46 +00007402 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00007403}
7404#endif
7405
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007406#ifdef MS_WINDOWS
7407
7408PyDoc_STRVAR(win32_urandom__doc__,
7409"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007410Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007411
7412typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7413 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7414 DWORD dwFlags );
7415typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7416 BYTE *pbBuffer );
7417
7418static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00007419/* This handle is never explicitly released. Instead, the operating
7420 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007421static HCRYPTPROV hCryptProv = 0;
7422
Tim Peters4ad82172004-08-30 17:02:04 +00007423static PyObject*
7424win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007425{
Victor Stinner8c62be82010-05-06 00:08:46 +00007426 int howMany;
7427 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007428
Victor Stinner8c62be82010-05-06 00:08:46 +00007429 /* Read arguments */
7430 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7431 return NULL;
7432 if (howMany < 0)
7433 return PyErr_Format(PyExc_ValueError,
7434 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007435
Victor Stinner8c62be82010-05-06 00:08:46 +00007436 if (hCryptProv == 0) {
7437 HINSTANCE hAdvAPI32 = NULL;
7438 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007439
Victor Stinner8c62be82010-05-06 00:08:46 +00007440 /* Obtain handle to the DLL containing CryptoAPI
7441 This should not fail */
7442 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7443 if(hAdvAPI32 == NULL)
7444 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007445
Victor Stinner8c62be82010-05-06 00:08:46 +00007446 /* Obtain pointers to the CryptoAPI functions
7447 This will fail on some early versions of Win95 */
7448 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7449 hAdvAPI32,
7450 "CryptAcquireContextA");
7451 if (pCryptAcquireContext == NULL)
7452 return PyErr_Format(PyExc_NotImplementedError,
7453 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007454
Victor Stinner8c62be82010-05-06 00:08:46 +00007455 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7456 hAdvAPI32, "CryptGenRandom");
7457 if (pCryptGenRandom == NULL)
7458 return PyErr_Format(PyExc_NotImplementedError,
7459 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007460
Victor Stinner8c62be82010-05-06 00:08:46 +00007461 /* Acquire context */
7462 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7463 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7464 return win32_error("CryptAcquireContext", NULL);
7465 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007466
Victor Stinner8c62be82010-05-06 00:08:46 +00007467 /* Allocate bytes */
7468 result = PyBytes_FromStringAndSize(NULL, howMany);
7469 if (result != NULL) {
7470 /* Get random data */
7471 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
7472 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7473 PyBytes_AS_STRING(result))) {
7474 Py_DECREF(result);
7475 return win32_error("CryptGenRandom", NULL);
7476 }
7477 }
7478 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007479}
7480#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007481
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007482PyDoc_STRVAR(device_encoding__doc__,
7483"device_encoding(fd) -> str\n\n\
7484Return a string describing the encoding of the device\n\
7485if the output is a terminal; else return None.");
7486
7487static PyObject *
7488device_encoding(PyObject *self, PyObject *args)
7489{
Victor Stinner8c62be82010-05-06 00:08:46 +00007490 int fd;
7491 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
7492 return NULL;
7493 if (!_PyVerify_fd(fd) || !isatty(fd)) {
7494 Py_INCREF(Py_None);
7495 return Py_None;
7496 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007497#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner8c62be82010-05-06 00:08:46 +00007498 if (fd == 0) {
7499 char buf[100];
7500 sprintf(buf, "cp%d", GetConsoleCP());
7501 return PyUnicode_FromString(buf);
7502 }
7503 if (fd == 1 || fd == 2) {
7504 char buf[100];
7505 sprintf(buf, "cp%d", GetConsoleOutputCP());
7506 return PyUnicode_FromString(buf);
7507 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007508#elif defined(CODESET)
Victor Stinner8c62be82010-05-06 00:08:46 +00007509 {
7510 char *codeset = nl_langinfo(CODESET);
7511 if (codeset != NULL && codeset[0] != 0)
7512 return PyUnicode_FromString(codeset);
7513 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007514#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007515 Py_INCREF(Py_None);
7516 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007517}
7518
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007519#ifdef __VMS
7520/* Use openssl random routine */
7521#include <openssl/rand.h>
7522PyDoc_STRVAR(vms_urandom__doc__,
7523"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007524Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007525
7526static PyObject*
7527vms_urandom(PyObject *self, PyObject *args)
7528{
Victor Stinner8c62be82010-05-06 00:08:46 +00007529 int howMany;
7530 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007531
Victor Stinner8c62be82010-05-06 00:08:46 +00007532 /* Read arguments */
7533 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7534 return NULL;
7535 if (howMany < 0)
7536 return PyErr_Format(PyExc_ValueError,
7537 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007538
Victor Stinner8c62be82010-05-06 00:08:46 +00007539 /* Allocate bytes */
7540 result = PyBytes_FromStringAndSize(NULL, howMany);
7541 if (result != NULL) {
7542 /* Get random data */
7543 if (RAND_pseudo_bytes((unsigned char*)
7544 PyBytes_AS_STRING(result),
7545 howMany) < 0) {
7546 Py_DECREF(result);
7547 return PyErr_Format(PyExc_ValueError,
7548 "RAND_pseudo_bytes");
7549 }
7550 }
7551 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007552}
7553#endif
7554
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007555#ifdef HAVE_SETRESUID
7556PyDoc_STRVAR(posix_setresuid__doc__,
7557"setresuid(ruid, euid, suid)\n\n\
7558Set the current process's real, effective, and saved user ids.");
7559
7560static PyObject*
7561posix_setresuid (PyObject *self, PyObject *args)
7562{
Victor Stinner8c62be82010-05-06 00:08:46 +00007563 /* We assume uid_t is no larger than a long. */
7564 long ruid, euid, suid;
7565 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
7566 return NULL;
7567 if (setresuid(ruid, euid, suid) < 0)
7568 return posix_error();
7569 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007570}
7571#endif
7572
7573#ifdef HAVE_SETRESGID
7574PyDoc_STRVAR(posix_setresgid__doc__,
7575"setresgid(rgid, egid, sgid)\n\n\
7576Set the current process's real, effective, and saved group ids.");
7577
7578static PyObject*
7579posix_setresgid (PyObject *self, PyObject *args)
7580{
Victor Stinner8c62be82010-05-06 00:08:46 +00007581 /* We assume uid_t is no larger than a long. */
7582 long rgid, egid, sgid;
7583 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
7584 return NULL;
7585 if (setresgid(rgid, egid, sgid) < 0)
7586 return posix_error();
7587 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007588}
7589#endif
7590
7591#ifdef HAVE_GETRESUID
7592PyDoc_STRVAR(posix_getresuid__doc__,
7593"getresuid() -> (ruid, euid, suid)\n\n\
7594Get tuple of the current process's real, effective, and saved user ids.");
7595
7596static PyObject*
7597posix_getresuid (PyObject *self, PyObject *noargs)
7598{
Victor Stinner8c62be82010-05-06 00:08:46 +00007599 uid_t ruid, euid, suid;
7600 long l_ruid, l_euid, l_suid;
7601 if (getresuid(&ruid, &euid, &suid) < 0)
7602 return posix_error();
7603 /* Force the values into long's as we don't know the size of uid_t. */
7604 l_ruid = ruid;
7605 l_euid = euid;
7606 l_suid = suid;
7607 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007608}
7609#endif
7610
7611#ifdef HAVE_GETRESGID
7612PyDoc_STRVAR(posix_getresgid__doc__,
7613"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00007614Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007615
7616static PyObject*
7617posix_getresgid (PyObject *self, PyObject *noargs)
7618{
Victor Stinner8c62be82010-05-06 00:08:46 +00007619 uid_t rgid, egid, sgid;
7620 long l_rgid, l_egid, l_sgid;
7621 if (getresgid(&rgid, &egid, &sgid) < 0)
7622 return posix_error();
7623 /* Force the values into long's as we don't know the size of uid_t. */
7624 l_rgid = rgid;
7625 l_egid = egid;
7626 l_sgid = sgid;
7627 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007628}
7629#endif
7630
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007631static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00007632 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007633#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007634 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007635#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007636 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007637#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007638 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007639#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007640 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007641#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007642 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007643#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007644#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007645 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007646#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00007647#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007648 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007649#endif /* HAVE_LCHMOD */
7650#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007651 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007652#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00007653#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007654 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007655#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007656#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007657 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007658#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007659#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +00007660 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00007661#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007662#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +00007663 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007664#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007665#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +00007666 {"getcwd", (PyCFunction)posix_getcwd_unicode,
7667 METH_NOARGS, posix_getcwd__doc__},
7668 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
7669 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007670#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007671#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007672 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007673#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +00007674 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7675 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7676 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007677#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +00007678 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007679#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007680#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007681 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007682#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007683#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007684 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007685#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007686 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7687 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7688 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +00007689 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007690#ifdef HAVE_SYMLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007691 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007692#endif /* HAVE_SYMLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007693#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin74e45612010-07-09 15:58:59 +00007694 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
7695 win_symlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007696#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007697#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +00007698 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007699#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007700 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007701#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007702 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007703#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +00007704 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7705 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7706 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007707#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00007708 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007709#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00007710 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007711#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +00007712 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7713 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007714#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007715#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +00007716 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7717 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007718#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00007719 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7720 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007721#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007722#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007723#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +00007724 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007725#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007726#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +00007727 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007728#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007729#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +00007730 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007731#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007732#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007733 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007734#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007735#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007736 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007737#endif /* HAVE_GETEGID */
7738#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007739 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007740#endif /* HAVE_GETEUID */
7741#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007742 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007743#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007744#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007745 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007746#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007747 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007748#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007749 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007750#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007751#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +00007752 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007753#endif /* HAVE_GETPPID */
7754#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007755 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007756#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007757#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007758 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007759#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007760#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +00007761 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007762#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007763#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +00007764 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007765#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007766#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007767 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007768#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007769#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007770 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7771 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +00007772#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007773#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007774 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007775#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007776#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007777 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007778#endif /* HAVE_SETEUID */
7779#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007780 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007781#endif /* HAVE_SETEGID */
7782#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007783 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007784#endif /* HAVE_SETREUID */
7785#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007786 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007787#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007788#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007789 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007790#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007791#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007792 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007793#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +00007794#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007795 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +00007796#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007797#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007798 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00007799#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007800#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007801 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007802#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007803#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007804 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007805#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007806#ifdef HAVE_WAIT3
Victor Stinner8c62be82010-05-06 00:08:46 +00007807 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007808#endif /* HAVE_WAIT3 */
7809#ifdef HAVE_WAIT4
Victor Stinner8c62be82010-05-06 00:08:46 +00007810 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007811#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007812#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007813 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007814#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007815#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007816 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007817#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007818#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007819 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007820#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007821#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007822 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007823#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007824#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007825 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007826#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007827#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007828 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007829#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +00007830 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7831 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7832 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
7833 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
7834 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7835 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7836 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7837 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7838 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7839 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7840 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007841#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +00007842 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007843#endif
7844#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +00007845 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007846#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007847#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +00007848 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007849#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007850#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +00007851 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7852 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7853 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007854#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007855#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +00007856 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007857#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007858#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007859 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007860#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007861#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007862 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00007863#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007864 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007865#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +00007866 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007867#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007868#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007869 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007870#endif
7871#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007872 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007873#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007874#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007875#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +00007876 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00007877#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007878#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00007879 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007880#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007881#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +00007882 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007883#endif /* WIFSTOPPED */
7884#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +00007885 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007886#endif /* WIFSIGNALED */
7887#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +00007888 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007889#endif /* WIFEXITED */
7890#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +00007891 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007892#endif /* WEXITSTATUS */
7893#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007894 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007895#endif /* WTERMSIG */
7896#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007897 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007898#endif /* WSTOPSIG */
7899#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007900#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007901 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007902#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007903#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007904 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007905#endif
Fred Drakec9680921999-12-13 16:37:25 +00007906#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +00007907 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007908#endif
7909#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007910 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007911#endif
7912#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007913 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007914#endif
7915#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007916 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007917#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007918 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007919#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007920 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +00007921 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +00007922 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Mark Hammondef8b6542001-05-13 08:04:26 +00007923#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007924#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +00007925 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007926#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007927 #ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007928 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007929 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007930 #ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007931 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007932 #endif
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007933#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007934 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007935#endif
7936#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007937 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007938#endif
7939#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007940 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007941#endif
7942#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007943 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007944#endif
7945
Victor Stinner8c62be82010-05-06 00:08:46 +00007946 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007947};
7948
7949
Barry Warsaw4a342091996-12-19 23:50:02 +00007950static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007951ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007952{
Victor Stinner8c62be82010-05-06 00:08:46 +00007953 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007954}
7955
Guido van Rossumd48f2521997-12-05 22:19:34 +00007956#if defined(PYOS_OS2)
7957/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007958static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007959{
7960 APIRET rc;
7961 ULONG values[QSV_MAX+1];
7962 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007963 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007964
7965 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007966 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007967 Py_END_ALLOW_THREADS
7968
7969 if (rc != NO_ERROR) {
7970 os2_error(rc);
7971 return -1;
7972 }
7973
Fred Drake4d1e64b2002-04-15 19:40:07 +00007974 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7975 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7976 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7977 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7978 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7979 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7980 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007981
7982 switch (values[QSV_VERSION_MINOR]) {
7983 case 0: ver = "2.00"; break;
7984 case 10: ver = "2.10"; break;
7985 case 11: ver = "2.11"; break;
7986 case 30: ver = "3.00"; break;
7987 case 40: ver = "4.00"; break;
7988 case 50: ver = "5.00"; break;
7989 default:
Tim Peters885d4572001-11-28 20:27:42 +00007990 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +00007991 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00007992 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007993 ver = &tmp[0];
7994 }
7995
7996 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007997 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007998 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007999
8000 /* Add Indicator of Which Drive was Used to Boot the System */
8001 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8002 tmp[1] = ':';
8003 tmp[2] = '\0';
8004
Fred Drake4d1e64b2002-04-15 19:40:07 +00008005 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008006}
8007#endif
8008
Barry Warsaw4a342091996-12-19 23:50:02 +00008009static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008010all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008011{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008012#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008013 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008014#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008015#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008016 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008017#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008018#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008019 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008020#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008021#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008022 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008023#endif
Fred Drakec9680921999-12-13 16:37:25 +00008024#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008025 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00008026#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008027#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008028 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008029#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008030#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00008031 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008032#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008033#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +00008034 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008035#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008036#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +00008037 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008038#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008039#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008040 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008041#endif
8042#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008043 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008044#endif
8045#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +00008046 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008047#endif
8048#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +00008049 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008050#endif
8051#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008052 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008053#endif
8054#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +00008055 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008056#endif
8057#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008058 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008059#endif
8060#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008061 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008062#endif
8063#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008064 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008065#endif
8066#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +00008067 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008068#endif
8069#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008070 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008071#endif
8072#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +00008073 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008074#endif
8075#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008076 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008077#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008078#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008079 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008080#endif
8081#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +00008082 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008083#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008084#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008085 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008086#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008087#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008088 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008089#endif
8090#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008091 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008092#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008093
Tim Peters5aa91602002-01-30 05:46:57 +00008094/* MS Windows */
8095#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008096 /* Don't inherit in child processes. */
8097 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008098#endif
8099#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +00008100 /* Optimize for short life (keep in memory). */
8101 /* MS forgot to define this one with a non-underscore form too. */
8102 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008103#endif
8104#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008105 /* Automatically delete when last handle is closed. */
8106 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008107#endif
8108#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +00008109 /* Optimize for random access. */
8110 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008111#endif
8112#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008113 /* Optimize for sequential access. */
8114 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008115#endif
8116
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008117/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008118#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008119 /* Send a SIGIO signal whenever input or output
8120 becomes available on file descriptor */
8121 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008122#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008123#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008124 /* Direct disk access. */
8125 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008126#endif
8127#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +00008128 /* Must be a directory. */
8129 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008130#endif
8131#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +00008132 /* Do not follow links. */
8133 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008134#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008135#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +00008136 /* Do not update the access time. */
8137 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008138#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008139
Victor Stinner8c62be82010-05-06 00:08:46 +00008140 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008141#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008142 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008143#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008144#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008145 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008146#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008147#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008148 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008149#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008150#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008151 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008152#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008153#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +00008154 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008155#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008156#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +00008157 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008158#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008159#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008160 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008161#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008162#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +00008163 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008164#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008165#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008166 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008167#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008168#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008169 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008170#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008171#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008172 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008173#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008174#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008175 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008176#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008177#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +00008178 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008179#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008180#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +00008181 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008182#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008183#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008184 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008185#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008186#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008187 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008188#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008189#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +00008190 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008191#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008192
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008193 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008194#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008195 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008196#endif /* ST_RDONLY */
8197#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008198 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008199#endif /* ST_NOSUID */
8200
Guido van Rossum246bc171999-02-01 23:54:31 +00008201#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008202#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00008203 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8204 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8205 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8206 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8207 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8208 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8209 if (ins(d, "P_PM", (long)P_PM)) return -1;
8210 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8211 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8212 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8213 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8214 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8215 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8216 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8217 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8218 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8219 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8220 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8221 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8222 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008223#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008224 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8225 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8226 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8227 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8228 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008229#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008230#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008231
Guido van Rossumd48f2521997-12-05 22:19:34 +00008232#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00008233 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008234#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008235 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00008236}
8237
8238
Tim Peters5aa91602002-01-30 05:46:57 +00008239#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008240#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008241#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008242
8243#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008244#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008245#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008246
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008247#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00008248#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008249#define MODNAME "posix"
8250#endif
8251
Martin v. Löwis1a214512008-06-11 05:26:20 +00008252static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +00008253 PyModuleDef_HEAD_INIT,
8254 MODNAME,
8255 posix__doc__,
8256 -1,
8257 posix_methods,
8258 NULL,
8259 NULL,
8260 NULL,
8261 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00008262};
8263
8264
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008265PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008266INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008267{
Victor Stinner8c62be82010-05-06 00:08:46 +00008268 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008269
Victor Stinner8c62be82010-05-06 00:08:46 +00008270 m = PyModule_Create(&posixmodule);
8271 if (m == NULL)
8272 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008273
Victor Stinner8c62be82010-05-06 00:08:46 +00008274 /* Initialize environ dictionary */
8275 v = convertenviron();
8276 Py_XINCREF(v);
8277 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
8278 return NULL;
8279 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008280
Victor Stinner8c62be82010-05-06 00:08:46 +00008281 if (all_ins(m))
8282 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00008283
Victor Stinner8c62be82010-05-06 00:08:46 +00008284 if (setup_confname_tables(m))
8285 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00008286
Victor Stinner8c62be82010-05-06 00:08:46 +00008287 Py_INCREF(PyExc_OSError);
8288 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008289
Guido van Rossumb3d39562000-01-31 18:41:26 +00008290#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00008291 if (posix_putenv_garbage == NULL)
8292 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008293#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008294
Victor Stinner8c62be82010-05-06 00:08:46 +00008295 if (!initialized) {
8296 stat_result_desc.name = MODNAME ".stat_result";
8297 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8298 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8299 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8300 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8301 structseq_new = StatResultType.tp_new;
8302 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008303
Victor Stinner8c62be82010-05-06 00:08:46 +00008304 statvfs_result_desc.name = MODNAME ".statvfs_result";
8305 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008306#ifdef NEED_TICKS_PER_SECOND
8307# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +00008308 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008309# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +00008310 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008311# else
Victor Stinner8c62be82010-05-06 00:08:46 +00008312 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008313# endif
8314#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008315 }
8316 Py_INCREF((PyObject*) &StatResultType);
8317 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
8318 Py_INCREF((PyObject*) &StatVFSResultType);
8319 PyModule_AddObject(m, "statvfs_result",
8320 (PyObject*) &StatVFSResultType);
8321 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008322
8323#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +00008324 /*
8325 * Step 2 of weak-linking support on Mac OS X.
8326 *
8327 * The code below removes functions that are not available on the
8328 * currently active platform.
8329 *
8330 * This block allow one to use a python binary that was build on
8331 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8332 * OSX 10.4.
8333 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008334#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008335 if (fstatvfs == NULL) {
8336 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8337 return NULL;
8338 }
8339 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008340#endif /* HAVE_FSTATVFS */
8341
8342#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008343 if (statvfs == NULL) {
8344 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8345 return NULL;
8346 }
8347 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008348#endif /* HAVE_STATVFS */
8349
8350# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00008351 if (lchown == NULL) {
8352 if (PyObject_DelAttrString(m, "lchown") == -1) {
8353 return NULL;
8354 }
8355 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008356#endif /* HAVE_LCHOWN */
8357
8358
8359#endif /* __APPLE__ */
Victor Stinner8c62be82010-05-06 00:08:46 +00008360 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008361
Guido van Rossumb6775db1994-08-01 11:34:53 +00008362}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008363
8364#ifdef __cplusplus
8365}
8366#endif