blob: 3197a0d2d8dfb8ebaf439738788fd85a0214b8ce [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
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000125#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000126#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000127#define HAVE_EXECV 1
128#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000129#define HAVE_SYSTEM 1
130#define HAVE_CWAIT 1
131#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000132#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000133#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000134#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
135/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000136#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000137/* Unix functions that the configure script doesn't check for */
138#define HAVE_EXECV 1
139#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000140#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000141#define HAVE_FORK1 1
142#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000143#define HAVE_GETCWD 1
144#define HAVE_GETEGID 1
145#define HAVE_GETEUID 1
146#define HAVE_GETGID 1
147#define HAVE_GETPPID 1
148#define HAVE_GETUID 1
149#define HAVE_KILL 1
150#define HAVE_OPENDIR 1
151#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000152#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000154#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000155#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000156#endif /* _MSC_VER */
157#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000158#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000159#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000160
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000161#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000162
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000163#if defined(__sgi)&&_COMPILER_VERSION>=700
164/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
165 (default) */
166extern char *ctermid_r(char *);
167#endif
168
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000169#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000170#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000171extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000172#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000173#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000174extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000176extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000177#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000178#endif
179#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000180extern int chdir(char *);
181extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000182#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000183extern int chdir(const char *);
184extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000185#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000186#ifdef __BORLANDC__
187extern int chmod(const char *, int);
188#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000189extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000190#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000191/*#ifdef HAVE_FCHMOD
192extern int fchmod(int, mode_t);
193#endif*/
194/*#ifdef HAVE_LCHMOD
195extern int lchmod(const char *, mode_t);
196#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000197extern int chown(const char *, uid_t, gid_t);
198extern char *getcwd(char *, int);
199extern char *strerror(int);
200extern int link(const char *, const char *);
201extern int rename(const char *, const char *);
202extern int stat(const char *, struct stat *);
203extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000204#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000205extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000206#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000207#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000208extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000209#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000210#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000211
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000212#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000213
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#ifdef HAVE_UTIME_H
215#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000216#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000218#ifdef HAVE_SYS_UTIME_H
219#include <sys/utime.h>
220#define HAVE_UTIME_H /* pretend we do for the rest of this file */
221#endif /* HAVE_SYS_UTIME_H */
222
Guido van Rossumb6775db1994-08-01 11:34:53 +0000223#ifdef HAVE_SYS_TIMES_H
224#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000225#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226
227#ifdef HAVE_SYS_PARAM_H
228#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000229#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000230
231#ifdef HAVE_SYS_UTSNAME_H
232#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000233#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000235#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000236#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000237#define NAMLEN(dirent) strlen((dirent)->d_name)
238#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000239#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000240#include <direct.h>
241#define NAMLEN(dirent) strlen((dirent)->d_name)
242#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000244#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000245#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000246#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000248#endif
249#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000250#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000251#endif
252#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000253#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000254#endif
255#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000257#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000258#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000259#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000260#endif
261#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000263#endif
264#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000266#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000267#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000268#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000269#endif
270#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000271#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000272#endif
273#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000274#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000275#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000276#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000277#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000279#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000280#include <lmcons.h> /* for UNLEN */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000281#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282
Guido van Rossumd48f2521997-12-05 22:19:34 +0000283#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000285#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000286
Tim Petersbc2e10e2002-03-03 23:17:02 +0000287#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000288#if defined(PATH_MAX) && PATH_MAX > 1024
289#define MAXPATHLEN PATH_MAX
290#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000291#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000292#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000293#endif /* MAXPATHLEN */
294
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000295#ifdef UNION_WAIT
296/* Emulate some macros on systems that have a union instead of macros */
297
298#ifndef WIFEXITED
299#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
300#endif
301
302#ifndef WEXITSTATUS
303#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
304#endif
305
306#ifndef WTERMSIG
307#define WTERMSIG(u_wait) ((u_wait).w_termsig)
308#endif
309
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000310#define WAIT_TYPE union wait
311#define WAIT_STATUS_INT(s) (s.w_status)
312
313#else /* !UNION_WAIT */
314#define WAIT_TYPE int
315#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000316#endif /* UNION_WAIT */
317
Greg Wardb48bc172000-03-01 21:51:56 +0000318/* Don't use the "_r" form if we don't need it (also, won't have a
319 prototype for it, at least on Solaris -- maybe others as well?). */
320#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
321#define USE_CTERMID_R
322#endif
323
Fred Drake699f3522000-06-29 21:12:41 +0000324/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000325#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000326#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000327# define STAT win32_stat
328# define FSTAT win32_fstat
329# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000330#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000331# define STAT stat
332# define FSTAT fstat
333# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000334#endif
335
Tim Peters11b23062003-04-23 02:39:17 +0000336#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000337#include <sys/mkdev.h>
338#else
339#if defined(MAJOR_IN_SYSMACROS)
340#include <sys/sysmacros.h>
341#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000342#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
343#include <sys/mkdev.h>
344#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000345#endif
Fred Drake699f3522000-06-29 21:12:41 +0000346
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000347#if defined _MSC_VER && _MSC_VER >= 1400
348/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
349 * valid and throw an assertion if it isn't.
350 * Normally, an invalid fd is likely to be a C program error and therefore
351 * an assertion can be useful, but it does contradict the POSIX standard
352 * which for write(2) states:
353 * "Otherwise, -1 shall be returned and errno set to indicate the error."
354 * "[EBADF] The fildes argument is not a valid file descriptor open for
355 * writing."
356 * Furthermore, python allows the user to enter any old integer
357 * as a fd and should merely raise a python exception on error.
358 * The Microsoft CRT doesn't provide an official way to check for the
359 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000360 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000361 * internal structures involved.
362 * The structures below must be updated for each version of visual studio
363 * according to the file internal.h in the CRT source, until MS comes
364 * up with a less hacky way to do this.
365 * (all of this is to avoid globally modifying the CRT behaviour using
366 * _set_invalid_parameter_handler() and _CrtSetReportMode())
367 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000368/* The actual size of the structure is determined at runtime.
369 * Only the first items must be present.
370 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000371typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000372 intptr_t osfhnd;
373 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000374} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000375
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000376extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000377#define IOINFO_L2E 5
378#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
379#define IOINFO_ARRAYS 64
380#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
381#define FOPEN 0x01
382#define _NO_CONSOLE_FILENO (intptr_t)-2
383
384/* This function emulates what the windows CRT does to validate file handles */
385int
386_PyVerify_fd(int fd)
387{
Victor Stinner8c62be82010-05-06 00:08:46 +0000388 const int i1 = fd >> IOINFO_L2E;
389 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000390
Antoine Pitrou22e41552010-08-15 18:07:50 +0000391 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000392
Victor Stinner8c62be82010-05-06 00:08:46 +0000393 /* Determine the actual size of the ioinfo structure,
394 * as used by the CRT loaded in memory
395 */
396 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
397 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
398 }
399 if (sizeof_ioinfo == 0) {
400 /* This should not happen... */
401 goto fail;
402 }
403
404 /* See that it isn't a special CLEAR fileno */
405 if (fd != _NO_CONSOLE_FILENO) {
406 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
407 * we check pointer validity and other info
408 */
409 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
410 /* finally, check that the file is open */
411 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
412 if (info->osfile & FOPEN) {
413 return 1;
414 }
415 }
416 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000417 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000418 errno = EBADF;
419 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000420}
421
422/* the special case of checking dup2. The target fd must be in a sensible range */
423static int
424_PyVerify_fd_dup2(int fd1, int fd2)
425{
Victor Stinner8c62be82010-05-06 00:08:46 +0000426 if (!_PyVerify_fd(fd1))
427 return 0;
428 if (fd2 == _NO_CONSOLE_FILENO)
429 return 0;
430 if ((unsigned)fd2 < _NHANDLE_)
431 return 1;
432 else
433 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000434}
435#else
436/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
437#define _PyVerify_fd_dup2(A, B) (1)
438#endif
439
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000440#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000441/* The following structure was copied from
442 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
443 include doesn't seem to be present in the Windows SDK (at least as included
444 with Visual Studio Express). */
445typedef struct _REPARSE_DATA_BUFFER {
446 ULONG ReparseTag;
447 USHORT ReparseDataLength;
448 USHORT Reserved;
449 union {
450 struct {
451 USHORT SubstituteNameOffset;
452 USHORT SubstituteNameLength;
453 USHORT PrintNameOffset;
454 USHORT PrintNameLength;
455 ULONG Flags;
456 WCHAR PathBuffer[1];
457 } SymbolicLinkReparseBuffer;
458
459 struct {
460 USHORT SubstituteNameOffset;
461 USHORT SubstituteNameLength;
462 USHORT PrintNameOffset;
463 USHORT PrintNameLength;
464 WCHAR PathBuffer[1];
465 } MountPointReparseBuffer;
466
467 struct {
468 UCHAR DataBuffer[1];
469 } GenericReparseBuffer;
470 };
471} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
472
473#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
474 GenericReparseBuffer)
475#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
476
477static int
478_Py_ReadLink(HANDLE reparse_point_handle, ULONG *reparse_tag, wchar_t **target_path)
479{
480 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
481 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
482 DWORD n_bytes_returned;
483 const wchar_t *ptr;
484 wchar_t *buf;
485 size_t len;
486
487 if (0 == DeviceIoControl(
488 reparse_point_handle,
489 FSCTL_GET_REPARSE_POINT,
490 NULL, 0, /* in buffer */
491 target_buffer, sizeof(target_buffer),
492 &n_bytes_returned,
493 NULL)) /* we're not using OVERLAPPED_IO */
494 return 0;
495
496 if (reparse_tag)
497 *reparse_tag = rdb->ReparseTag;
498
499 if (target_path) {
500 switch (rdb->ReparseTag) {
501 case IO_REPARSE_TAG_SYMLINK:
502 /* XXX: Maybe should use SubstituteName? */
503 ptr = rdb->SymbolicLinkReparseBuffer.PathBuffer +
504 rdb->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR);
505 len = rdb->SymbolicLinkReparseBuffer.PrintNameLength/sizeof(WCHAR);
506 break;
507 case IO_REPARSE_TAG_MOUNT_POINT:
508 ptr = rdb->MountPointReparseBuffer.PathBuffer +
509 rdb->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR);
510 len = rdb->MountPointReparseBuffer.SubstituteNameLength/sizeof(WCHAR);
511 break;
512 default:
513 SetLastError(ERROR_REPARSE_TAG_MISMATCH); /* XXX: Proper error code? */
514 return 0;
515 }
516 buf = (wchar_t *)malloc(sizeof(wchar_t)*(len+1));
517 if (!buf) {
518 SetLastError(ERROR_OUTOFMEMORY);
519 return 0;
520 }
521 wcsncpy(buf, ptr, len);
522 buf[len] = L'\0';
523 if (wcsncmp(buf, L"\\??\\", 4) == 0)
524 buf[1] = L'\\';
525 *target_path = buf;
526 }
527
528 return 1;
529}
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000530#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000531
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000532/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000533#ifdef WITH_NEXT_FRAMEWORK
534/* On Darwin/MacOSX a shared library or framework has no access to
535** environ directly, we must obtain it with _NSGetEnviron().
536*/
537#include <crt_externs.h>
538static char **environ;
539#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000540extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000541#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000542
Barry Warsaw53699e91996-12-10 23:23:01 +0000543static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000544convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000545{
Victor Stinner8c62be82010-05-06 00:08:46 +0000546 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000547#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000548 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000549#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000550 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000551#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000552#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000553 APIRET rc;
554 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
555#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000556
Victor Stinner8c62be82010-05-06 00:08:46 +0000557 d = PyDict_New();
558 if (d == NULL)
559 return NULL;
560#ifdef WITH_NEXT_FRAMEWORK
561 if (environ == NULL)
562 environ = *_NSGetEnviron();
563#endif
564#ifdef MS_WINDOWS
565 /* _wenviron must be initialized in this way if the program is started
566 through main() instead of wmain(). */
567 _wgetenv(L"");
568 if (_wenviron == NULL)
569 return d;
570 /* This part ignores errors */
571 for (e = _wenviron; *e != NULL; e++) {
572 PyObject *k;
573 PyObject *v;
574 wchar_t *p = wcschr(*e, L'=');
575 if (p == NULL)
576 continue;
577 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
578 if (k == NULL) {
579 PyErr_Clear();
580 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000581 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000582 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
583 if (v == NULL) {
584 PyErr_Clear();
585 Py_DECREF(k);
586 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000587 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000588 if (PyDict_GetItem(d, k) == NULL) {
589 if (PyDict_SetItem(d, k, v) != 0)
590 PyErr_Clear();
591 }
592 Py_DECREF(k);
593 Py_DECREF(v);
594 }
595#else
596 if (environ == NULL)
597 return d;
598 /* This part ignores errors */
599 for (e = environ; *e != NULL; e++) {
600 PyObject *k;
601 PyObject *v;
602 char *p = strchr(*e, '=');
603 if (p == NULL)
604 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000605 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000606 if (k == NULL) {
607 PyErr_Clear();
608 continue;
609 }
Victor Stinner84ae1182010-05-06 22:05:07 +0000610 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +0000611 if (v == NULL) {
612 PyErr_Clear();
613 Py_DECREF(k);
614 continue;
615 }
616 if (PyDict_GetItem(d, k) == NULL) {
617 if (PyDict_SetItem(d, k, v) != 0)
618 PyErr_Clear();
619 }
620 Py_DECREF(k);
621 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000622 }
623#endif
Victor Stinner8c62be82010-05-06 00:08:46 +0000624#if defined(PYOS_OS2)
625 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
626 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
627 PyObject *v = PyBytes_FromString(buffer);
628 PyDict_SetItemString(d, "BEGINLIBPATH", v);
629 Py_DECREF(v);
630 }
631 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
632 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
633 PyObject *v = PyBytes_FromString(buffer);
634 PyDict_SetItemString(d, "ENDLIBPATH", v);
635 Py_DECREF(v);
636 }
637#endif
638 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000639}
640
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000641/* Set a POSIX-specific error from errno, and return NULL */
642
Barry Warsawd58d7641998-07-23 16:14:40 +0000643static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000644posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000645{
Victor Stinner8c62be82010-05-06 00:08:46 +0000646 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000647}
Barry Warsawd58d7641998-07-23 16:14:40 +0000648static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000649posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000650{
Victor Stinner8c62be82010-05-06 00:08:46 +0000651 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000652}
653
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000654
Mark Hammondef8b6542001-05-13 08:04:26 +0000655static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000656posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000657{
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000658 PyObject *name_str, *rc;
659 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
660 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +0000661 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000662 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
663 name_str);
664 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +0000665 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000666}
667
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000668#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000669static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +0000670win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000671{
Victor Stinner8c62be82010-05-06 00:08:46 +0000672 /* XXX We should pass the function name along in the future.
673 (winreg.c also wants to pass the function name.)
674 This would however require an additional param to the
675 Windows error object, which is non-trivial.
676 */
677 errno = GetLastError();
678 if (filename)
679 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
680 else
681 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000682}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000683
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000684static PyObject *
685win32_error_unicode(char* function, Py_UNICODE* filename)
686{
Victor Stinner8c62be82010-05-06 00:08:46 +0000687 /* XXX - see win32_error for comments on 'function' */
688 errno = GetLastError();
689 if (filename)
690 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
691 else
692 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000693}
694
Thomas Wouters477c8d52006-05-27 19:21:47 +0000695static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000696convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000697{
Victor Stinner8c62be82010-05-06 00:08:46 +0000698 if (PyUnicode_CheckExact(*param))
699 Py_INCREF(*param);
700 else if (PyUnicode_Check(*param))
701 /* For a Unicode subtype that's not a Unicode object,
702 return a true Unicode object with the same data. */
703 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
704 PyUnicode_GET_SIZE(*param));
705 else
706 *param = PyUnicode_FromEncodedObject(*param,
707 Py_FileSystemDefaultEncoding,
708 "strict");
709 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000710}
711
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000712#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000713
Guido van Rossumd48f2521997-12-05 22:19:34 +0000714#if defined(PYOS_OS2)
715/**********************************************************************
716 * Helper Function to Trim and Format OS/2 Messages
717 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000718static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000719os2_formatmsg(char *msgbuf, int msglen, char *reason)
720{
721 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
722
723 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
724 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
725
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000726 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000727 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
728 }
729
730 /* Add Optional Reason Text */
731 if (reason) {
732 strcat(msgbuf, " : ");
733 strcat(msgbuf, reason);
734 }
735}
736
737/**********************************************************************
738 * Decode an OS/2 Operating System Error Code
739 *
740 * A convenience function to lookup an OS/2 error code and return a
741 * text message we can use to raise a Python exception.
742 *
743 * Notes:
744 * The messages for errors returned from the OS/2 kernel reside in
745 * the file OSO001.MSG in the \OS2 directory hierarchy.
746 *
747 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000748static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000749os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
750{
751 APIRET rc;
752 ULONG msglen;
753
754 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
755 Py_BEGIN_ALLOW_THREADS
756 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
757 errorcode, "oso001.msg", &msglen);
758 Py_END_ALLOW_THREADS
759
760 if (rc == NO_ERROR)
761 os2_formatmsg(msgbuf, msglen, reason);
762 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000763 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +0000764 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000765
766 return msgbuf;
767}
768
769/* Set an OS/2-specific error and return NULL. OS/2 kernel
770 errors are not in a global variable e.g. 'errno' nor are
771 they congruent with posix error numbers. */
772
Victor Stinner8c62be82010-05-06 00:08:46 +0000773static PyObject *
774os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000775{
776 char text[1024];
777 PyObject *v;
778
779 os2_strerror(text, sizeof(text), code, "");
780
781 v = Py_BuildValue("(is)", code, text);
782 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000783 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000784 Py_DECREF(v);
785 }
786 return NULL; /* Signal to Python that an Exception is Pending */
787}
788
789#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000790
791/* POSIX generic methods */
792
Barry Warsaw53699e91996-12-10 23:23:01 +0000793static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000794posix_fildes(PyObject *fdobj, int (*func)(int))
795{
Victor Stinner8c62be82010-05-06 00:08:46 +0000796 int fd;
797 int res;
798 fd = PyObject_AsFileDescriptor(fdobj);
799 if (fd < 0)
800 return NULL;
801 if (!_PyVerify_fd(fd))
802 return posix_error();
803 Py_BEGIN_ALLOW_THREADS
804 res = (*func)(fd);
805 Py_END_ALLOW_THREADS
806 if (res < 0)
807 return posix_error();
808 Py_INCREF(Py_None);
809 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000810}
Guido van Rossum21142a01999-01-08 21:05:37 +0000811
812static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000813posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000814{
Victor Stinner8c62be82010-05-06 00:08:46 +0000815 PyObject *opath1 = NULL;
816 char *path1;
817 int res;
818 if (!PyArg_ParseTuple(args, format,
819 PyUnicode_FSConverter, &opath1))
820 return NULL;
821 path1 = PyBytes_AsString(opath1);
822 Py_BEGIN_ALLOW_THREADS
823 res = (*func)(path1);
824 Py_END_ALLOW_THREADS
825 if (res < 0)
826 return posix_error_with_allocated_filename(opath1);
827 Py_DECREF(opath1);
828 Py_INCREF(Py_None);
829 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000830}
831
Barry Warsaw53699e91996-12-10 23:23:01 +0000832static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000833posix_2str(PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +0000834 char *format,
835 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000836{
Victor Stinner8c62be82010-05-06 00:08:46 +0000837 PyObject *opath1 = NULL, *opath2 = NULL;
838 char *path1, *path2;
839 int res;
840 if (!PyArg_ParseTuple(args, format,
841 PyUnicode_FSConverter, &opath1,
842 PyUnicode_FSConverter, &opath2)) {
843 return NULL;
844 }
845 path1 = PyBytes_AsString(opath1);
846 path2 = PyBytes_AsString(opath2);
847 Py_BEGIN_ALLOW_THREADS
848 res = (*func)(path1, path2);
849 Py_END_ALLOW_THREADS
850 Py_DECREF(opath1);
851 Py_DECREF(opath2);
852 if (res != 0)
853 /* XXX how to report both path1 and path2??? */
854 return posix_error();
855 Py_INCREF(Py_None);
856 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000857}
858
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000859#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000860static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +0000861win32_1str(PyObject* args, char* func,
862 char* format, BOOL (__stdcall *funcA)(LPCSTR),
863 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000864{
Victor Stinner8c62be82010-05-06 00:08:46 +0000865 PyObject *uni;
866 char *ansi;
867 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +0000868
Victor Stinner8c62be82010-05-06 00:08:46 +0000869 if (!PyArg_ParseTuple(args, wformat, &uni))
870 PyErr_Clear();
871 else {
872 Py_BEGIN_ALLOW_THREADS
873 result = funcW(PyUnicode_AsUnicode(uni));
874 Py_END_ALLOW_THREADS
875 if (!result)
876 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
877 Py_INCREF(Py_None);
878 return Py_None;
879 }
880 if (!PyArg_ParseTuple(args, format, &ansi))
881 return NULL;
882 Py_BEGIN_ALLOW_THREADS
883 result = funcA(ansi);
884 Py_END_ALLOW_THREADS
885 if (!result)
886 return win32_error(func, ansi);
887 Py_INCREF(Py_None);
888 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000889
890}
891
892/* This is a reimplementation of the C library's chdir function,
893 but one that produces Win32 errors instead of DOS error codes.
894 chdir is essentially a wrapper around SetCurrentDirectory; however,
895 it also needs to set "magic" environment variables indicating
896 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000897static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000898win32_chdir(LPCSTR path)
899{
Victor Stinner8c62be82010-05-06 00:08:46 +0000900 char new_path[MAX_PATH+1];
901 int result;
902 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000903
Victor Stinner8c62be82010-05-06 00:08:46 +0000904 if(!SetCurrentDirectoryA(path))
905 return FALSE;
906 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
907 if (!result)
908 return FALSE;
909 /* In the ANSI API, there should not be any paths longer
910 than MAX_PATH. */
911 assert(result <= MAX_PATH+1);
912 if (strncmp(new_path, "\\\\", 2) == 0 ||
913 strncmp(new_path, "//", 2) == 0)
914 /* UNC path, nothing to do. */
915 return TRUE;
916 env[1] = new_path[0];
917 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000918}
919
920/* The Unicode version differs from the ANSI version
921 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000922static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000923win32_wchdir(LPCWSTR path)
924{
Victor Stinner8c62be82010-05-06 00:08:46 +0000925 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
926 int result;
927 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000928
Victor Stinner8c62be82010-05-06 00:08:46 +0000929 if(!SetCurrentDirectoryW(path))
930 return FALSE;
931 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
932 if (!result)
933 return FALSE;
934 if (result > MAX_PATH+1) {
935 new_path = malloc(result * sizeof(wchar_t));
936 if (!new_path) {
937 SetLastError(ERROR_OUTOFMEMORY);
938 return FALSE;
939 }
940 result = GetCurrentDirectoryW(result, new_path);
941 if (!result) {
942 free(new_path);
943 return FALSE;
944 }
945 }
946 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
947 wcsncmp(new_path, L"//", 2) == 0)
948 /* UNC path, nothing to do. */
949 return TRUE;
950 env[1] = new_path[0];
951 result = SetEnvironmentVariableW(env, new_path);
952 if (new_path != _new_path)
953 free(new_path);
954 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000955}
956#endif
957
Martin v. Löwis14694662006-02-03 12:54:16 +0000958#ifdef MS_WINDOWS
959/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
960 - time stamps are restricted to second resolution
961 - file modification times suffer from forth-and-back conversions between
962 UTC and local time
963 Therefore, we implement our own stat, based on the Win32 API directly.
964*/
Victor Stinner8c62be82010-05-06 00:08:46 +0000965#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +0000966
967struct win32_stat{
968 int st_dev;
969 __int64 st_ino;
970 unsigned short st_mode;
971 int st_nlink;
972 int st_uid;
973 int st_gid;
974 int st_rdev;
975 __int64 st_size;
976 int st_atime;
977 int st_atime_nsec;
978 int st_mtime;
979 int st_mtime_nsec;
980 int st_ctime;
981 int st_ctime_nsec;
982};
983
984static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
985
986static void
987FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
988{
Victor Stinner8c62be82010-05-06 00:08:46 +0000989 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
990 /* Cannot simply cast and dereference in_ptr,
991 since it might not be aligned properly */
992 __int64 in;
993 memcpy(&in, in_ptr, sizeof(in));
994 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
995 /* XXX Win32 supports time stamps past 2038; we currently don't */
996 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
Martin v. Löwis14694662006-02-03 12:54:16 +0000997}
998
Thomas Wouters477c8d52006-05-27 19:21:47 +0000999static void
1000time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
1001{
Victor Stinner8c62be82010-05-06 00:08:46 +00001002 /* XXX endianness */
1003 __int64 out;
1004 out = time_in + secs_between_epochs;
1005 out = out * 10000000 + nsec_in / 100;
1006 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001007}
1008
Martin v. Löwis14694662006-02-03 12:54:16 +00001009/* Below, we *know* that ugo+r is 0444 */
1010#if _S_IREAD != 0400
1011#error Unsupported C library
1012#endif
1013static int
1014attributes_to_mode(DWORD attr)
1015{
Victor Stinner8c62be82010-05-06 00:08:46 +00001016 int m = 0;
1017 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1018 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1019 else
1020 m |= _S_IFREG;
1021 if (attr & FILE_ATTRIBUTE_READONLY)
1022 m |= 0444;
1023 else
1024 m |= 0666;
1025 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001026}
1027
1028static int
Brian Curtinf5e76d02010-11-24 13:14:05 +00001029attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001030{
Victor Stinner8c62be82010-05-06 00:08:46 +00001031 memset(result, 0, sizeof(*result));
1032 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1033 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1034 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1035 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1036 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001037 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001038 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Martin v. Löwis14694662006-02-03 12:54:16 +00001039
Victor Stinner8c62be82010-05-06 00:08:46 +00001040 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001041}
1042
Guido van Rossumd8faa362007-04-27 19:54:29 +00001043static BOOL
Brian Curtinf5e76d02010-11-24 13:14:05 +00001044attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001045{
Victor Stinner8c62be82010-05-06 00:08:46 +00001046 HANDLE hFindFile;
1047 WIN32_FIND_DATAA FileData;
1048 hFindFile = FindFirstFileA(pszFile, &FileData);
1049 if (hFindFile == INVALID_HANDLE_VALUE)
1050 return FALSE;
1051 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001052 memset(info, 0, sizeof(*info));
1053 info->dwFileAttributes = FileData.dwFileAttributes;
1054 info->ftCreationTime = FileData.ftCreationTime;
1055 info->ftLastAccessTime = FileData.ftLastAccessTime;
1056 info->ftLastWriteTime = FileData.ftLastWriteTime;
1057 info->nFileSizeHigh = FileData.nFileSizeHigh;
1058 info->nFileSizeLow = FileData.nFileSizeLow;
1059/* info->nNumberOfLinks = 1; */
Victor Stinner8c62be82010-05-06 00:08:46 +00001060 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001061}
1062
1063static BOOL
Brian Curtinf5e76d02010-11-24 13:14:05 +00001064attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001065{
Victor Stinner8c62be82010-05-06 00:08:46 +00001066 HANDLE hFindFile;
1067 WIN32_FIND_DATAW FileData;
1068 hFindFile = FindFirstFileW(pszFile, &FileData);
1069 if (hFindFile == INVALID_HANDLE_VALUE)
1070 return FALSE;
1071 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001072 memset(info, 0, sizeof(*info));
1073 info->dwFileAttributes = FileData.dwFileAttributes;
1074 info->ftCreationTime = FileData.ftCreationTime;
1075 info->ftLastAccessTime = FileData.ftLastAccessTime;
1076 info->ftLastWriteTime = FileData.ftLastWriteTime;
1077 info->nFileSizeHigh = FileData.nFileSizeHigh;
1078 info->nFileSizeLow = FileData.nFileSizeLow;
1079/* info->nNumberOfLinks = 1; */
Victor Stinner8c62be82010-05-06 00:08:46 +00001080 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001081}
1082
Brian Curtinf5e76d02010-11-24 13:14:05 +00001083#ifndef SYMLOOP_MAX
1084#define SYMLOOP_MAX ( 88 )
1085#endif
1086
1087static int
1088win32_xstat_for_handle(HANDLE hFile, struct win32_stat *result, BOOL traverse, int depth);
1089
1090static int
1091win32_xstat(const char *path, struct win32_stat *result, BOOL traverse, int depth)
1092{
1093 int code;
1094 HANDLE hFile;
1095 BY_HANDLE_FILE_INFORMATION info;
1096 const char *dot;
1097
1098 hFile = CreateFileA(
1099 path,
1100 0, /* desired access */
1101 0, /* share mode */
1102 NULL, /* security attributes */
1103 OPEN_EXISTING,
1104 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
1105 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT,
1106 NULL);
1107
1108 if(hFile == INVALID_HANDLE_VALUE) {
1109 /* Either the target doesn't exist, or we don't have access to
1110 get a handle to it. If the former, we need to return an error.
1111 If the latter, we can use attributes_from_dir. */
1112 if (GetLastError() != ERROR_SHARING_VIOLATION)
1113 goto err;
1114 else {
1115 /* Could not get attributes on open file. Fall back to
1116 reading the directory. */
1117 if (!attributes_from_dir(path, &info))
1118 /* Very strange. This should not fail now */
1119 goto err;
1120 if (traverse && (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
1121 /* Should traverse, but cannot open reparse point handle */
1122 SetLastError(ERROR_SHARING_VIOLATION);
1123 goto err;
1124 }
1125 attribute_data_to_stat(&info, result);
1126 }
1127 }
1128 else {
1129 code = win32_xstat_for_handle(hFile, result, traverse, depth);
1130 CloseHandle(hFile);
1131 if (code != 0)
1132 return code;
1133 }
1134
1135 /* Set S_IEXEC if it is an .exe, .bat, ... */
1136 dot = strrchr(path, '.');
1137 if (dot) {
1138 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1139 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1140 result->st_mode |= 0111;
1141 }
1142 return 0;
1143
1144err:
1145 /* Protocol violation: we explicitly clear errno, instead of
1146 setting it to a POSIX error. Callers should use GetLastError. */
1147 errno = 0;
1148 return -1;
1149}
1150
1151static int
1152win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse, int depth)
1153{
1154 int code;
1155 HANDLE hFile;
1156 BY_HANDLE_FILE_INFORMATION info;
1157 const wchar_t *dot;
1158
1159 hFile = CreateFileW(
1160 path,
1161 0, /* desired access */
1162 0, /* share mode */
1163 NULL, /* security attributes */
1164 OPEN_EXISTING,
1165 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
1166 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT,
1167 NULL);
1168
1169 if(hFile == INVALID_HANDLE_VALUE) {
1170 /* Either the target doesn't exist, or we don't have access to
1171 get a handle to it. If the former, we need to return an error.
1172 If the latter, we can use attributes_from_dir. */
1173 if (GetLastError() != ERROR_SHARING_VIOLATION)
1174 goto err;
1175 else {
1176 /* Could not get attributes on open file. Fall back to
1177 reading the directory. */
1178 if (!attributes_from_dir_w(path, &info))
1179 /* Very strange. This should not fail now */
1180 goto err;
1181 if (traverse && (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
1182 /* Should traverse, but cannot open reparse point handle */
1183 SetLastError(ERROR_SHARING_VIOLATION);
1184 goto err;
1185 }
1186 attribute_data_to_stat(&info, result);
1187 }
1188 }
1189 else {
1190 code = win32_xstat_for_handle(hFile, result, traverse, depth);
1191 CloseHandle(hFile);
1192 if (code != 0)
1193 return code;
1194 }
1195
1196 /* Set S_IEXEC if it is an .exe, .bat, ... */
1197 dot = wcsrchr(path, '.');
1198 if (dot) {
1199 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1200 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1201 result->st_mode |= 0111;
1202 }
1203 return 0;
1204
1205err:
1206 /* Protocol violation: we explicitly clear errno, instead of
1207 setting it to a POSIX error. Callers should use GetLastError. */
1208 errno = 0;
1209 return -1;
1210}
1211
1212static int
1213win32_xstat_for_handle(HANDLE hFile, struct win32_stat *result, BOOL traverse, int depth)
1214{
1215 int code;
1216 BOOL reparse_tag;
1217 wchar_t *target_path;
1218 BY_HANDLE_FILE_INFORMATION info;
1219
1220 if (!GetFileInformationByHandle(hFile, &info))
1221 return -1;
1222
1223 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1224 if (traverse) {
1225 if (depth + 1 > SYMLOOP_MAX) {
1226 SetLastError(ERROR_CANT_RESOLVE_FILENAME); /* XXX: ELOOP? */
1227 return -1;
1228 }
1229 if (!_Py_ReadLink(hFile, NULL, &target_path))
1230 return -1;
1231 code = win32_xstat_w(target_path, result, traverse, depth + 1);
1232 free(target_path);
1233 return code;
1234 } else {
1235 if (!_Py_ReadLink(hFile, &reparse_tag, NULL))
1236 return -1;
1237 attribute_data_to_stat(&info, result);
1238 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1239 /* first clear the S_IFMT bits */
1240 result->st_mode ^= (result->st_mode & 0170000);
1241 /* now set the bits that make this a symlink */
1242 result->st_mode |= 0120000;
1243 }
1244 }
1245 } else {
1246 attribute_data_to_stat(&info, result);
1247 }
1248 return 0;
1249}
1250
Brian Curtind40e6f72010-07-08 21:39:08 +00001251/* About the following functions: win32_lstat, win32_lstat_w, win32_stat,
1252 win32_stat_w
1253
1254 In Posix, stat automatically traverses symlinks and returns the stat
1255 structure for the target. In Windows, the equivalent GetFileAttributes by
1256 default does not traverse symlinks and instead returns attributes for
1257 the symlink.
1258
1259 Therefore, win32_lstat will get the attributes traditionally, and
1260 win32_stat will first explicitly resolve the symlink target and then will
1261 call win32_lstat on that result.
1262
1263 The _w represent Unicode equivalents of the aformentioned ANSI functions. */
1264
1265static int
1266win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001267{
Brian Curtinf5e76d02010-11-24 13:14:05 +00001268 return win32_xstat(path, result, FALSE, 0);
Martin v. Löwis14694662006-02-03 12:54:16 +00001269}
1270
Victor Stinner8c62be82010-05-06 00:08:46 +00001271static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001272win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001273{
Brian Curtinf5e76d02010-11-24 13:14:05 +00001274 return win32_xstat_w(path, result, FALSE, 0);
Brian Curtind40e6f72010-07-08 21:39:08 +00001275}
1276
1277static int
1278win32_stat(const char* path, struct win32_stat *result)
1279{
Brian Curtinf5e76d02010-11-24 13:14:05 +00001280 return win32_xstat(path, result, TRUE, 0);
Brian Curtind40e6f72010-07-08 21:39:08 +00001281}
1282
1283static int
1284win32_stat_w(const wchar_t* path, struct win32_stat *result)
1285{
Brian Curtinf5e76d02010-11-24 13:14:05 +00001286 return win32_xstat_w(path, result, TRUE, 0);
Martin v. Löwis14694662006-02-03 12:54:16 +00001287}
1288
1289static int
1290win32_fstat(int file_number, struct win32_stat *result)
1291{
Victor Stinner8c62be82010-05-06 00:08:46 +00001292 BY_HANDLE_FILE_INFORMATION info;
1293 HANDLE h;
1294 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001295
Victor Stinner8c62be82010-05-06 00:08:46 +00001296 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001297
Victor Stinner8c62be82010-05-06 00:08:46 +00001298 /* Protocol violation: we explicitly clear errno, instead of
1299 setting it to a POSIX error. Callers should use GetLastError. */
1300 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001301
Victor Stinner8c62be82010-05-06 00:08:46 +00001302 if (h == INVALID_HANDLE_VALUE) {
1303 /* This is really a C library error (invalid file handle).
1304 We set the Win32 error to the closes one matching. */
1305 SetLastError(ERROR_INVALID_HANDLE);
1306 return -1;
1307 }
1308 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001309
Victor Stinner8c62be82010-05-06 00:08:46 +00001310 type = GetFileType(h);
1311 if (type == FILE_TYPE_UNKNOWN) {
1312 DWORD error = GetLastError();
1313 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001314 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001315 }
1316 /* else: valid but unknown file */
1317 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001318
Victor Stinner8c62be82010-05-06 00:08:46 +00001319 if (type != FILE_TYPE_DISK) {
1320 if (type == FILE_TYPE_CHAR)
1321 result->st_mode = _S_IFCHR;
1322 else if (type == FILE_TYPE_PIPE)
1323 result->st_mode = _S_IFIFO;
1324 return 0;
1325 }
1326
1327 if (!GetFileInformationByHandle(h, &info)) {
1328 return -1;
1329 }
1330
Brian Curtinf5e76d02010-11-24 13:14:05 +00001331 attribute_data_to_stat(&info, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001332 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001333 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1334 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001335}
1336
1337#endif /* MS_WINDOWS */
1338
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001339PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001340"stat_result: Result from stat or lstat.\n\n\
1341This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001342 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001343or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1344\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001345Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1346or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001347\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001348See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001349
1350static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001351 {"st_mode", "protection bits"},
1352 {"st_ino", "inode"},
1353 {"st_dev", "device"},
1354 {"st_nlink", "number of hard links"},
1355 {"st_uid", "user ID of owner"},
1356 {"st_gid", "group ID of owner"},
1357 {"st_size", "total size, in bytes"},
1358 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1359 {NULL, "integer time of last access"},
1360 {NULL, "integer time of last modification"},
1361 {NULL, "integer time of last change"},
1362 {"st_atime", "time of last access"},
1363 {"st_mtime", "time of last modification"},
1364 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001365#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001366 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001367#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001368#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001369 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001370#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001371#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001372 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001373#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001374#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001375 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001376#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001377#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001378 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001379#endif
1380#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001381 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001382#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001383 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001384};
1385
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001386#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001387#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001388#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001389#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001390#endif
1391
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001392#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001393#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1394#else
1395#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1396#endif
1397
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001398#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001399#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1400#else
1401#define ST_RDEV_IDX ST_BLOCKS_IDX
1402#endif
1403
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001404#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1405#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1406#else
1407#define ST_FLAGS_IDX ST_RDEV_IDX
1408#endif
1409
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001410#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001411#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001412#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001413#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001414#endif
1415
1416#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1417#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1418#else
1419#define ST_BIRTHTIME_IDX ST_GEN_IDX
1420#endif
1421
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001422static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001423 "stat_result", /* name */
1424 stat_result__doc__, /* doc */
1425 stat_result_fields,
1426 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001427};
1428
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001429PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001430"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1431This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001432 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001433or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001434\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001435See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001436
1437static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001438 {"f_bsize", },
1439 {"f_frsize", },
1440 {"f_blocks", },
1441 {"f_bfree", },
1442 {"f_bavail", },
1443 {"f_files", },
1444 {"f_ffree", },
1445 {"f_favail", },
1446 {"f_flag", },
1447 {"f_namemax",},
1448 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001449};
1450
1451static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001452 "statvfs_result", /* name */
1453 statvfs_result__doc__, /* doc */
1454 statvfs_result_fields,
1455 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001456};
1457
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001458static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001459static PyTypeObject StatResultType;
1460static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001461static newfunc structseq_new;
1462
1463static PyObject *
1464statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1465{
Victor Stinner8c62be82010-05-06 00:08:46 +00001466 PyStructSequence *result;
1467 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001468
Victor Stinner8c62be82010-05-06 00:08:46 +00001469 result = (PyStructSequence*)structseq_new(type, args, kwds);
1470 if (!result)
1471 return NULL;
1472 /* If we have been initialized from a tuple,
1473 st_?time might be set to None. Initialize it
1474 from the int slots. */
1475 for (i = 7; i <= 9; i++) {
1476 if (result->ob_item[i+3] == Py_None) {
1477 Py_DECREF(Py_None);
1478 Py_INCREF(result->ob_item[i]);
1479 result->ob_item[i+3] = result->ob_item[i];
1480 }
1481 }
1482 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001483}
1484
1485
1486
1487/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001488static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001489
1490PyDoc_STRVAR(stat_float_times__doc__,
1491"stat_float_times([newval]) -> oldval\n\n\
1492Determine whether os.[lf]stat represents time stamps as float objects.\n\
1493If newval is True, future calls to stat() return floats, if it is False,\n\
1494future calls return ints. \n\
1495If newval is omitted, return the current setting.\n");
1496
1497static PyObject*
1498stat_float_times(PyObject* self, PyObject *args)
1499{
Victor Stinner8c62be82010-05-06 00:08:46 +00001500 int newval = -1;
1501 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1502 return NULL;
1503 if (newval == -1)
1504 /* Return old value */
1505 return PyBool_FromLong(_stat_float_times);
1506 _stat_float_times = newval;
1507 Py_INCREF(Py_None);
1508 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001509}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001510
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001511static void
1512fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1513{
Victor Stinner8c62be82010-05-06 00:08:46 +00001514 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001515#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner8c62be82010-05-06 00:08:46 +00001516 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001517#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001518 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001519#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001520 if (!ival)
1521 return;
1522 if (_stat_float_times) {
1523 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1524 } else {
1525 fval = ival;
1526 Py_INCREF(fval);
1527 }
1528 PyStructSequence_SET_ITEM(v, index, ival);
1529 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001530}
1531
Tim Peters5aa91602002-01-30 05:46:57 +00001532/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001533 (used by posix_stat() and posix_fstat()) */
1534static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001535_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001536{
Victor Stinner8c62be82010-05-06 00:08:46 +00001537 unsigned long ansec, mnsec, cnsec;
1538 PyObject *v = PyStructSequence_New(&StatResultType);
1539 if (v == NULL)
1540 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001541
Victor Stinner8c62be82010-05-06 00:08:46 +00001542 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001543#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001544 PyStructSequence_SET_ITEM(v, 1,
1545 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001546#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001547 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001548#endif
1549#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001550 PyStructSequence_SET_ITEM(v, 2,
1551 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001552#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001553 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001554#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001555 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1556 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1557 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001558#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001559 PyStructSequence_SET_ITEM(v, 6,
1560 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001561#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001562 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001563#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001564
Martin v. Löwis14694662006-02-03 12:54:16 +00001565#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001566 ansec = st->st_atim.tv_nsec;
1567 mnsec = st->st_mtim.tv_nsec;
1568 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001569#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001570 ansec = st->st_atimespec.tv_nsec;
1571 mnsec = st->st_mtimespec.tv_nsec;
1572 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001573#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001574 ansec = st->st_atime_nsec;
1575 mnsec = st->st_mtime_nsec;
1576 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001577#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001578 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001579#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001580 fill_time(v, 7, st->st_atime, ansec);
1581 fill_time(v, 8, st->st_mtime, mnsec);
1582 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001583
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001584#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001585 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1586 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001587#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001588#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001589 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1590 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001591#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001592#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001593 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1594 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001595#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001596#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001597 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1598 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001599#endif
1600#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001601 {
1602 PyObject *val;
1603 unsigned long bsec,bnsec;
1604 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001605#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner8c62be82010-05-06 00:08:46 +00001606 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001607#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001608 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001609#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001610 if (_stat_float_times) {
1611 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1612 } else {
1613 val = PyLong_FromLong((long)bsec);
1614 }
1615 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1616 val);
1617 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001618#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001619#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001620 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1621 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001622#endif
Fred Drake699f3522000-06-29 21:12:41 +00001623
Victor Stinner8c62be82010-05-06 00:08:46 +00001624 if (PyErr_Occurred()) {
1625 Py_DECREF(v);
1626 return NULL;
1627 }
Fred Drake699f3522000-06-29 21:12:41 +00001628
Victor Stinner8c62be82010-05-06 00:08:46 +00001629 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001630}
1631
Barry Warsaw53699e91996-12-10 23:23:01 +00001632static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001633posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +00001634 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001635#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00001636 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001637#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001638 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001639#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001640 char *wformat,
1641 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001642{
Victor Stinner8c62be82010-05-06 00:08:46 +00001643 STRUCT_STAT st;
1644 PyObject *opath;
1645 char *path;
1646 int res;
1647 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001648
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001649#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001650 PyUnicodeObject *po;
1651 if (PyArg_ParseTuple(args, wformat, &po)) {
1652 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001653
Victor Stinner8c62be82010-05-06 00:08:46 +00001654 Py_BEGIN_ALLOW_THREADS
1655 /* PyUnicode_AS_UNICODE result OK without
1656 thread lock as it is a simple dereference. */
1657 res = wstatfunc(wpath, &st);
1658 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001659
Victor Stinner8c62be82010-05-06 00:08:46 +00001660 if (res != 0)
1661 return win32_error_unicode("stat", wpath);
1662 return _pystat_fromstructstat(&st);
1663 }
1664 /* Drop the argument parsing error as narrow strings
1665 are also valid. */
1666 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001667#endif
1668
Victor Stinner8c62be82010-05-06 00:08:46 +00001669 if (!PyArg_ParseTuple(args, format,
1670 PyUnicode_FSConverter, &opath))
1671 return NULL;
1672 path = PyBytes_AsString(opath);
1673 Py_BEGIN_ALLOW_THREADS
1674 res = (*statfunc)(path, &st);
1675 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001676
Victor Stinner8c62be82010-05-06 00:08:46 +00001677 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001678#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001679 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001680#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001681 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001682#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001683 }
1684 else
1685 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001686
Victor Stinner8c62be82010-05-06 00:08:46 +00001687 Py_DECREF(opath);
1688 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001689}
1690
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001691/* POSIX methods */
1692
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001693PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001694"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001695Use the real uid/gid to test for access to a path. Note that most\n\
1696operations will use the effective uid/gid, therefore this routine can\n\
1697be used in a suid/sgid environment to test if the invoking user has the\n\
1698specified access to the path. The mode argument can be F_OK to test\n\
1699existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001700
1701static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001702posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001703{
Victor Stinner8c62be82010-05-06 00:08:46 +00001704 PyObject *opath;
1705 char *path;
1706 int mode;
1707
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001708#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001709 DWORD attr;
1710 PyUnicodeObject *po;
1711 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1712 Py_BEGIN_ALLOW_THREADS
1713 /* PyUnicode_AS_UNICODE OK without thread lock as
1714 it is a simple dereference. */
1715 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1716 Py_END_ALLOW_THREADS
1717 goto finish;
1718 }
1719 /* Drop the argument parsing error as narrow strings
1720 are also valid. */
1721 PyErr_Clear();
1722 if (!PyArg_ParseTuple(args, "O&i:access",
1723 PyUnicode_FSConverter, &opath, &mode))
1724 return NULL;
1725 path = PyBytes_AsString(opath);
1726 Py_BEGIN_ALLOW_THREADS
1727 attr = GetFileAttributesA(path);
1728 Py_END_ALLOW_THREADS
1729 Py_DECREF(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001730finish:
Victor Stinner8c62be82010-05-06 00:08:46 +00001731 if (attr == 0xFFFFFFFF)
1732 /* File does not exist, or cannot read attributes */
1733 return PyBool_FromLong(0);
1734 /* Access is possible if either write access wasn't requested, or
1735 the file isn't read-only, or if it's a directory, as there are
1736 no read-only directories on Windows. */
1737 return PyBool_FromLong(!(mode & 2)
1738 || !(attr & FILE_ATTRIBUTE_READONLY)
1739 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001740#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001741 int res;
1742 if (!PyArg_ParseTuple(args, "O&i:access",
1743 PyUnicode_FSConverter, &opath, &mode))
1744 return NULL;
1745 path = PyBytes_AsString(opath);
1746 Py_BEGIN_ALLOW_THREADS
1747 res = access(path, mode);
1748 Py_END_ALLOW_THREADS
1749 Py_DECREF(opath);
1750 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001751#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001752}
1753
Guido van Rossumd371ff11999-01-25 16:12:23 +00001754#ifndef F_OK
1755#define F_OK 0
1756#endif
1757#ifndef R_OK
1758#define R_OK 4
1759#endif
1760#ifndef W_OK
1761#define W_OK 2
1762#endif
1763#ifndef X_OK
1764#define X_OK 1
1765#endif
1766
1767#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001768PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001769"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001770Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001771
1772static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001773posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001774{
Victor Stinner8c62be82010-05-06 00:08:46 +00001775 int id;
1776 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001777
Victor Stinner8c62be82010-05-06 00:08:46 +00001778 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1779 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001780
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001781#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001782 /* file descriptor 0 only, the default input device (stdin) */
1783 if (id == 0) {
1784 ret = ttyname();
1785 }
1786 else {
1787 ret = NULL;
1788 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001789#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001790 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001791#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001792 if (ret == NULL)
1793 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001794 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001795}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001796#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001797
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001798#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001799PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001800"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001801Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001802
1803static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001804posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001805{
Victor Stinner8c62be82010-05-06 00:08:46 +00001806 char *ret;
1807 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001808
Greg Wardb48bc172000-03-01 21:51:56 +00001809#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00001810 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001811#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001812 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001813#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001814 if (ret == NULL)
1815 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001816 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001817}
1818#endif
1819
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001820PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001821"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001822Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001823
Barry Warsaw53699e91996-12-10 23:23:01 +00001824static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001825posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001826{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001827#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001828 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001829#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001830 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001831#elif defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001832 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001833#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001834 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001835#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001836}
1837
Fred Drake4d1e64b2002-04-15 19:40:07 +00001838#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001839PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001840"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001841Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001842opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001843
1844static PyObject *
1845posix_fchdir(PyObject *self, PyObject *fdobj)
1846{
Victor Stinner8c62be82010-05-06 00:08:46 +00001847 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001848}
1849#endif /* HAVE_FCHDIR */
1850
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001851
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001852PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001853"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001854Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001855
Barry Warsaw53699e91996-12-10 23:23:01 +00001856static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001857posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001858{
Victor Stinner8c62be82010-05-06 00:08:46 +00001859 PyObject *opath = NULL;
1860 char *path = NULL;
1861 int i;
1862 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001863#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001864 DWORD attr;
1865 PyUnicodeObject *po;
1866 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1867 Py_BEGIN_ALLOW_THREADS
1868 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1869 if (attr != 0xFFFFFFFF) {
1870 if (i & _S_IWRITE)
1871 attr &= ~FILE_ATTRIBUTE_READONLY;
1872 else
1873 attr |= FILE_ATTRIBUTE_READONLY;
1874 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1875 }
1876 else
1877 res = 0;
1878 Py_END_ALLOW_THREADS
1879 if (!res)
1880 return win32_error_unicode("chmod",
1881 PyUnicode_AS_UNICODE(po));
1882 Py_INCREF(Py_None);
1883 return Py_None;
1884 }
1885 /* Drop the argument parsing error as narrow strings
1886 are also valid. */
1887 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001888
Victor Stinner8c62be82010-05-06 00:08:46 +00001889 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1890 &opath, &i))
1891 return NULL;
1892 path = PyBytes_AsString(opath);
1893 Py_BEGIN_ALLOW_THREADS
1894 attr = GetFileAttributesA(path);
1895 if (attr != 0xFFFFFFFF) {
1896 if (i & _S_IWRITE)
1897 attr &= ~FILE_ATTRIBUTE_READONLY;
1898 else
1899 attr |= FILE_ATTRIBUTE_READONLY;
1900 res = SetFileAttributesA(path, attr);
1901 }
1902 else
1903 res = 0;
1904 Py_END_ALLOW_THREADS
1905 if (!res) {
1906 win32_error("chmod", path);
1907 Py_DECREF(opath);
1908 return NULL;
1909 }
1910 Py_DECREF(opath);
1911 Py_INCREF(Py_None);
1912 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001913#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00001914 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1915 &opath, &i))
1916 return NULL;
1917 path = PyBytes_AsString(opath);
1918 Py_BEGIN_ALLOW_THREADS
1919 res = chmod(path, i);
1920 Py_END_ALLOW_THREADS
1921 if (res < 0)
1922 return posix_error_with_allocated_filename(opath);
1923 Py_DECREF(opath);
1924 Py_INCREF(Py_None);
1925 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001926#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001927}
1928
Christian Heimes4e30a842007-11-30 22:12:06 +00001929#ifdef HAVE_FCHMOD
1930PyDoc_STRVAR(posix_fchmod__doc__,
1931"fchmod(fd, mode)\n\n\
1932Change the access permissions of the file given by file\n\
1933descriptor fd.");
1934
1935static PyObject *
1936posix_fchmod(PyObject *self, PyObject *args)
1937{
Victor Stinner8c62be82010-05-06 00:08:46 +00001938 int fd, mode, res;
1939 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1940 return NULL;
1941 Py_BEGIN_ALLOW_THREADS
1942 res = fchmod(fd, mode);
1943 Py_END_ALLOW_THREADS
1944 if (res < 0)
1945 return posix_error();
1946 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001947}
1948#endif /* HAVE_FCHMOD */
1949
1950#ifdef HAVE_LCHMOD
1951PyDoc_STRVAR(posix_lchmod__doc__,
1952"lchmod(path, mode)\n\n\
1953Change the access permissions of a file. If path is a symlink, this\n\
1954affects the link itself rather than the target.");
1955
1956static PyObject *
1957posix_lchmod(PyObject *self, PyObject *args)
1958{
Victor Stinner8c62be82010-05-06 00:08:46 +00001959 PyObject *opath;
1960 char *path;
1961 int i;
1962 int res;
1963 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
1964 &opath, &i))
1965 return NULL;
1966 path = PyBytes_AsString(opath);
1967 Py_BEGIN_ALLOW_THREADS
1968 res = lchmod(path, i);
1969 Py_END_ALLOW_THREADS
1970 if (res < 0)
1971 return posix_error_with_allocated_filename(opath);
1972 Py_DECREF(opath);
1973 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001974}
1975#endif /* HAVE_LCHMOD */
1976
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001977
Thomas Wouterscf297e42007-02-23 15:07:44 +00001978#ifdef HAVE_CHFLAGS
1979PyDoc_STRVAR(posix_chflags__doc__,
1980"chflags(path, flags)\n\n\
1981Set file flags.");
1982
1983static PyObject *
1984posix_chflags(PyObject *self, PyObject *args)
1985{
Victor Stinner8c62be82010-05-06 00:08:46 +00001986 PyObject *opath;
1987 char *path;
1988 unsigned long flags;
1989 int res;
1990 if (!PyArg_ParseTuple(args, "O&k:chflags",
1991 PyUnicode_FSConverter, &opath, &flags))
1992 return NULL;
1993 path = PyBytes_AsString(opath);
1994 Py_BEGIN_ALLOW_THREADS
1995 res = chflags(path, flags);
1996 Py_END_ALLOW_THREADS
1997 if (res < 0)
1998 return posix_error_with_allocated_filename(opath);
1999 Py_DECREF(opath);
2000 Py_INCREF(Py_None);
2001 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002002}
2003#endif /* HAVE_CHFLAGS */
2004
2005#ifdef HAVE_LCHFLAGS
2006PyDoc_STRVAR(posix_lchflags__doc__,
2007"lchflags(path, flags)\n\n\
2008Set file flags.\n\
2009This function will not follow symbolic links.");
2010
2011static PyObject *
2012posix_lchflags(PyObject *self, PyObject *args)
2013{
Victor Stinner8c62be82010-05-06 00:08:46 +00002014 PyObject *opath;
2015 char *path;
2016 unsigned long flags;
2017 int res;
2018 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2019 PyUnicode_FSConverter, &opath, &flags))
2020 return NULL;
2021 path = PyBytes_AsString(opath);
2022 Py_BEGIN_ALLOW_THREADS
2023 res = lchflags(path, flags);
2024 Py_END_ALLOW_THREADS
2025 if (res < 0)
2026 return posix_error_with_allocated_filename(opath);
2027 Py_DECREF(opath);
2028 Py_INCREF(Py_None);
2029 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002030}
2031#endif /* HAVE_LCHFLAGS */
2032
Martin v. Löwis244edc82001-10-04 22:44:26 +00002033#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002034PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002035"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002036Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002037
2038static PyObject *
2039posix_chroot(PyObject *self, PyObject *args)
2040{
Victor Stinner8c62be82010-05-06 00:08:46 +00002041 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002042}
2043#endif
2044
Guido van Rossum21142a01999-01-08 21:05:37 +00002045#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002046PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002047"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002048force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002049
2050static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002051posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002052{
Stefan Krah0e803b32010-11-26 16:16:47 +00002053 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002054}
2055#endif /* HAVE_FSYNC */
2056
2057#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002058
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002059#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002060extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2061#endif
2062
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002063PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002064"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002065force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002066 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002067
2068static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002069posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002070{
Stefan Krah0e803b32010-11-26 16:16:47 +00002071 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002072}
2073#endif /* HAVE_FDATASYNC */
2074
2075
Fredrik Lundh10723342000-07-10 16:38:09 +00002076#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002077PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002078"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002079Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002080
Barry Warsaw53699e91996-12-10 23:23:01 +00002081static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002082posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002083{
Victor Stinner8c62be82010-05-06 00:08:46 +00002084 PyObject *opath;
2085 char *path;
2086 long uid, gid;
2087 int res;
2088 if (!PyArg_ParseTuple(args, "O&ll:chown",
2089 PyUnicode_FSConverter, &opath,
2090 &uid, &gid))
2091 return NULL;
2092 path = PyBytes_AsString(opath);
2093 Py_BEGIN_ALLOW_THREADS
2094 res = chown(path, (uid_t) uid, (gid_t) gid);
2095 Py_END_ALLOW_THREADS
2096 if (res < 0)
2097 return posix_error_with_allocated_filename(opath);
2098 Py_DECREF(opath);
2099 Py_INCREF(Py_None);
2100 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002101}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002102#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002103
Christian Heimes4e30a842007-11-30 22:12:06 +00002104#ifdef HAVE_FCHOWN
2105PyDoc_STRVAR(posix_fchown__doc__,
2106"fchown(fd, uid, gid)\n\n\
2107Change the owner and group id of the file given by file descriptor\n\
2108fd to the numeric uid and gid.");
2109
2110static PyObject *
2111posix_fchown(PyObject *self, PyObject *args)
2112{
Victor Stinner8c62be82010-05-06 00:08:46 +00002113 int fd;
2114 long uid, gid;
2115 int res;
2116 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
2117 return NULL;
2118 Py_BEGIN_ALLOW_THREADS
2119 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2120 Py_END_ALLOW_THREADS
2121 if (res < 0)
2122 return posix_error();
2123 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002124}
2125#endif /* HAVE_FCHOWN */
2126
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002127#ifdef HAVE_LCHOWN
2128PyDoc_STRVAR(posix_lchown__doc__,
2129"lchown(path, uid, gid)\n\n\
2130Change the owner and group id of path to the numeric uid and gid.\n\
2131This function will not follow symbolic links.");
2132
2133static PyObject *
2134posix_lchown(PyObject *self, PyObject *args)
2135{
Victor Stinner8c62be82010-05-06 00:08:46 +00002136 PyObject *opath;
2137 char *path;
2138 long uid, gid;
2139 int res;
2140 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2141 PyUnicode_FSConverter, &opath,
2142 &uid, &gid))
2143 return NULL;
2144 path = PyBytes_AsString(opath);
2145 Py_BEGIN_ALLOW_THREADS
2146 res = lchown(path, (uid_t) uid, (gid_t) gid);
2147 Py_END_ALLOW_THREADS
2148 if (res < 0)
2149 return posix_error_with_allocated_filename(opath);
2150 Py_DECREF(opath);
2151 Py_INCREF(Py_None);
2152 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002153}
2154#endif /* HAVE_LCHOWN */
2155
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002156
Guido van Rossum36bc6801995-06-14 22:54:23 +00002157#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002158static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002159posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002160{
Victor Stinner8c62be82010-05-06 00:08:46 +00002161 char buf[1026];
2162 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002163
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002164#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002165 if (!use_bytes) {
2166 wchar_t wbuf[1026];
2167 wchar_t *wbuf2 = wbuf;
2168 PyObject *resobj;
2169 DWORD len;
2170 Py_BEGIN_ALLOW_THREADS
2171 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2172 /* If the buffer is large enough, len does not include the
2173 terminating \0. If the buffer is too small, len includes
2174 the space needed for the terminator. */
2175 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2176 wbuf2 = malloc(len * sizeof(wchar_t));
2177 if (wbuf2)
2178 len = GetCurrentDirectoryW(len, wbuf2);
2179 }
2180 Py_END_ALLOW_THREADS
2181 if (!wbuf2) {
2182 PyErr_NoMemory();
2183 return NULL;
2184 }
2185 if (!len) {
2186 if (wbuf2 != wbuf) free(wbuf2);
2187 return win32_error("getcwdu", NULL);
2188 }
2189 resobj = PyUnicode_FromWideChar(wbuf2, len);
2190 if (wbuf2 != wbuf) free(wbuf2);
2191 return resobj;
2192 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002193#endif
2194
Victor Stinner8c62be82010-05-06 00:08:46 +00002195 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002196#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002197 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002198#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002199 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002200#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002201 Py_END_ALLOW_THREADS
2202 if (res == NULL)
2203 return posix_error();
2204 if (use_bytes)
2205 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002206 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002207}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002208
2209PyDoc_STRVAR(posix_getcwd__doc__,
2210"getcwd() -> path\n\n\
2211Return a unicode string representing the current working directory.");
2212
2213static PyObject *
2214posix_getcwd_unicode(PyObject *self)
2215{
2216 return posix_getcwd(0);
2217}
2218
2219PyDoc_STRVAR(posix_getcwdb__doc__,
2220"getcwdb() -> path\n\n\
2221Return a bytes string representing the current working directory.");
2222
2223static PyObject *
2224posix_getcwd_bytes(PyObject *self)
2225{
2226 return posix_getcwd(1);
2227}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002228#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002229
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002230
Guido van Rossumb6775db1994-08-01 11:34:53 +00002231#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002232PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002233"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002234Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002235
Barry Warsaw53699e91996-12-10 23:23:01 +00002236static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002237posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002238{
Victor Stinner8c62be82010-05-06 00:08:46 +00002239 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002240}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002241#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002242
Brian Curtin1b9df392010-11-24 20:24:31 +00002243#ifdef MS_WINDOWS
2244PyDoc_STRVAR(win32_link__doc__,
2245"link(src, dst)\n\n\
2246Create a hard link to a file.");
2247
2248static PyObject *
2249win32_link(PyObject *self, PyObject *args)
2250{
2251 PyObject *osrc, *odst;
2252 char *src, *dst;
2253 BOOL rslt;
2254
2255 if (!PyArg_ParseTuple(args, "O&O&:link", PyUnicode_FSConverter, &osrc,
2256 PyUnicode_FSConverter, &odst))
2257 return NULL;
2258
2259 src = PyBytes_AsString(osrc);
2260 dst = PyBytes_AsString(odst);
2261
2262 Py_BEGIN_ALLOW_THREADS
2263 rslt = CreateHardLink(dst, src, NULL);
2264 Py_END_ALLOW_THREADS
2265
Stefan Krah30b341f2010-11-27 11:44:18 +00002266 Py_DECREF(osrc);
2267 Py_DECREF(odst);
Brian Curtin1b9df392010-11-24 20:24:31 +00002268 if (rslt == 0)
2269 return posix_error();
2270
2271 Py_RETURN_NONE;
2272}
2273#endif /* MS_WINDOWS */
2274
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002275
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002276PyDoc_STRVAR(posix_listdir__doc__,
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002277"listdir([path]) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002278Return a list containing the names of the entries in the directory.\n\
2279\n\
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002280 path: path of directory to list (default: '.')\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002281\n\
2282The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002283entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002284
Barry Warsaw53699e91996-12-10 23:23:01 +00002285static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002286posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002287{
Victor Stinner8c62be82010-05-06 00:08:46 +00002288 /* XXX Should redo this putting the (now four) versions of opendir
2289 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002290#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002291
Victor Stinner8c62be82010-05-06 00:08:46 +00002292 PyObject *d, *v;
2293 HANDLE hFindFile;
2294 BOOL result;
2295 WIN32_FIND_DATA FileData;
2296 PyObject *opath;
2297 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2298 char *bufptr = namebuf;
2299 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002300
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002301 PyObject *po = NULL;
2302 if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002303 WIN32_FIND_DATAW wFileData;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002304 Py_UNICODE *wnamebuf, *po_wchars;
2305
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002306 if (po == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002307 po_wchars = L".";
2308 len = 1;
2309 } else {
2310 po_wchars = PyUnicode_AS_UNICODE(po);
2311 len = PyUnicode_GET_SIZE(po);
2312 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002313 /* Overallocate for \\*.*\0 */
Victor Stinner8c62be82010-05-06 00:08:46 +00002314 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2315 if (!wnamebuf) {
2316 PyErr_NoMemory();
2317 return NULL;
2318 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002319 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00002320 if (len > 0) {
2321 Py_UNICODE wch = wnamebuf[len-1];
2322 if (wch != L'/' && wch != L'\\' && wch != L':')
2323 wnamebuf[len++] = L'\\';
2324 wcscpy(wnamebuf + len, L"*.*");
2325 }
2326 if ((d = PyList_New(0)) == NULL) {
2327 free(wnamebuf);
2328 return NULL;
2329 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00002330 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002331 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002332 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002333 if (hFindFile == INVALID_HANDLE_VALUE) {
2334 int error = GetLastError();
2335 if (error == ERROR_FILE_NOT_FOUND) {
2336 free(wnamebuf);
2337 return d;
2338 }
2339 Py_DECREF(d);
2340 win32_error_unicode("FindFirstFileW", wnamebuf);
2341 free(wnamebuf);
2342 return NULL;
2343 }
2344 do {
2345 /* Skip over . and .. */
2346 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2347 wcscmp(wFileData.cFileName, L"..") != 0) {
2348 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2349 if (v == NULL) {
2350 Py_DECREF(d);
2351 d = NULL;
2352 break;
2353 }
2354 if (PyList_Append(d, v) != 0) {
2355 Py_DECREF(v);
2356 Py_DECREF(d);
2357 d = NULL;
2358 break;
2359 }
2360 Py_DECREF(v);
2361 }
2362 Py_BEGIN_ALLOW_THREADS
2363 result = FindNextFileW(hFindFile, &wFileData);
2364 Py_END_ALLOW_THREADS
2365 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2366 it got to the end of the directory. */
2367 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2368 Py_DECREF(d);
2369 win32_error_unicode("FindNextFileW", wnamebuf);
2370 FindClose(hFindFile);
2371 free(wnamebuf);
2372 return NULL;
2373 }
2374 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002375
Victor Stinner8c62be82010-05-06 00:08:46 +00002376 if (FindClose(hFindFile) == FALSE) {
2377 Py_DECREF(d);
2378 win32_error_unicode("FindClose", wnamebuf);
2379 free(wnamebuf);
2380 return NULL;
2381 }
2382 free(wnamebuf);
2383 return d;
2384 }
2385 /* Drop the argument parsing error as narrow strings
2386 are also valid. */
2387 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002388
Victor Stinner8c62be82010-05-06 00:08:46 +00002389 if (!PyArg_ParseTuple(args, "O&:listdir",
2390 PyUnicode_FSConverter, &opath))
2391 return NULL;
2392 if (PyBytes_GET_SIZE(opath)+1 > MAX_PATH) {
2393 PyErr_SetString(PyExc_ValueError, "path too long");
2394 Py_DECREF(opath);
2395 return NULL;
2396 }
2397 strcpy(namebuf, PyBytes_AsString(opath));
2398 len = PyObject_Size(opath);
Stefan Krah2a7feee2010-11-27 22:06:49 +00002399 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00002400 if (len > 0) {
2401 char ch = namebuf[len-1];
2402 if (ch != SEP && ch != ALTSEP && ch != ':')
2403 namebuf[len++] = '/';
2404 strcpy(namebuf + len, "*.*");
2405 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002406
Victor Stinner8c62be82010-05-06 00:08:46 +00002407 if ((d = PyList_New(0)) == NULL)
2408 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002409
Antoine Pitroub73caab2010-08-09 23:39:31 +00002410 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002411 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002412 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002413 if (hFindFile == INVALID_HANDLE_VALUE) {
2414 int error = GetLastError();
2415 if (error == ERROR_FILE_NOT_FOUND)
2416 return d;
2417 Py_DECREF(d);
2418 return win32_error("FindFirstFile", namebuf);
2419 }
2420 do {
2421 /* Skip over . and .. */
2422 if (strcmp(FileData.cFileName, ".") != 0 &&
2423 strcmp(FileData.cFileName, "..") != 0) {
2424 v = PyBytes_FromString(FileData.cFileName);
2425 if (v == NULL) {
2426 Py_DECREF(d);
2427 d = NULL;
2428 break;
2429 }
2430 if (PyList_Append(d, v) != 0) {
2431 Py_DECREF(v);
2432 Py_DECREF(d);
2433 d = NULL;
2434 break;
2435 }
2436 Py_DECREF(v);
2437 }
2438 Py_BEGIN_ALLOW_THREADS
2439 result = FindNextFile(hFindFile, &FileData);
2440 Py_END_ALLOW_THREADS
2441 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2442 it got to the end of the directory. */
2443 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2444 Py_DECREF(d);
2445 win32_error("FindNextFile", namebuf);
2446 FindClose(hFindFile);
2447 return NULL;
2448 }
2449 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002450
Victor Stinner8c62be82010-05-06 00:08:46 +00002451 if (FindClose(hFindFile) == FALSE) {
2452 Py_DECREF(d);
2453 return win32_error("FindClose", namebuf);
2454 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002455
Victor Stinner8c62be82010-05-06 00:08:46 +00002456 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002457
Tim Peters0bb44a42000-09-15 07:44:49 +00002458#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002459
2460#ifndef MAX_PATH
2461#define MAX_PATH CCHMAXPATH
2462#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002463 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002464 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002465 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002466 PyObject *d, *v;
2467 char namebuf[MAX_PATH+5];
2468 HDIR hdir = 1;
2469 ULONG srchcnt = 1;
2470 FILEFINDBUF3 ep;
2471 APIRET rc;
2472
Victor Stinner8c62be82010-05-06 00:08:46 +00002473 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002474 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002475 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002476 name = PyBytes_AsString(oname);
2477 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002478 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002479 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002480 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002481 return NULL;
2482 }
2483 strcpy(namebuf, name);
2484 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002485 if (*pt == ALTSEP)
2486 *pt = SEP;
2487 if (namebuf[len-1] != SEP)
2488 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002489 strcpy(namebuf + len, "*.*");
2490
Neal Norwitz6c913782007-10-14 03:23:09 +00002491 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002492 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002493 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002494 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002495
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002496 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2497 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002498 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002499 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2500 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2501 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002502
2503 if (rc != NO_ERROR) {
2504 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002505 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002506 }
2507
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002508 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002509 do {
2510 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002511 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002512 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002513
2514 strcpy(namebuf, ep.achName);
2515
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002516 /* Leave Case of Name Alone -- In Native Form */
2517 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002518
Christian Heimes72b710a2008-05-26 13:28:38 +00002519 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002520 if (v == NULL) {
2521 Py_DECREF(d);
2522 d = NULL;
2523 break;
2524 }
2525 if (PyList_Append(d, v) != 0) {
2526 Py_DECREF(v);
2527 Py_DECREF(d);
2528 d = NULL;
2529 break;
2530 }
2531 Py_DECREF(v);
2532 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2533 }
2534
Victor Stinnerdcb24032010-04-22 12:08:36 +00002535 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002536 return d;
2537#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002538 PyObject *oname;
2539 char *name;
2540 PyObject *d, *v;
2541 DIR *dirp;
2542 struct dirent *ep;
2543 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002544
Victor Stinner8c62be82010-05-06 00:08:46 +00002545 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002546 /* v is never read, so it does not need to be initialized yet. */
2547 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002548 arg_is_unicode = 0;
2549 PyErr_Clear();
2550 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002551 oname = NULL;
2552 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
Victor Stinner8c62be82010-05-06 00:08:46 +00002553 return NULL;
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002554 if (oname == NULL) { /* Default arg: "." */
Stefan Krah0e803b32010-11-26 16:16:47 +00002555 oname = PyBytes_FromString(".");
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002556 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002557 name = PyBytes_AsString(oname);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002558 Py_BEGIN_ALLOW_THREADS
2559 dirp = opendir(name);
2560 Py_END_ALLOW_THREADS
2561 if (dirp == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002562 return posix_error_with_allocated_filename(oname);
2563 }
2564 if ((d = PyList_New(0)) == NULL) {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002565 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002566 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002567 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002568 Py_DECREF(oname);
2569 return NULL;
2570 }
2571 for (;;) {
2572 errno = 0;
2573 Py_BEGIN_ALLOW_THREADS
2574 ep = readdir(dirp);
2575 Py_END_ALLOW_THREADS
2576 if (ep == NULL) {
2577 if (errno == 0) {
2578 break;
2579 } else {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002580 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002581 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002582 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002583 Py_DECREF(d);
2584 return posix_error_with_allocated_filename(oname);
2585 }
2586 }
2587 if (ep->d_name[0] == '.' &&
2588 (NAMLEN(ep) == 1 ||
2589 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2590 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002591 if (arg_is_unicode)
2592 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2593 else
2594 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002595 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002596 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002597 break;
2598 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002599 if (PyList_Append(d, v) != 0) {
2600 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002601 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002602 break;
2603 }
2604 Py_DECREF(v);
2605 }
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002606 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002607 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002608 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002609 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002610
Victor Stinner8c62be82010-05-06 00:08:46 +00002611 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002612
Tim Peters0bb44a42000-09-15 07:44:49 +00002613#endif /* which OS */
2614} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002615
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002616#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002617/* A helper function for abspath on win32 */
2618static PyObject *
2619posix__getfullpathname(PyObject *self, PyObject *args)
2620{
Victor Stinner8c62be82010-05-06 00:08:46 +00002621 PyObject *opath;
2622 char *path;
2623 char outbuf[MAX_PATH*2];
2624 char *temp;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002625#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002626 PyUnicodeObject *po;
2627 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2628 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2629 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2630 Py_UNICODE *wtemp;
2631 DWORD result;
2632 PyObject *v;
2633 result = GetFullPathNameW(wpath,
2634 sizeof(woutbuf)/sizeof(woutbuf[0]),
2635 woutbuf, &wtemp);
2636 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2637 woutbufp = malloc(result * sizeof(Py_UNICODE));
2638 if (!woutbufp)
2639 return PyErr_NoMemory();
2640 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2641 }
2642 if (result)
2643 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2644 else
2645 v = win32_error_unicode("GetFullPathNameW", wpath);
2646 if (woutbufp != woutbuf)
2647 free(woutbufp);
2648 return v;
2649 }
2650 /* Drop the argument parsing error as narrow strings
2651 are also valid. */
2652 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002653
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002654#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002655 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2656 PyUnicode_FSConverter, &opath))
2657 return NULL;
2658 path = PyBytes_AsString(opath);
2659 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2660 outbuf, &temp)) {
2661 win32_error("GetFullPathName", path);
2662 Py_DECREF(opath);
2663 return NULL;
2664 }
2665 Py_DECREF(opath);
2666 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2667 return PyUnicode_Decode(outbuf, strlen(outbuf),
2668 Py_FileSystemDefaultEncoding, NULL);
2669 }
2670 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002671} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00002672
Brian Curtinf5e76d02010-11-24 13:14:05 +00002673/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
2674static int has_GetFinalPathNameByHandle = 0;
2675static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
2676 DWORD);
2677static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
2678 DWORD);
2679static int
2680check_GetFinalPathNameByHandle()
2681{
2682 HINSTANCE hKernel32;
2683 /* only recheck */
2684 if (!has_GetFinalPathNameByHandle)
2685 {
2686 hKernel32 = GetModuleHandle("KERNEL32");
2687 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
2688 "GetFinalPathNameByHandleA");
2689 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
2690 "GetFinalPathNameByHandleW");
2691 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
2692 Py_GetFinalPathNameByHandleW;
2693 }
2694 return has_GetFinalPathNameByHandle;
2695}
2696
Brian Curtind40e6f72010-07-08 21:39:08 +00002697/* A helper function for samepath on windows */
2698static PyObject *
2699posix__getfinalpathname(PyObject *self, PyObject *args)
2700{
2701 HANDLE hFile;
2702 int buf_size;
2703 wchar_t *target_path;
2704 int result_length;
2705 PyObject *result;
2706 wchar_t *path;
2707
Brian Curtin94622b02010-09-24 00:03:39 +00002708 if (!PyArg_ParseTuple(args, "u|:_getfinalpathname", &path)) {
Brian Curtind40e6f72010-07-08 21:39:08 +00002709 return NULL;
2710 }
2711
2712 if(!check_GetFinalPathNameByHandle()) {
2713 /* If the OS doesn't have GetFinalPathNameByHandle, return a
2714 NotImplementedError. */
2715 return PyErr_Format(PyExc_NotImplementedError,
2716 "GetFinalPathNameByHandle not available on this platform");
2717 }
2718
2719 hFile = CreateFileW(
2720 path,
2721 0, /* desired access */
2722 0, /* share mode */
2723 NULL, /* security attributes */
2724 OPEN_EXISTING,
2725 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
2726 FILE_FLAG_BACKUP_SEMANTICS,
2727 NULL);
2728
2729 if(hFile == INVALID_HANDLE_VALUE) {
2730 return win32_error_unicode("GetFinalPathNamyByHandle", path);
Brian Curtin74e45612010-07-09 15:58:59 +00002731 return PyErr_Format(PyExc_RuntimeError,
2732 "Could not get a handle to file.");
Brian Curtind40e6f72010-07-08 21:39:08 +00002733 }
2734
2735 /* We have a good handle to the target, use it to determine the
2736 target path name. */
2737 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
2738
2739 if(!buf_size)
2740 return win32_error_unicode("GetFinalPathNameByHandle", path);
2741
2742 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
2743 if(!target_path)
2744 return PyErr_NoMemory();
2745
2746 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
2747 buf_size, VOLUME_NAME_DOS);
2748 if(!result_length)
2749 return win32_error_unicode("GetFinalPathNamyByHandle", path);
2750
2751 if(!CloseHandle(hFile))
2752 return win32_error_unicode("GetFinalPathNameByHandle", path);
2753
2754 target_path[result_length] = 0;
2755 result = PyUnicode_FromUnicode(target_path, result_length);
2756 free(target_path);
2757 return result;
2758
2759} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00002760
2761static PyObject *
2762posix__getfileinformation(PyObject *self, PyObject *args)
2763{
2764 HANDLE hFile;
2765 BY_HANDLE_FILE_INFORMATION info;
2766 int fd;
2767
2768 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
2769 return NULL;
2770
2771 if (!_PyVerify_fd(fd)) {
2772 PyErr_SetString(PyExc_ValueError, "received invalid file descriptor");
2773 return NULL;
2774 }
2775
2776 hFile = (HANDLE)_get_osfhandle(fd);
2777 if (hFile == INVALID_HANDLE_VALUE)
2778 return win32_error("_getfileinformation", NULL);
2779
2780 if (!GetFileInformationByHandle(hFile, &info))
2781 return win32_error("_getfileinformation", NULL);
2782
2783 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
2784 info.nFileIndexHigh,
2785 info.nFileIndexLow);
2786}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002787#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002788
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002789PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002790"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002791Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002792
Barry Warsaw53699e91996-12-10 23:23:01 +00002793static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002794posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002795{
Victor Stinner8c62be82010-05-06 00:08:46 +00002796 int res;
2797 PyObject *opath;
2798 char *path;
2799 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002800
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002801#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002802 PyUnicodeObject *po;
2803 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2804 Py_BEGIN_ALLOW_THREADS
2805 /* PyUnicode_AS_UNICODE OK without thread lock as
2806 it is a simple dereference. */
2807 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2808 Py_END_ALLOW_THREADS
2809 if (!res)
2810 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2811 Py_INCREF(Py_None);
2812 return Py_None;
2813 }
2814 /* Drop the argument parsing error as narrow strings
2815 are also valid. */
2816 PyErr_Clear();
2817 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2818 PyUnicode_FSConverter, &opath, &mode))
2819 return NULL;
2820 path = PyBytes_AsString(opath);
2821 Py_BEGIN_ALLOW_THREADS
2822 /* PyUnicode_AS_UNICODE OK without thread lock as
2823 it is a simple dereference. */
2824 res = CreateDirectoryA(path, NULL);
2825 Py_END_ALLOW_THREADS
2826 if (!res) {
2827 win32_error("mkdir", path);
2828 Py_DECREF(opath);
2829 return NULL;
2830 }
2831 Py_DECREF(opath);
2832 Py_INCREF(Py_None);
2833 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002834#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002835
Victor Stinner8c62be82010-05-06 00:08:46 +00002836 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2837 PyUnicode_FSConverter, &opath, &mode))
2838 return NULL;
2839 path = PyBytes_AsString(opath);
2840 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002841#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00002842 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002843#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002844 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002845#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002846 Py_END_ALLOW_THREADS
2847 if (res < 0)
2848 return posix_error_with_allocated_filename(opath);
2849 Py_DECREF(opath);
2850 Py_INCREF(Py_None);
2851 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002852#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002853}
2854
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002855
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002856/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2857#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002858#include <sys/resource.h>
2859#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002860
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002861
2862#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002863PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002864"nice(inc) -> new_priority\n\n\
2865Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002866
Barry Warsaw53699e91996-12-10 23:23:01 +00002867static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002868posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002869{
Victor Stinner8c62be82010-05-06 00:08:46 +00002870 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002871
Victor Stinner8c62be82010-05-06 00:08:46 +00002872 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2873 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002874
Victor Stinner8c62be82010-05-06 00:08:46 +00002875 /* There are two flavours of 'nice': one that returns the new
2876 priority (as required by almost all standards out there) and the
2877 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2878 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002879
Victor Stinner8c62be82010-05-06 00:08:46 +00002880 If we are of the nice family that returns the new priority, we
2881 need to clear errno before the call, and check if errno is filled
2882 before calling posix_error() on a returnvalue of -1, because the
2883 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002884
Victor Stinner8c62be82010-05-06 00:08:46 +00002885 errno = 0;
2886 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002887#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00002888 if (value == 0)
2889 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002890#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002891 if (value == -1 && errno != 0)
2892 /* either nice() or getpriority() returned an error */
2893 return posix_error();
2894 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002895}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002896#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002897
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002898PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002899"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002900Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002901
Barry Warsaw53699e91996-12-10 23:23:01 +00002902static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002903posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002904{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002905#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002906 PyObject *o1, *o2;
2907 char *p1, *p2;
2908 BOOL result;
2909 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2910 goto error;
2911 if (!convert_to_unicode(&o1))
2912 goto error;
2913 if (!convert_to_unicode(&o2)) {
2914 Py_DECREF(o1);
2915 goto error;
2916 }
2917 Py_BEGIN_ALLOW_THREADS
2918 result = MoveFileW(PyUnicode_AsUnicode(o1),
2919 PyUnicode_AsUnicode(o2));
2920 Py_END_ALLOW_THREADS
2921 Py_DECREF(o1);
2922 Py_DECREF(o2);
2923 if (!result)
2924 return win32_error("rename", NULL);
2925 Py_INCREF(Py_None);
2926 return Py_None;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002927error:
Victor Stinner8c62be82010-05-06 00:08:46 +00002928 PyErr_Clear();
2929 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2930 return NULL;
2931 Py_BEGIN_ALLOW_THREADS
2932 result = MoveFileA(p1, p2);
2933 Py_END_ALLOW_THREADS
2934 if (!result)
2935 return win32_error("rename", NULL);
2936 Py_INCREF(Py_None);
2937 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002938#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002939 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002940#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002941}
2942
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002943
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002944PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002945"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002946Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002947
Barry Warsaw53699e91996-12-10 23:23:01 +00002948static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002949posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002950{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002951#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002952 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002953#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002954 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002955#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002956}
2957
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002958
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002959PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002960"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002961Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002962
Barry Warsaw53699e91996-12-10 23:23:01 +00002963static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002964posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002965{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002966#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00002967 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002968#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002969 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002970#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002971}
2972
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002973
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002974#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002975PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002976"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002977Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002978
Barry Warsaw53699e91996-12-10 23:23:01 +00002979static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002980posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002981{
Victor Stinner8c62be82010-05-06 00:08:46 +00002982 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002983#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002984 wchar_t *command;
2985 if (!PyArg_ParseTuple(args, "u:system", &command))
2986 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00002987
Victor Stinner8c62be82010-05-06 00:08:46 +00002988 Py_BEGIN_ALLOW_THREADS
2989 sts = _wsystem(command);
2990 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00002991#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002992 PyObject *command_obj;
2993 char *command;
2994 if (!PyArg_ParseTuple(args, "O&:system",
2995 PyUnicode_FSConverter, &command_obj))
2996 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00002997
Victor Stinner8c62be82010-05-06 00:08:46 +00002998 command = PyBytes_AsString(command_obj);
2999 Py_BEGIN_ALLOW_THREADS
3000 sts = system(command);
3001 Py_END_ALLOW_THREADS
3002 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00003003#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003004 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003005}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003006#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003007
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003008
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003009PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003010"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003011Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003012
Barry Warsaw53699e91996-12-10 23:23:01 +00003013static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003014posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003015{
Victor Stinner8c62be82010-05-06 00:08:46 +00003016 int i;
3017 if (!PyArg_ParseTuple(args, "i:umask", &i))
3018 return NULL;
3019 i = (int)umask(i);
3020 if (i < 0)
3021 return posix_error();
3022 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003023}
3024
Brian Curtind40e6f72010-07-08 21:39:08 +00003025#ifdef MS_WINDOWS
3026
3027/* override the default DeleteFileW behavior so that directory
3028symlinks can be removed with this function, the same as with
3029Unix symlinks */
3030BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
3031{
3032 WIN32_FILE_ATTRIBUTE_DATA info;
3033 WIN32_FIND_DATAW find_data;
3034 HANDLE find_data_handle;
3035 int is_directory = 0;
3036 int is_link = 0;
3037
3038 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3039 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
3040
3041 /* Get WIN32_FIND_DATA structure for the path to determine if
3042 it is a symlink */
3043 if(is_directory &&
3044 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3045 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3046
3047 if(find_data_handle != INVALID_HANDLE_VALUE) {
3048 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3049 FindClose(find_data_handle);
3050 }
3051 }
3052 }
3053
3054 if (is_directory && is_link)
3055 return RemoveDirectoryW(lpFileName);
3056
3057 return DeleteFileW(lpFileName);
3058}
3059#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003060
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003061PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003062"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003063Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003064
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003065PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003066"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003067Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003068
Barry Warsaw53699e91996-12-10 23:23:01 +00003069static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003070posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003071{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003072#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003073 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3074 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003075#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003076 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003077#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003078}
3079
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003080
Guido van Rossumb6775db1994-08-01 11:34:53 +00003081#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003082PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003083"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003084Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003085
Barry Warsaw53699e91996-12-10 23:23:01 +00003086static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003087posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003088{
Victor Stinner8c62be82010-05-06 00:08:46 +00003089 struct utsname u;
3090 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003091
Victor Stinner8c62be82010-05-06 00:08:46 +00003092 Py_BEGIN_ALLOW_THREADS
3093 res = uname(&u);
3094 Py_END_ALLOW_THREADS
3095 if (res < 0)
3096 return posix_error();
3097 return Py_BuildValue("(sssss)",
3098 u.sysname,
3099 u.nodename,
3100 u.release,
3101 u.version,
3102 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003103}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003104#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003105
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003106static int
3107extract_time(PyObject *t, long* sec, long* usec)
3108{
Victor Stinner8c62be82010-05-06 00:08:46 +00003109 long intval;
3110 if (PyFloat_Check(t)) {
3111 double tval = PyFloat_AsDouble(t);
3112 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
3113 if (!intobj)
3114 return -1;
3115 intval = PyLong_AsLong(intobj);
3116 Py_DECREF(intobj);
3117 if (intval == -1 && PyErr_Occurred())
3118 return -1;
3119 *sec = intval;
3120 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
3121 if (*usec < 0)
3122 /* If rounding gave us a negative number,
3123 truncate. */
3124 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00003125 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003126 }
3127 intval = PyLong_AsLong(t);
3128 if (intval == -1 && PyErr_Occurred())
3129 return -1;
3130 *sec = intval;
3131 *usec = 0;
3132 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003133}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003134
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003135PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00003136"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00003137utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00003138Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003139second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003140
Barry Warsaw53699e91996-12-10 23:23:01 +00003141static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003142posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003143{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003144#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003145 PyObject *arg;
3146 PyUnicodeObject *obwpath;
3147 wchar_t *wpath = NULL;
3148 PyObject *oapath;
3149 char *apath;
3150 HANDLE hFile;
3151 long atimesec, mtimesec, ausec, musec;
3152 FILETIME atime, mtime;
3153 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003154
Victor Stinner8c62be82010-05-06 00:08:46 +00003155 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
3156 wpath = PyUnicode_AS_UNICODE(obwpath);
3157 Py_BEGIN_ALLOW_THREADS
3158 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3159 NULL, OPEN_EXISTING,
3160 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3161 Py_END_ALLOW_THREADS
3162 if (hFile == INVALID_HANDLE_VALUE)
3163 return win32_error_unicode("utime", wpath);
3164 } else
3165 /* Drop the argument parsing error as narrow strings
3166 are also valid. */
3167 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003168
Victor Stinner8c62be82010-05-06 00:08:46 +00003169 if (!wpath) {
3170 if (!PyArg_ParseTuple(args, "O&O:utime",
3171 PyUnicode_FSConverter, &oapath, &arg))
3172 return NULL;
3173 apath = PyBytes_AsString(oapath);
3174 Py_BEGIN_ALLOW_THREADS
3175 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3176 NULL, OPEN_EXISTING,
3177 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3178 Py_END_ALLOW_THREADS
3179 if (hFile == INVALID_HANDLE_VALUE) {
3180 win32_error("utime", apath);
3181 Py_DECREF(oapath);
3182 return NULL;
3183 }
3184 Py_DECREF(oapath);
3185 }
3186
3187 if (arg == Py_None) {
3188 SYSTEMTIME now;
3189 GetSystemTime(&now);
3190 if (!SystemTimeToFileTime(&now, &mtime) ||
3191 !SystemTimeToFileTime(&now, &atime)) {
3192 win32_error("utime", NULL);
3193 goto done;
Stefan Krah0e803b32010-11-26 16:16:47 +00003194 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003195 }
3196 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3197 PyErr_SetString(PyExc_TypeError,
3198 "utime() arg 2 must be a tuple (atime, mtime)");
3199 goto done;
3200 }
3201 else {
3202 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3203 &atimesec, &ausec) == -1)
3204 goto done;
3205 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3206 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3207 &mtimesec, &musec) == -1)
3208 goto done;
3209 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3210 }
3211 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3212 /* Avoid putting the file name into the error here,
3213 as that may confuse the user into believing that
3214 something is wrong with the file, when it also
3215 could be the time stamp that gives a problem. */
3216 win32_error("utime", NULL);
3217 }
3218 Py_INCREF(Py_None);
3219 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003220done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003221 CloseHandle(hFile);
3222 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003223#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003224
Victor Stinner8c62be82010-05-06 00:08:46 +00003225 PyObject *opath;
3226 char *path;
3227 long atime, mtime, ausec, musec;
3228 int res;
3229 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003230
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003231#if defined(HAVE_UTIMES)
Victor Stinner8c62be82010-05-06 00:08:46 +00003232 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003233#define ATIME buf[0].tv_sec
3234#define MTIME buf[1].tv_sec
3235#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003236/* XXX should define struct utimbuf instead, above */
Victor Stinner8c62be82010-05-06 00:08:46 +00003237 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003238#define ATIME buf.actime
3239#define MTIME buf.modtime
3240#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003241#else /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003242 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003243#define ATIME buf[0]
3244#define MTIME buf[1]
3245#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003246#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003247
Mark Hammond817c9292003-12-03 01:22:38 +00003248
Victor Stinner8c62be82010-05-06 00:08:46 +00003249 if (!PyArg_ParseTuple(args, "O&O:utime",
3250 PyUnicode_FSConverter, &opath, &arg))
3251 return NULL;
3252 path = PyBytes_AsString(opath);
3253 if (arg == Py_None) {
3254 /* optional time values not given */
3255 Py_BEGIN_ALLOW_THREADS
3256 res = utime(path, NULL);
3257 Py_END_ALLOW_THREADS
3258 }
3259 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3260 PyErr_SetString(PyExc_TypeError,
3261 "utime() arg 2 must be a tuple (atime, mtime)");
3262 Py_DECREF(opath);
3263 return NULL;
3264 }
3265 else {
3266 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3267 &atime, &ausec) == -1) {
3268 Py_DECREF(opath);
3269 return NULL;
3270 }
3271 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3272 &mtime, &musec) == -1) {
3273 Py_DECREF(opath);
3274 return NULL;
3275 }
3276 ATIME = atime;
3277 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003278#ifdef HAVE_UTIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00003279 buf[0].tv_usec = ausec;
3280 buf[1].tv_usec = musec;
3281 Py_BEGIN_ALLOW_THREADS
3282 res = utimes(path, buf);
3283 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003284#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003285 Py_BEGIN_ALLOW_THREADS
3286 res = utime(path, UTIME_ARG);
3287 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003288#endif /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003289 }
3290 if (res < 0) {
3291 return posix_error_with_allocated_filename(opath);
3292 }
3293 Py_DECREF(opath);
3294 Py_INCREF(Py_None);
3295 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003296#undef UTIME_ARG
3297#undef ATIME
3298#undef MTIME
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003299#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003300}
3301
Guido van Rossum85e3b011991-06-03 12:42:10 +00003302
Guido van Rossum3b066191991-06-04 19:40:25 +00003303/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003304
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003305PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003306"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003307Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003308
Barry Warsaw53699e91996-12-10 23:23:01 +00003309static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003310posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003311{
Victor Stinner8c62be82010-05-06 00:08:46 +00003312 int sts;
3313 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3314 return NULL;
3315 _exit(sts);
3316 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003317}
3318
Martin v. Löwis114619e2002-10-07 06:44:21 +00003319#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3320static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003321free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003322{
Victor Stinner8c62be82010-05-06 00:08:46 +00003323 Py_ssize_t i;
3324 for (i = 0; i < count; i++)
3325 PyMem_Free(array[i]);
3326 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003327}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003328
Antoine Pitrou69f71142009-05-24 21:25:49 +00003329static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003330int fsconvert_strdup(PyObject *o, char**out)
3331{
Victor Stinner8c62be82010-05-06 00:08:46 +00003332 PyObject *bytes;
3333 Py_ssize_t size;
3334 if (!PyUnicode_FSConverter(o, &bytes))
3335 return 0;
3336 size = PyBytes_GET_SIZE(bytes);
3337 *out = PyMem_Malloc(size+1);
3338 if (!*out)
3339 return 0;
3340 memcpy(*out, PyBytes_AsString(bytes), size+1);
3341 Py_DECREF(bytes);
3342 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003343}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003344#endif
3345
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003346
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003347#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003348PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003349"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003350Execute an executable path with arguments, replacing current process.\n\
3351\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003352 path: path of executable file\n\
3353 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003354
Barry Warsaw53699e91996-12-10 23:23:01 +00003355static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003356posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003357{
Victor Stinner8c62be82010-05-06 00:08:46 +00003358 PyObject *opath;
3359 char *path;
3360 PyObject *argv;
3361 char **argvlist;
3362 Py_ssize_t i, argc;
3363 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003364
Victor Stinner8c62be82010-05-06 00:08:46 +00003365 /* execv has two arguments: (path, argv), where
3366 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003367
Victor Stinner8c62be82010-05-06 00:08:46 +00003368 if (!PyArg_ParseTuple(args, "O&O:execv",
3369 PyUnicode_FSConverter,
3370 &opath, &argv))
3371 return NULL;
3372 path = PyBytes_AsString(opath);
3373 if (PyList_Check(argv)) {
3374 argc = PyList_Size(argv);
3375 getitem = PyList_GetItem;
3376 }
3377 else if (PyTuple_Check(argv)) {
3378 argc = PyTuple_Size(argv);
3379 getitem = PyTuple_GetItem;
3380 }
3381 else {
3382 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3383 Py_DECREF(opath);
3384 return NULL;
3385 }
3386 if (argc < 1) {
3387 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3388 Py_DECREF(opath);
3389 return NULL;
3390 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003391
Victor Stinner8c62be82010-05-06 00:08:46 +00003392 argvlist = PyMem_NEW(char *, argc+1);
3393 if (argvlist == NULL) {
3394 Py_DECREF(opath);
3395 return PyErr_NoMemory();
3396 }
3397 for (i = 0; i < argc; i++) {
3398 if (!fsconvert_strdup((*getitem)(argv, i),
3399 &argvlist[i])) {
3400 free_string_array(argvlist, i);
3401 PyErr_SetString(PyExc_TypeError,
3402 "execv() arg 2 must contain only strings");
3403 Py_DECREF(opath);
3404 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003405
Victor Stinner8c62be82010-05-06 00:08:46 +00003406 }
3407 }
3408 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003409
Victor Stinner8c62be82010-05-06 00:08:46 +00003410 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003411
Victor Stinner8c62be82010-05-06 00:08:46 +00003412 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003413
Victor Stinner8c62be82010-05-06 00:08:46 +00003414 free_string_array(argvlist, argc);
3415 Py_DECREF(opath);
3416 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003417}
3418
Victor Stinner13bb71c2010-04-23 21:41:56 +00003419static char**
3420parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3421{
Victor Stinner8c62be82010-05-06 00:08:46 +00003422 char **envlist;
3423 Py_ssize_t i, pos, envc;
3424 PyObject *keys=NULL, *vals=NULL;
3425 PyObject *key, *val, *key2, *val2;
3426 char *p, *k, *v;
3427 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003428
Victor Stinner8c62be82010-05-06 00:08:46 +00003429 i = PyMapping_Size(env);
3430 if (i < 0)
3431 return NULL;
3432 envlist = PyMem_NEW(char *, i + 1);
3433 if (envlist == NULL) {
3434 PyErr_NoMemory();
3435 return NULL;
3436 }
3437 envc = 0;
3438 keys = PyMapping_Keys(env);
3439 vals = PyMapping_Values(env);
3440 if (!keys || !vals)
3441 goto error;
3442 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3443 PyErr_Format(PyExc_TypeError,
3444 "env.keys() or env.values() is not a list");
3445 goto error;
3446 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003447
Victor Stinner8c62be82010-05-06 00:08:46 +00003448 for (pos = 0; pos < i; pos++) {
3449 key = PyList_GetItem(keys, pos);
3450 val = PyList_GetItem(vals, pos);
3451 if (!key || !val)
3452 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003453
Victor Stinner8c62be82010-05-06 00:08:46 +00003454 if (PyUnicode_FSConverter(key, &key2) == 0)
3455 goto error;
3456 if (PyUnicode_FSConverter(val, &val2) == 0) {
3457 Py_DECREF(key2);
3458 goto error;
3459 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003460
3461#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003462 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3463 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00003464#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003465 k = PyBytes_AsString(key2);
3466 v = PyBytes_AsString(val2);
3467 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003468
Victor Stinner8c62be82010-05-06 00:08:46 +00003469 p = PyMem_NEW(char, len);
3470 if (p == NULL) {
3471 PyErr_NoMemory();
3472 Py_DECREF(key2);
3473 Py_DECREF(val2);
3474 goto error;
3475 }
3476 PyOS_snprintf(p, len, "%s=%s", k, v);
3477 envlist[envc++] = p;
3478 Py_DECREF(key2);
3479 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003480#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003481 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003482#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003483 }
3484 Py_DECREF(vals);
3485 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003486
Victor Stinner8c62be82010-05-06 00:08:46 +00003487 envlist[envc] = 0;
3488 *envc_ptr = envc;
3489 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003490
3491error:
Victor Stinner8c62be82010-05-06 00:08:46 +00003492 Py_XDECREF(keys);
3493 Py_XDECREF(vals);
3494 while (--envc >= 0)
3495 PyMem_DEL(envlist[envc]);
3496 PyMem_DEL(envlist);
3497 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003498}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003499
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003500PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003501"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003502Execute a path with arguments and environment, replacing current process.\n\
3503\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003504 path: path of executable file\n\
3505 args: tuple or list of arguments\n\
3506 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003507
Barry Warsaw53699e91996-12-10 23:23:01 +00003508static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003509posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003510{
Victor Stinner8c62be82010-05-06 00:08:46 +00003511 PyObject *opath;
3512 char *path;
3513 PyObject *argv, *env;
3514 char **argvlist;
3515 char **envlist;
3516 Py_ssize_t i, argc, envc;
3517 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3518 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003519
Victor Stinner8c62be82010-05-06 00:08:46 +00003520 /* execve has three arguments: (path, argv, env), where
3521 argv is a list or tuple of strings and env is a dictionary
3522 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003523
Victor Stinner8c62be82010-05-06 00:08:46 +00003524 if (!PyArg_ParseTuple(args, "O&OO:execve",
3525 PyUnicode_FSConverter,
3526 &opath, &argv, &env))
3527 return NULL;
3528 path = PyBytes_AsString(opath);
3529 if (PyList_Check(argv)) {
3530 argc = PyList_Size(argv);
3531 getitem = PyList_GetItem;
3532 }
3533 else if (PyTuple_Check(argv)) {
3534 argc = PyTuple_Size(argv);
3535 getitem = PyTuple_GetItem;
3536 }
3537 else {
3538 PyErr_SetString(PyExc_TypeError,
3539 "execve() arg 2 must be a tuple or list");
3540 goto fail_0;
3541 }
3542 if (!PyMapping_Check(env)) {
3543 PyErr_SetString(PyExc_TypeError,
3544 "execve() arg 3 must be a mapping object");
3545 goto fail_0;
3546 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003547
Victor Stinner8c62be82010-05-06 00:08:46 +00003548 argvlist = PyMem_NEW(char *, argc+1);
3549 if (argvlist == NULL) {
3550 PyErr_NoMemory();
3551 goto fail_0;
3552 }
3553 for (i = 0; i < argc; i++) {
3554 if (!fsconvert_strdup((*getitem)(argv, i),
3555 &argvlist[i]))
3556 {
3557 lastarg = i;
3558 goto fail_1;
3559 }
3560 }
3561 lastarg = argc;
3562 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003563
Victor Stinner8c62be82010-05-06 00:08:46 +00003564 envlist = parse_envlist(env, &envc);
3565 if (envlist == NULL)
3566 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003567
Victor Stinner8c62be82010-05-06 00:08:46 +00003568 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003569
Victor Stinner8c62be82010-05-06 00:08:46 +00003570 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003571
Victor Stinner8c62be82010-05-06 00:08:46 +00003572 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003573
Victor Stinner8c62be82010-05-06 00:08:46 +00003574 while (--envc >= 0)
3575 PyMem_DEL(envlist[envc]);
3576 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003577 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003578 free_string_array(argvlist, lastarg);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003579 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003580 Py_DECREF(opath);
3581 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003582}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003583#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003584
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003585
Guido van Rossuma1065681999-01-25 23:20:23 +00003586#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003587PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003588"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003589Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003590\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003591 mode: mode of process creation\n\
3592 path: path of executable file\n\
3593 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003594
3595static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003596posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003597{
Victor Stinner8c62be82010-05-06 00:08:46 +00003598 PyObject *opath;
3599 char *path;
3600 PyObject *argv;
3601 char **argvlist;
3602 int mode, i;
3603 Py_ssize_t argc;
3604 Py_intptr_t spawnval;
3605 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003606
Victor Stinner8c62be82010-05-06 00:08:46 +00003607 /* spawnv has three arguments: (mode, path, argv), where
3608 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003609
Victor Stinner8c62be82010-05-06 00:08:46 +00003610 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3611 PyUnicode_FSConverter,
3612 &opath, &argv))
3613 return NULL;
3614 path = PyBytes_AsString(opath);
3615 if (PyList_Check(argv)) {
3616 argc = PyList_Size(argv);
3617 getitem = PyList_GetItem;
3618 }
3619 else if (PyTuple_Check(argv)) {
3620 argc = PyTuple_Size(argv);
3621 getitem = PyTuple_GetItem;
3622 }
3623 else {
3624 PyErr_SetString(PyExc_TypeError,
3625 "spawnv() arg 2 must be a tuple or list");
3626 Py_DECREF(opath);
3627 return NULL;
3628 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003629
Victor Stinner8c62be82010-05-06 00:08:46 +00003630 argvlist = PyMem_NEW(char *, argc+1);
3631 if (argvlist == NULL) {
3632 Py_DECREF(opath);
3633 return PyErr_NoMemory();
3634 }
3635 for (i = 0; i < argc; i++) {
3636 if (!fsconvert_strdup((*getitem)(argv, i),
3637 &argvlist[i])) {
3638 free_string_array(argvlist, i);
3639 PyErr_SetString(
3640 PyExc_TypeError,
3641 "spawnv() arg 2 must contain only strings");
3642 Py_DECREF(opath);
3643 return NULL;
3644 }
3645 }
3646 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003647
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003648#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003649 Py_BEGIN_ALLOW_THREADS
3650 spawnval = spawnv(mode, path, argvlist);
3651 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003652#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003653 if (mode == _OLD_P_OVERLAY)
3654 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003655
Victor Stinner8c62be82010-05-06 00:08:46 +00003656 Py_BEGIN_ALLOW_THREADS
3657 spawnval = _spawnv(mode, path, argvlist);
3658 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003659#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003660
Victor Stinner8c62be82010-05-06 00:08:46 +00003661 free_string_array(argvlist, argc);
3662 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003663
Victor Stinner8c62be82010-05-06 00:08:46 +00003664 if (spawnval == -1)
3665 return posix_error();
3666 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003667#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003668 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003669#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003670 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003671#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003672}
3673
3674
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003675PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003676"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003677Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003678\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003679 mode: mode of process creation\n\
3680 path: path of executable file\n\
3681 args: tuple or list of arguments\n\
3682 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003683
3684static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003685posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003686{
Victor Stinner8c62be82010-05-06 00:08:46 +00003687 PyObject *opath;
3688 char *path;
3689 PyObject *argv, *env;
3690 char **argvlist;
3691 char **envlist;
3692 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003693 int mode;
3694 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003695 Py_intptr_t spawnval;
3696 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3697 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003698
Victor Stinner8c62be82010-05-06 00:08:46 +00003699 /* spawnve has four arguments: (mode, path, argv, env), where
3700 argv is a list or tuple of strings and env is a dictionary
3701 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003702
Victor Stinner8c62be82010-05-06 00:08:46 +00003703 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3704 PyUnicode_FSConverter,
3705 &opath, &argv, &env))
3706 return NULL;
3707 path = PyBytes_AsString(opath);
3708 if (PyList_Check(argv)) {
3709 argc = PyList_Size(argv);
3710 getitem = PyList_GetItem;
3711 }
3712 else if (PyTuple_Check(argv)) {
3713 argc = PyTuple_Size(argv);
3714 getitem = PyTuple_GetItem;
3715 }
3716 else {
3717 PyErr_SetString(PyExc_TypeError,
3718 "spawnve() arg 2 must be a tuple or list");
3719 goto fail_0;
3720 }
3721 if (!PyMapping_Check(env)) {
3722 PyErr_SetString(PyExc_TypeError,
3723 "spawnve() arg 3 must be a mapping object");
3724 goto fail_0;
3725 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003726
Victor Stinner8c62be82010-05-06 00:08:46 +00003727 argvlist = PyMem_NEW(char *, argc+1);
3728 if (argvlist == NULL) {
3729 PyErr_NoMemory();
3730 goto fail_0;
3731 }
3732 for (i = 0; i < argc; i++) {
3733 if (!fsconvert_strdup((*getitem)(argv, i),
3734 &argvlist[i]))
3735 {
3736 lastarg = i;
3737 goto fail_1;
3738 }
3739 }
3740 lastarg = argc;
3741 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003742
Victor Stinner8c62be82010-05-06 00:08:46 +00003743 envlist = parse_envlist(env, &envc);
3744 if (envlist == NULL)
3745 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003746
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003747#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003748 Py_BEGIN_ALLOW_THREADS
3749 spawnval = spawnve(mode, path, argvlist, envlist);
3750 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003751#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003752 if (mode == _OLD_P_OVERLAY)
3753 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003754
Victor Stinner8c62be82010-05-06 00:08:46 +00003755 Py_BEGIN_ALLOW_THREADS
3756 spawnval = _spawnve(mode, path, argvlist, envlist);
3757 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003758#endif
Tim Peters25059d32001-12-07 20:35:43 +00003759
Victor Stinner8c62be82010-05-06 00:08:46 +00003760 if (spawnval == -1)
3761 (void) posix_error();
3762 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003763#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003764 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003765#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003766 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003767#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003768
Victor Stinner8c62be82010-05-06 00:08:46 +00003769 while (--envc >= 0)
3770 PyMem_DEL(envlist[envc]);
3771 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003772 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003773 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003774 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003775 Py_DECREF(opath);
3776 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003777}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003778
3779/* OS/2 supports spawnvp & spawnvpe natively */
3780#if defined(PYOS_OS2)
3781PyDoc_STRVAR(posix_spawnvp__doc__,
3782"spawnvp(mode, file, args)\n\n\
3783Execute the program 'file' in a new process, using the environment\n\
3784search path to find the file.\n\
3785\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003786 mode: mode of process creation\n\
3787 file: executable file name\n\
3788 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003789
3790static PyObject *
3791posix_spawnvp(PyObject *self, PyObject *args)
3792{
Victor Stinner8c62be82010-05-06 00:08:46 +00003793 PyObject *opath;
3794 char *path;
3795 PyObject *argv;
3796 char **argvlist;
3797 int mode, i, argc;
3798 Py_intptr_t spawnval;
3799 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003800
Victor Stinner8c62be82010-05-06 00:08:46 +00003801 /* spawnvp has three arguments: (mode, path, argv), where
3802 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003803
Victor Stinner8c62be82010-05-06 00:08:46 +00003804 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3805 PyUnicode_FSConverter,
3806 &opath, &argv))
3807 return NULL;
3808 path = PyBytes_AsString(opath);
3809 if (PyList_Check(argv)) {
3810 argc = PyList_Size(argv);
3811 getitem = PyList_GetItem;
3812 }
3813 else if (PyTuple_Check(argv)) {
3814 argc = PyTuple_Size(argv);
3815 getitem = PyTuple_GetItem;
3816 }
3817 else {
3818 PyErr_SetString(PyExc_TypeError,
3819 "spawnvp() arg 2 must be a tuple or list");
3820 Py_DECREF(opath);
3821 return NULL;
3822 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003823
Victor Stinner8c62be82010-05-06 00:08:46 +00003824 argvlist = PyMem_NEW(char *, argc+1);
3825 if (argvlist == NULL) {
3826 Py_DECREF(opath);
3827 return PyErr_NoMemory();
3828 }
3829 for (i = 0; i < argc; i++) {
3830 if (!fsconvert_strdup((*getitem)(argv, i),
3831 &argvlist[i])) {
3832 free_string_array(argvlist, i);
3833 PyErr_SetString(
3834 PyExc_TypeError,
3835 "spawnvp() arg 2 must contain only strings");
3836 Py_DECREF(opath);
3837 return NULL;
3838 }
3839 }
3840 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003841
Victor Stinner8c62be82010-05-06 00:08:46 +00003842 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003843#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003844 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003845#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003846 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003847#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003848 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003849
Victor Stinner8c62be82010-05-06 00:08:46 +00003850 free_string_array(argvlist, argc);
3851 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003852
Victor Stinner8c62be82010-05-06 00:08:46 +00003853 if (spawnval == -1)
3854 return posix_error();
3855 else
3856 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003857}
3858
3859
3860PyDoc_STRVAR(posix_spawnvpe__doc__,
3861"spawnvpe(mode, file, args, env)\n\n\
3862Execute the program 'file' in a new process, using the environment\n\
3863search path to find the file.\n\
3864\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003865 mode: mode of process creation\n\
3866 file: executable file name\n\
3867 args: tuple or list of arguments\n\
3868 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003869
3870static PyObject *
3871posix_spawnvpe(PyObject *self, PyObject *args)
3872{
Victor Stinner8c62be82010-05-06 00:08:46 +00003873 PyObject *opath
3874 char *path;
3875 PyObject *argv, *env;
3876 char **argvlist;
3877 char **envlist;
3878 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003879 int mode;
3880 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003881 Py_intptr_t spawnval;
3882 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3883 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003884
Victor Stinner8c62be82010-05-06 00:08:46 +00003885 /* spawnvpe has four arguments: (mode, path, argv, env), where
3886 argv is a list or tuple of strings and env is a dictionary
3887 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003888
Victor Stinner8c62be82010-05-06 00:08:46 +00003889 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3890 PyUnicode_FSConverter,
3891 &opath, &argv, &env))
3892 return NULL;
3893 path = PyBytes_AsString(opath);
3894 if (PyList_Check(argv)) {
3895 argc = PyList_Size(argv);
3896 getitem = PyList_GetItem;
3897 }
3898 else if (PyTuple_Check(argv)) {
3899 argc = PyTuple_Size(argv);
3900 getitem = PyTuple_GetItem;
3901 }
3902 else {
3903 PyErr_SetString(PyExc_TypeError,
3904 "spawnvpe() arg 2 must be a tuple or list");
3905 goto fail_0;
3906 }
3907 if (!PyMapping_Check(env)) {
3908 PyErr_SetString(PyExc_TypeError,
3909 "spawnvpe() arg 3 must be a mapping object");
3910 goto fail_0;
3911 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003912
Victor Stinner8c62be82010-05-06 00:08:46 +00003913 argvlist = PyMem_NEW(char *, argc+1);
3914 if (argvlist == NULL) {
3915 PyErr_NoMemory();
3916 goto fail_0;
3917 }
3918 for (i = 0; i < argc; i++) {
3919 if (!fsconvert_strdup((*getitem)(argv, i),
3920 &argvlist[i]))
3921 {
3922 lastarg = i;
3923 goto fail_1;
3924 }
3925 }
3926 lastarg = argc;
3927 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003928
Victor Stinner8c62be82010-05-06 00:08:46 +00003929 envlist = parse_envlist(env, &envc);
3930 if (envlist == NULL)
3931 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003932
Victor Stinner8c62be82010-05-06 00:08:46 +00003933 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003934#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003935 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003936#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003937 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003938#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003939 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003940
Victor Stinner8c62be82010-05-06 00:08:46 +00003941 if (spawnval == -1)
3942 (void) posix_error();
3943 else
3944 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003945
Victor Stinner8c62be82010-05-06 00:08:46 +00003946 while (--envc >= 0)
3947 PyMem_DEL(envlist[envc]);
3948 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003949 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003950 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003951 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003952 Py_DECREF(opath);
3953 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003954}
3955#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003956#endif /* HAVE_SPAWNV */
3957
3958
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003959#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003960PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003961"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003962Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3963\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003964Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003965
3966static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003967posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003968{
Victor Stinner8c62be82010-05-06 00:08:46 +00003969 pid_t pid;
3970 int result = 0;
3971 _PyImport_AcquireLock();
3972 pid = fork1();
3973 if (pid == 0) {
3974 /* child: this clobbers and resets the import lock. */
3975 PyOS_AfterFork();
3976 } else {
3977 /* parent: release the import lock. */
3978 result = _PyImport_ReleaseLock();
3979 }
3980 if (pid == -1)
3981 return posix_error();
3982 if (result < 0) {
3983 /* Don't clobber the OSError if the fork failed. */
3984 PyErr_SetString(PyExc_RuntimeError,
3985 "not holding the import lock");
3986 return NULL;
3987 }
3988 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003989}
3990#endif
3991
3992
Guido van Rossumad0ee831995-03-01 10:34:45 +00003993#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003994PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003995"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003996Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003997Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003998
Barry Warsaw53699e91996-12-10 23:23:01 +00003999static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004000posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004001{
Victor Stinner8c62be82010-05-06 00:08:46 +00004002 pid_t pid;
4003 int result = 0;
4004 _PyImport_AcquireLock();
4005 pid = fork();
4006 if (pid == 0) {
4007 /* child: this clobbers and resets the import lock. */
4008 PyOS_AfterFork();
4009 } else {
4010 /* parent: release the import lock. */
4011 result = _PyImport_ReleaseLock();
4012 }
4013 if (pid == -1)
4014 return posix_error();
4015 if (result < 0) {
4016 /* Don't clobber the OSError if the fork failed. */
4017 PyErr_SetString(PyExc_RuntimeError,
4018 "not holding the import lock");
4019 return NULL;
4020 }
4021 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00004022}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004023#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004024
Neal Norwitzb59798b2003-03-21 01:43:31 +00004025/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00004026/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
4027#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00004028#define DEV_PTY_FILE "/dev/ptc"
4029#define HAVE_DEV_PTMX
4030#else
4031#define DEV_PTY_FILE "/dev/ptmx"
4032#endif
4033
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004034#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004035#ifdef HAVE_PTY_H
4036#include <pty.h>
4037#else
4038#ifdef HAVE_LIBUTIL_H
4039#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00004040#else
4041#ifdef HAVE_UTIL_H
4042#include <util.h>
4043#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004044#endif /* HAVE_LIBUTIL_H */
4045#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00004046#ifdef HAVE_STROPTS_H
4047#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004048#endif
4049#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004050
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004051#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004052PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004053"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004054Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004055
4056static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004057posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004058{
Victor Stinner8c62be82010-05-06 00:08:46 +00004059 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004060#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004061 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004062#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004063#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004064 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004065#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00004066 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004067#endif
4068#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00004069
Thomas Wouters70c21a12000-07-14 14:28:33 +00004070#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004071 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
4072 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004073#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004074 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
4075 if (slave_name == NULL)
4076 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00004077
Victor Stinner8c62be82010-05-06 00:08:46 +00004078 slave_fd = open(slave_name, O_RDWR);
4079 if (slave_fd < 0)
4080 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004081#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004082 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
4083 if (master_fd < 0)
4084 return posix_error();
4085 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
4086 /* change permission of slave */
4087 if (grantpt(master_fd) < 0) {
4088 PyOS_setsig(SIGCHLD, sig_saved);
4089 return posix_error();
4090 }
4091 /* unlock slave */
4092 if (unlockpt(master_fd) < 0) {
4093 PyOS_setsig(SIGCHLD, sig_saved);
4094 return posix_error();
4095 }
4096 PyOS_setsig(SIGCHLD, sig_saved);
4097 slave_name = ptsname(master_fd); /* get name of slave */
4098 if (slave_name == NULL)
4099 return posix_error();
4100 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
4101 if (slave_fd < 0)
4102 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004103#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004104 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
4105 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00004106#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00004107 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00004108#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004109#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00004110#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00004111
Victor Stinner8c62be82010-05-06 00:08:46 +00004112 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00004113
Fred Drake8cef4cf2000-06-28 16:40:38 +00004114}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004115#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004116
4117#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004118PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004119"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00004120Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
4121Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004122To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004123
4124static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004125posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004126{
Victor Stinner8c62be82010-05-06 00:08:46 +00004127 int master_fd = -1, result = 0;
4128 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00004129
Victor Stinner8c62be82010-05-06 00:08:46 +00004130 _PyImport_AcquireLock();
4131 pid = forkpty(&master_fd, NULL, NULL, NULL);
4132 if (pid == 0) {
4133 /* child: this clobbers and resets the import lock. */
4134 PyOS_AfterFork();
4135 } else {
4136 /* parent: release the import lock. */
4137 result = _PyImport_ReleaseLock();
4138 }
4139 if (pid == -1)
4140 return posix_error();
4141 if (result < 0) {
4142 /* Don't clobber the OSError if the fork failed. */
4143 PyErr_SetString(PyExc_RuntimeError,
4144 "not holding the import lock");
4145 return NULL;
4146 }
4147 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004148}
4149#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004150
Guido van Rossumad0ee831995-03-01 10:34:45 +00004151#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004152PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004153"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004154Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004155
Barry Warsaw53699e91996-12-10 23:23:01 +00004156static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004157posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004158{
Victor Stinner8c62be82010-05-06 00:08:46 +00004159 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004160}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004161#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004162
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004163
Guido van Rossumad0ee831995-03-01 10:34:45 +00004164#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004165PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004166"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004167Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004168
Barry Warsaw53699e91996-12-10 23:23:01 +00004169static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004170posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004171{
Victor Stinner8c62be82010-05-06 00:08:46 +00004172 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004173}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004174#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004175
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004176
Guido van Rossumad0ee831995-03-01 10:34:45 +00004177#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004178PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004179"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004180Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004181
Barry Warsaw53699e91996-12-10 23:23:01 +00004182static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004183posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004184{
Victor Stinner8c62be82010-05-06 00:08:46 +00004185 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004186}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004187#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004188
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004189
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004190PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004191"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004192Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004193
Barry Warsaw53699e91996-12-10 23:23:01 +00004194static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004195posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004196{
Victor Stinner8c62be82010-05-06 00:08:46 +00004197 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004198}
4199
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004200
Fred Drakec9680921999-12-13 16:37:25 +00004201#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004202PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004203"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004204Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004205
4206static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004207posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004208{
4209 PyObject *result = NULL;
4210
Fred Drakec9680921999-12-13 16:37:25 +00004211#ifdef NGROUPS_MAX
4212#define MAX_GROUPS NGROUPS_MAX
4213#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004214 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004215#define MAX_GROUPS 64
4216#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004217 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004218
4219 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
4220 * This is a helper variable to store the intermediate result when
4221 * that happens.
4222 *
4223 * To keep the code readable the OSX behaviour is unconditional,
4224 * according to the POSIX spec this should be safe on all unix-y
4225 * systems.
4226 */
4227 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00004228 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004229
Victor Stinner8c62be82010-05-06 00:08:46 +00004230 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004231 if (n < 0) {
4232 if (errno == EINVAL) {
4233 n = getgroups(0, NULL);
4234 if (n == -1) {
4235 return posix_error();
4236 }
4237 if (n == 0) {
4238 /* Avoid malloc(0) */
4239 alt_grouplist = grouplist;
4240 } else {
4241 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4242 if (alt_grouplist == NULL) {
4243 errno = EINVAL;
4244 return posix_error();
4245 }
4246 n = getgroups(n, alt_grouplist);
4247 if (n == -1) {
4248 PyMem_Free(alt_grouplist);
4249 return posix_error();
4250 }
4251 }
4252 } else {
4253 return posix_error();
4254 }
4255 }
4256 result = PyList_New(n);
4257 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004258 int i;
4259 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004260 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00004261 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00004262 Py_DECREF(result);
4263 result = NULL;
4264 break;
Fred Drakec9680921999-12-13 16:37:25 +00004265 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004266 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004267 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004268 }
4269
4270 if (alt_grouplist != grouplist) {
4271 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00004272 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004273
Fred Drakec9680921999-12-13 16:37:25 +00004274 return result;
4275}
4276#endif
4277
Antoine Pitroub7572f02009-12-02 20:46:48 +00004278#ifdef HAVE_INITGROUPS
4279PyDoc_STRVAR(posix_initgroups__doc__,
4280"initgroups(username, gid) -> None\n\n\
4281Call the system initgroups() to initialize the group access list with all of\n\
4282the groups of which the specified username is a member, plus the specified\n\
4283group id.");
4284
4285static PyObject *
4286posix_initgroups(PyObject *self, PyObject *args)
4287{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004288 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00004289 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004290 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00004291 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004292
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004293 if (!PyArg_ParseTuple(args, "O&l:initgroups",
4294 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00004295 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004296 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004297
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004298 res = initgroups(username, (gid_t) gid);
4299 Py_DECREF(oname);
4300 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00004301 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004302
Victor Stinner8c62be82010-05-06 00:08:46 +00004303 Py_INCREF(Py_None);
4304 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004305}
4306#endif
4307
Martin v. Löwis606edc12002-06-13 21:09:11 +00004308#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004309PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004310"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004311Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004312
4313static PyObject *
4314posix_getpgid(PyObject *self, PyObject *args)
4315{
Victor Stinner8c62be82010-05-06 00:08:46 +00004316 pid_t pid, pgid;
4317 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
4318 return NULL;
4319 pgid = getpgid(pid);
4320 if (pgid < 0)
4321 return posix_error();
4322 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004323}
4324#endif /* HAVE_GETPGID */
4325
4326
Guido van Rossumb6775db1994-08-01 11:34:53 +00004327#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004328PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004329"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004330Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004331
Barry Warsaw53699e91996-12-10 23:23:01 +00004332static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004333posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004334{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004335#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004336 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004337#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004338 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004339#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004340}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004341#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004342
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004343
Guido van Rossumb6775db1994-08-01 11:34:53 +00004344#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004345PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004346"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00004347Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004348
Barry Warsaw53699e91996-12-10 23:23:01 +00004349static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004350posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004351{
Guido van Rossum64933891994-10-20 21:56:42 +00004352#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004353 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004354#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004355 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004356#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004357 return posix_error();
4358 Py_INCREF(Py_None);
4359 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004360}
4361
Guido van Rossumb6775db1994-08-01 11:34:53 +00004362#endif /* HAVE_SETPGRP */
4363
Guido van Rossumad0ee831995-03-01 10:34:45 +00004364#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004365
4366#ifdef MS_WINDOWS
4367#include <tlhelp32.h>
4368
4369static PyObject*
4370win32_getppid()
4371{
4372 HANDLE snapshot;
4373 pid_t mypid;
4374 PyObject* result = NULL;
4375 BOOL have_record;
4376 PROCESSENTRY32 pe;
4377
4378 mypid = getpid(); /* This function never fails */
4379
4380 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
4381 if (snapshot == INVALID_HANDLE_VALUE)
4382 return PyErr_SetFromWindowsErr(GetLastError());
4383
4384 pe.dwSize = sizeof(pe);
4385 have_record = Process32First(snapshot, &pe);
4386 while (have_record) {
4387 if (mypid == (pid_t)pe.th32ProcessID) {
4388 /* We could cache the ulong value in a static variable. */
4389 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
4390 break;
4391 }
4392
4393 have_record = Process32Next(snapshot, &pe);
4394 }
4395
4396 /* If our loop exits and our pid was not found (result will be NULL)
4397 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
4398 * error anyway, so let's raise it. */
4399 if (!result)
4400 result = PyErr_SetFromWindowsErr(GetLastError());
4401
4402 CloseHandle(snapshot);
4403
4404 return result;
4405}
4406#endif /*MS_WINDOWS*/
4407
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004408PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004409"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004410Return the parent's process id. If the parent process has already exited,\n\
4411Windows machines will still return its id; others systems will return the id\n\
4412of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004413
Barry Warsaw53699e91996-12-10 23:23:01 +00004414static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004415posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004416{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004417#ifdef MS_WINDOWS
4418 return win32_getppid();
4419#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004420 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00004421#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004422}
4423#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004424
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004425
Fred Drake12c6e2d1999-12-14 21:25:03 +00004426#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004427PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004428"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004429Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004430
4431static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004432posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004433{
Victor Stinner8c62be82010-05-06 00:08:46 +00004434 PyObject *result = NULL;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004435#ifdef MS_WINDOWS
4436 wchar_t user_name[UNLEN + 1];
4437 DWORD num_chars = sizeof(user_name)/sizeof(user_name[0]);
4438
4439 if (GetUserNameW(user_name, &num_chars)) {
4440 /* num_chars is the number of unicode chars plus null terminator */
4441 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
4442 }
4443 else
4444 result = PyErr_SetFromWindowsErr(GetLastError());
4445#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004446 char *name;
4447 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004448
Victor Stinner8c62be82010-05-06 00:08:46 +00004449 errno = 0;
4450 name = getlogin();
4451 if (name == NULL) {
4452 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00004453 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004454 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004455 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00004456 }
4457 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004458 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00004459 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004460#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00004461 return result;
4462}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004463#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00004464
Guido van Rossumad0ee831995-03-01 10:34:45 +00004465#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004466PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004467"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004468Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004469
Barry Warsaw53699e91996-12-10 23:23:01 +00004470static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004471posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004472{
Victor Stinner8c62be82010-05-06 00:08:46 +00004473 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004474}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004475#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004476
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004477
Guido van Rossumad0ee831995-03-01 10:34:45 +00004478#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004479PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004480"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004481Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004482
Barry Warsaw53699e91996-12-10 23:23:01 +00004483static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004484posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004485{
Victor Stinner8c62be82010-05-06 00:08:46 +00004486 pid_t pid;
4487 int sig;
4488 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
4489 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004490#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004491 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4492 APIRET rc;
4493 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004494 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004495
4496 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4497 APIRET rc;
4498 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004499 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004500
4501 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004502 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004503#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004504 if (kill(pid, sig) == -1)
4505 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004506#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004507 Py_INCREF(Py_None);
4508 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004509}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004510#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004511
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004512#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004513PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004514"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004515Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004516
4517static PyObject *
4518posix_killpg(PyObject *self, PyObject *args)
4519{
Victor Stinner8c62be82010-05-06 00:08:46 +00004520 int sig;
4521 pid_t pgid;
4522 /* XXX some man pages make the `pgid` parameter an int, others
4523 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4524 take the same type. Moreover, pid_t is always at least as wide as
4525 int (else compilation of this module fails), which is safe. */
4526 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
4527 return NULL;
4528 if (killpg(pgid, sig) == -1)
4529 return posix_error();
4530 Py_INCREF(Py_None);
4531 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004532}
4533#endif
4534
Brian Curtineb24d742010-04-12 17:16:38 +00004535#ifdef MS_WINDOWS
4536PyDoc_STRVAR(win32_kill__doc__,
4537"kill(pid, sig)\n\n\
4538Kill a process with a signal.");
4539
4540static PyObject *
4541win32_kill(PyObject *self, PyObject *args)
4542{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00004543 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004544 DWORD pid, sig, err;
4545 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00004546
Victor Stinner8c62be82010-05-06 00:08:46 +00004547 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4548 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00004549
Victor Stinner8c62be82010-05-06 00:08:46 +00004550 /* Console processes which share a common console can be sent CTRL+C or
4551 CTRL+BREAK events, provided they handle said events. */
4552 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4553 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4554 err = GetLastError();
4555 PyErr_SetFromWindowsErr(err);
4556 }
4557 else
4558 Py_RETURN_NONE;
4559 }
Brian Curtineb24d742010-04-12 17:16:38 +00004560
Victor Stinner8c62be82010-05-06 00:08:46 +00004561 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4562 attempt to open and terminate the process. */
4563 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4564 if (handle == NULL) {
4565 err = GetLastError();
4566 return PyErr_SetFromWindowsErr(err);
4567 }
Brian Curtineb24d742010-04-12 17:16:38 +00004568
Victor Stinner8c62be82010-05-06 00:08:46 +00004569 if (TerminateProcess(handle, sig) == 0) {
4570 err = GetLastError();
4571 result = PyErr_SetFromWindowsErr(err);
4572 } else {
4573 Py_INCREF(Py_None);
4574 result = Py_None;
4575 }
Brian Curtineb24d742010-04-12 17:16:38 +00004576
Victor Stinner8c62be82010-05-06 00:08:46 +00004577 CloseHandle(handle);
4578 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00004579}
4580#endif /* MS_WINDOWS */
4581
Guido van Rossumc0125471996-06-28 18:55:32 +00004582#ifdef HAVE_PLOCK
4583
4584#ifdef HAVE_SYS_LOCK_H
4585#include <sys/lock.h>
4586#endif
4587
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004588PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004589"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004590Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004591
Barry Warsaw53699e91996-12-10 23:23:01 +00004592static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004593posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004594{
Victor Stinner8c62be82010-05-06 00:08:46 +00004595 int op;
4596 if (!PyArg_ParseTuple(args, "i:plock", &op))
4597 return NULL;
4598 if (plock(op) == -1)
4599 return posix_error();
4600 Py_INCREF(Py_None);
4601 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004602}
4603#endif
4604
Guido van Rossumb6775db1994-08-01 11:34:53 +00004605#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004606PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004607"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004608Set the current process's user id.");
4609
Barry Warsaw53699e91996-12-10 23:23:01 +00004610static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004611posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004612{
Victor Stinner8c62be82010-05-06 00:08:46 +00004613 long uid_arg;
4614 uid_t uid;
4615 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
4616 return NULL;
4617 uid = uid_arg;
4618 if (uid != uid_arg) {
4619 PyErr_SetString(PyExc_OverflowError, "user id too big");
4620 return NULL;
4621 }
4622 if (setuid(uid) < 0)
4623 return posix_error();
4624 Py_INCREF(Py_None);
4625 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004626}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004627#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004628
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004629
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004630#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004631PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004632"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004633Set the current process's effective user id.");
4634
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004635static PyObject *
4636posix_seteuid (PyObject *self, PyObject *args)
4637{
Victor Stinner8c62be82010-05-06 00:08:46 +00004638 long euid_arg;
4639 uid_t euid;
4640 if (!PyArg_ParseTuple(args, "l", &euid_arg))
4641 return NULL;
4642 euid = euid_arg;
4643 if (euid != euid_arg) {
4644 PyErr_SetString(PyExc_OverflowError, "user id too big");
4645 return NULL;
4646 }
4647 if (seteuid(euid) < 0) {
4648 return posix_error();
4649 } else {
4650 Py_INCREF(Py_None);
4651 return Py_None;
4652 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004653}
4654#endif /* HAVE_SETEUID */
4655
4656#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004657PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004658"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004659Set the current process's effective group id.");
4660
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004661static PyObject *
4662posix_setegid (PyObject *self, PyObject *args)
4663{
Victor Stinner8c62be82010-05-06 00:08:46 +00004664 long egid_arg;
4665 gid_t egid;
4666 if (!PyArg_ParseTuple(args, "l", &egid_arg))
4667 return NULL;
4668 egid = egid_arg;
4669 if (egid != egid_arg) {
4670 PyErr_SetString(PyExc_OverflowError, "group id too big");
4671 return NULL;
4672 }
4673 if (setegid(egid) < 0) {
4674 return posix_error();
4675 } else {
4676 Py_INCREF(Py_None);
4677 return Py_None;
4678 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004679}
4680#endif /* HAVE_SETEGID */
4681
4682#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004683PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004684"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004685Set the current process's real and effective user ids.");
4686
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004687static PyObject *
4688posix_setreuid (PyObject *self, PyObject *args)
4689{
Victor Stinner8c62be82010-05-06 00:08:46 +00004690 long ruid_arg, euid_arg;
4691 uid_t ruid, euid;
4692 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
4693 return NULL;
4694 if (ruid_arg == -1)
4695 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
4696 else
4697 ruid = ruid_arg; /* otherwise, assign from our long */
4698 if (euid_arg == -1)
4699 euid = (uid_t)-1;
4700 else
4701 euid = euid_arg;
4702 if ((euid_arg != -1 && euid != euid_arg) ||
4703 (ruid_arg != -1 && ruid != ruid_arg)) {
4704 PyErr_SetString(PyExc_OverflowError, "user id too big");
4705 return NULL;
4706 }
4707 if (setreuid(ruid, euid) < 0) {
4708 return posix_error();
4709 } else {
4710 Py_INCREF(Py_None);
4711 return Py_None;
4712 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004713}
4714#endif /* HAVE_SETREUID */
4715
4716#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004717PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004718"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004719Set the current process's real and effective group ids.");
4720
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004721static PyObject *
4722posix_setregid (PyObject *self, PyObject *args)
4723{
Victor Stinner8c62be82010-05-06 00:08:46 +00004724 long rgid_arg, egid_arg;
4725 gid_t rgid, egid;
4726 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
4727 return NULL;
4728 if (rgid_arg == -1)
4729 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
4730 else
4731 rgid = rgid_arg; /* otherwise, assign from our long */
4732 if (egid_arg == -1)
4733 egid = (gid_t)-1;
4734 else
4735 egid = egid_arg;
4736 if ((egid_arg != -1 && egid != egid_arg) ||
4737 (rgid_arg != -1 && rgid != rgid_arg)) {
4738 PyErr_SetString(PyExc_OverflowError, "group id too big");
4739 return NULL;
4740 }
4741 if (setregid(rgid, egid) < 0) {
4742 return posix_error();
4743 } else {
4744 Py_INCREF(Py_None);
4745 return Py_None;
4746 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004747}
4748#endif /* HAVE_SETREGID */
4749
Guido van Rossumb6775db1994-08-01 11:34:53 +00004750#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004751PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004752"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004753Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004754
Barry Warsaw53699e91996-12-10 23:23:01 +00004755static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004756posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004757{
Victor Stinner8c62be82010-05-06 00:08:46 +00004758 long gid_arg;
4759 gid_t gid;
4760 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
4761 return NULL;
4762 gid = gid_arg;
4763 if (gid != gid_arg) {
4764 PyErr_SetString(PyExc_OverflowError, "group id too big");
4765 return NULL;
4766 }
4767 if (setgid(gid) < 0)
4768 return posix_error();
4769 Py_INCREF(Py_None);
4770 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004771}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004772#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004773
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004774#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004775PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004776"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004777Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004778
4779static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004780posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004781{
Victor Stinner8c62be82010-05-06 00:08:46 +00004782 int i, len;
4783 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004784
Victor Stinner8c62be82010-05-06 00:08:46 +00004785 if (!PySequence_Check(groups)) {
4786 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4787 return NULL;
4788 }
4789 len = PySequence_Size(groups);
4790 if (len > MAX_GROUPS) {
4791 PyErr_SetString(PyExc_ValueError, "too many groups");
4792 return NULL;
4793 }
4794 for(i = 0; i < len; i++) {
4795 PyObject *elem;
4796 elem = PySequence_GetItem(groups, i);
4797 if (!elem)
4798 return NULL;
4799 if (!PyLong_Check(elem)) {
4800 PyErr_SetString(PyExc_TypeError,
4801 "groups must be integers");
4802 Py_DECREF(elem);
4803 return NULL;
4804 } else {
4805 unsigned long x = PyLong_AsUnsignedLong(elem);
4806 if (PyErr_Occurred()) {
4807 PyErr_SetString(PyExc_TypeError,
4808 "group id too big");
4809 Py_DECREF(elem);
4810 return NULL;
4811 }
4812 grouplist[i] = x;
4813 /* read back the value to see if it fitted in gid_t */
4814 if (grouplist[i] != x) {
4815 PyErr_SetString(PyExc_TypeError,
4816 "group id too big");
4817 Py_DECREF(elem);
4818 return NULL;
4819 }
4820 }
4821 Py_DECREF(elem);
4822 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004823
Victor Stinner8c62be82010-05-06 00:08:46 +00004824 if (setgroups(len, grouplist) < 0)
4825 return posix_error();
4826 Py_INCREF(Py_None);
4827 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004828}
4829#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004830
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004831#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4832static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004833wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004834{
Victor Stinner8c62be82010-05-06 00:08:46 +00004835 PyObject *result;
4836 static PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004837
Victor Stinner8c62be82010-05-06 00:08:46 +00004838 if (pid == -1)
4839 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004840
Victor Stinner8c62be82010-05-06 00:08:46 +00004841 if (struct_rusage == NULL) {
4842 PyObject *m = PyImport_ImportModuleNoBlock("resource");
4843 if (m == NULL)
4844 return NULL;
4845 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4846 Py_DECREF(m);
4847 if (struct_rusage == NULL)
4848 return NULL;
4849 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004850
Victor Stinner8c62be82010-05-06 00:08:46 +00004851 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4852 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4853 if (!result)
4854 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004855
4856#ifndef doubletime
4857#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4858#endif
4859
Victor Stinner8c62be82010-05-06 00:08:46 +00004860 PyStructSequence_SET_ITEM(result, 0,
4861 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4862 PyStructSequence_SET_ITEM(result, 1,
4863 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004864#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00004865 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
4866 SET_INT(result, 2, ru->ru_maxrss);
4867 SET_INT(result, 3, ru->ru_ixrss);
4868 SET_INT(result, 4, ru->ru_idrss);
4869 SET_INT(result, 5, ru->ru_isrss);
4870 SET_INT(result, 6, ru->ru_minflt);
4871 SET_INT(result, 7, ru->ru_majflt);
4872 SET_INT(result, 8, ru->ru_nswap);
4873 SET_INT(result, 9, ru->ru_inblock);
4874 SET_INT(result, 10, ru->ru_oublock);
4875 SET_INT(result, 11, ru->ru_msgsnd);
4876 SET_INT(result, 12, ru->ru_msgrcv);
4877 SET_INT(result, 13, ru->ru_nsignals);
4878 SET_INT(result, 14, ru->ru_nvcsw);
4879 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004880#undef SET_INT
4881
Victor Stinner8c62be82010-05-06 00:08:46 +00004882 if (PyErr_Occurred()) {
4883 Py_DECREF(result);
4884 return NULL;
4885 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004886
Victor Stinner8c62be82010-05-06 00:08:46 +00004887 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004888}
4889#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4890
4891#ifdef HAVE_WAIT3
4892PyDoc_STRVAR(posix_wait3__doc__,
4893"wait3(options) -> (pid, status, rusage)\n\n\
4894Wait for completion of a child process.");
4895
4896static PyObject *
4897posix_wait3(PyObject *self, PyObject *args)
4898{
Victor Stinner8c62be82010-05-06 00:08:46 +00004899 pid_t pid;
4900 int options;
4901 struct rusage ru;
4902 WAIT_TYPE status;
4903 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004904
Victor Stinner8c62be82010-05-06 00:08:46 +00004905 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4906 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004907
Victor Stinner8c62be82010-05-06 00:08:46 +00004908 Py_BEGIN_ALLOW_THREADS
4909 pid = wait3(&status, options, &ru);
4910 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004911
Victor Stinner8c62be82010-05-06 00:08:46 +00004912 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004913}
4914#endif /* HAVE_WAIT3 */
4915
4916#ifdef HAVE_WAIT4
4917PyDoc_STRVAR(posix_wait4__doc__,
4918"wait4(pid, options) -> (pid, status, rusage)\n\n\
4919Wait for completion of a given child process.");
4920
4921static PyObject *
4922posix_wait4(PyObject *self, PyObject *args)
4923{
Victor Stinner8c62be82010-05-06 00:08:46 +00004924 pid_t pid;
4925 int options;
4926 struct rusage ru;
4927 WAIT_TYPE status;
4928 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004929
Victor Stinner8c62be82010-05-06 00:08:46 +00004930 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
4931 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004932
Victor Stinner8c62be82010-05-06 00:08:46 +00004933 Py_BEGIN_ALLOW_THREADS
4934 pid = wait4(pid, &status, options, &ru);
4935 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004936
Victor Stinner8c62be82010-05-06 00:08:46 +00004937 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004938}
4939#endif /* HAVE_WAIT4 */
4940
Guido van Rossumb6775db1994-08-01 11:34:53 +00004941#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004942PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004943"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004944Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004945
Barry Warsaw53699e91996-12-10 23:23:01 +00004946static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004947posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004948{
Victor Stinner8c62be82010-05-06 00:08:46 +00004949 pid_t pid;
4950 int options;
4951 WAIT_TYPE status;
4952 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004953
Victor Stinner8c62be82010-05-06 00:08:46 +00004954 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4955 return NULL;
4956 Py_BEGIN_ALLOW_THREADS
4957 pid = waitpid(pid, &status, options);
4958 Py_END_ALLOW_THREADS
4959 if (pid == -1)
4960 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004961
Victor Stinner8c62be82010-05-06 00:08:46 +00004962 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004963}
4964
Tim Petersab034fa2002-02-01 11:27:43 +00004965#elif defined(HAVE_CWAIT)
4966
4967/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004968PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004969"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004970"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004971
4972static PyObject *
4973posix_waitpid(PyObject *self, PyObject *args)
4974{
Victor Stinner8c62be82010-05-06 00:08:46 +00004975 Py_intptr_t pid;
4976 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004977
Victor Stinner8c62be82010-05-06 00:08:46 +00004978 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4979 return NULL;
4980 Py_BEGIN_ALLOW_THREADS
4981 pid = _cwait(&status, pid, options);
4982 Py_END_ALLOW_THREADS
4983 if (pid == -1)
4984 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004985
Victor Stinner8c62be82010-05-06 00:08:46 +00004986 /* shift the status left a byte so this is more like the POSIX waitpid */
4987 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004988}
4989#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004990
Guido van Rossumad0ee831995-03-01 10:34:45 +00004991#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004992PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004993"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004994Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004995
Barry Warsaw53699e91996-12-10 23:23:01 +00004996static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004997posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004998{
Victor Stinner8c62be82010-05-06 00:08:46 +00004999 pid_t pid;
5000 WAIT_TYPE status;
5001 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005002
Victor Stinner8c62be82010-05-06 00:08:46 +00005003 Py_BEGIN_ALLOW_THREADS
5004 pid = wait(&status);
5005 Py_END_ALLOW_THREADS
5006 if (pid == -1)
5007 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005008
Victor Stinner8c62be82010-05-06 00:08:46 +00005009 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005010}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005011#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005012
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005013
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005014PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005015"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005016Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005017
Barry Warsaw53699e91996-12-10 23:23:01 +00005018static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005019posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005020{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005021#ifdef HAVE_LSTAT
Victor Stinner8c62be82010-05-06 00:08:46 +00005022 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005023#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005024#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00005025 return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat",
5026 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005027#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005028 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005029#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005030#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005031}
5032
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005033
Guido van Rossumb6775db1994-08-01 11:34:53 +00005034#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005035PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005036"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005037Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005038
Barry Warsaw53699e91996-12-10 23:23:01 +00005039static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005040posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005041{
Victor Stinner8c62be82010-05-06 00:08:46 +00005042 PyObject* v;
5043 char buf[MAXPATHLEN];
5044 PyObject *opath;
5045 char *path;
5046 int n;
5047 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00005048
Victor Stinner8c62be82010-05-06 00:08:46 +00005049 if (!PyArg_ParseTuple(args, "O&:readlink",
5050 PyUnicode_FSConverter, &opath))
5051 return NULL;
5052 path = PyBytes_AsString(opath);
5053 v = PySequence_GetItem(args, 0);
5054 if (v == NULL) {
5055 Py_DECREF(opath);
5056 return NULL;
5057 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00005058
Victor Stinner8c62be82010-05-06 00:08:46 +00005059 if (PyUnicode_Check(v)) {
5060 arg_is_unicode = 1;
5061 }
5062 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005063
Victor Stinner8c62be82010-05-06 00:08:46 +00005064 Py_BEGIN_ALLOW_THREADS
5065 n = readlink(path, buf, (int) sizeof buf);
5066 Py_END_ALLOW_THREADS
5067 if (n < 0)
5068 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005069
Victor Stinner8c62be82010-05-06 00:08:46 +00005070 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00005071 if (arg_is_unicode)
5072 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
5073 else
5074 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005075}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005076#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005077
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005078
Guido van Rossumb6775db1994-08-01 11:34:53 +00005079#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005080PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005081"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005082Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005083
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005084static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005085posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005086{
Victor Stinner8c62be82010-05-06 00:08:46 +00005087 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005088}
5089#endif /* HAVE_SYMLINK */
5090
Brian Curtind40e6f72010-07-08 21:39:08 +00005091#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
5092
5093PyDoc_STRVAR(win_readlink__doc__,
5094"readlink(path) -> path\n\n\
5095Return a string representing the path to which the symbolic link points.");
5096
Brian Curtind40e6f72010-07-08 21:39:08 +00005097/* Windows readlink implementation */
5098static PyObject *
5099win_readlink(PyObject *self, PyObject *args)
5100{
5101 wchar_t *path;
5102 DWORD n_bytes_returned;
5103 DWORD io_result;
5104 PyObject *result;
5105 HANDLE reparse_point_handle;
5106
5107 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
5108 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
5109 wchar_t *print_name;
5110
5111 if (!PyArg_ParseTuple(args,
5112 "u:readlink",
5113 &path))
5114 return NULL;
5115
5116 /* First get a handle to the reparse point */
5117 Py_BEGIN_ALLOW_THREADS
5118 reparse_point_handle = CreateFileW(
5119 path,
5120 0,
5121 0,
5122 0,
5123 OPEN_EXISTING,
5124 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
5125 0);
5126 Py_END_ALLOW_THREADS
5127
5128 if (reparse_point_handle==INVALID_HANDLE_VALUE)
5129 {
5130 return win32_error_unicode("readlink", path);
5131 }
5132
5133 Py_BEGIN_ALLOW_THREADS
5134 /* New call DeviceIoControl to read the reparse point */
5135 io_result = DeviceIoControl(
5136 reparse_point_handle,
5137 FSCTL_GET_REPARSE_POINT,
5138 0, 0, /* in buffer */
5139 target_buffer, sizeof(target_buffer),
5140 &n_bytes_returned,
5141 0 /* we're not using OVERLAPPED_IO */
5142 );
5143 CloseHandle(reparse_point_handle);
5144 Py_END_ALLOW_THREADS
5145
5146 if (io_result==0)
5147 {
5148 return win32_error_unicode("readlink", path);
5149 }
5150
5151 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
5152 {
5153 PyErr_SetString(PyExc_ValueError,
5154 "not a symbolic link");
5155 return NULL;
5156 }
Brian Curtin74e45612010-07-09 15:58:59 +00005157 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
5158 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
5159
5160 result = PyUnicode_FromWideChar(print_name,
5161 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00005162 return result;
5163}
5164
5165#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
5166
5167#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
5168
5169/* Grab CreateSymbolicLinkW dynamically from kernel32 */
5170static int has_CreateSymbolicLinkW = 0;
5171static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
5172static int
5173check_CreateSymbolicLinkW()
5174{
5175 HINSTANCE hKernel32;
5176 /* only recheck */
5177 if (has_CreateSymbolicLinkW)
5178 return has_CreateSymbolicLinkW;
5179 hKernel32 = GetModuleHandle("KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00005180 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
5181 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00005182 if (Py_CreateSymbolicLinkW)
5183 has_CreateSymbolicLinkW = 1;
5184 return has_CreateSymbolicLinkW;
5185}
5186
5187PyDoc_STRVAR(win_symlink__doc__,
5188"symlink(src, dst, target_is_directory=False)\n\n\
5189Create a symbolic link pointing to src named dst.\n\
5190target_is_directory is required if the target is to be interpreted as\n\
5191a directory.\n\
5192This function requires Windows 6.0 or greater, and raises a\n\
5193NotImplementedError otherwise.");
5194
5195static PyObject *
5196win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
5197{
5198 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
5199 PyObject *src, *dest;
5200 int target_is_directory = 0;
5201 DWORD res;
5202 WIN32_FILE_ATTRIBUTE_DATA src_info;
5203
5204 if (!check_CreateSymbolicLinkW())
5205 {
5206 /* raise NotImplementedError */
5207 return PyErr_Format(PyExc_NotImplementedError,
5208 "CreateSymbolicLinkW not found");
5209 }
5210 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:symlink",
5211 kwlist, &src, &dest, &target_is_directory))
5212 return NULL;
5213 if (!convert_to_unicode(&src)) { return NULL; }
5214 if (!convert_to_unicode(&dest)) {
5215 Py_DECREF(src);
5216 return NULL;
5217 }
5218
5219 /* if src is a directory, ensure target_is_directory==1 */
5220 if(
5221 GetFileAttributesExW(
5222 PyUnicode_AsUnicode(src), GetFileExInfoStandard, &src_info
5223 ))
5224 {
5225 target_is_directory = target_is_directory ||
5226 (src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
5227 }
5228
5229 Py_BEGIN_ALLOW_THREADS
5230 res = Py_CreateSymbolicLinkW(
5231 PyUnicode_AsUnicode(dest),
5232 PyUnicode_AsUnicode(src),
5233 target_is_directory);
5234 Py_END_ALLOW_THREADS
5235 Py_DECREF(src);
5236 Py_DECREF(dest);
5237 if (!res)
5238 {
5239 return win32_error_unicode("symlink", PyUnicode_AsUnicode(src));
5240 }
5241
5242 Py_INCREF(Py_None);
5243 return Py_None;
5244}
5245#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005246
5247#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00005248#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5249static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005250system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005251{
5252 ULONG value = 0;
5253
5254 Py_BEGIN_ALLOW_THREADS
5255 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5256 Py_END_ALLOW_THREADS
5257
5258 return value;
5259}
5260
5261static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005262posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005263{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005264 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00005265 return Py_BuildValue("ddddd",
5266 (double)0 /* t.tms_utime / HZ */,
5267 (double)0 /* t.tms_stime / HZ */,
5268 (double)0 /* t.tms_cutime / HZ */,
5269 (double)0 /* t.tms_cstime / HZ */,
5270 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005271}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005272#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00005273#define NEED_TICKS_PER_SECOND
5274static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00005275static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005276posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005277{
Victor Stinner8c62be82010-05-06 00:08:46 +00005278 struct tms t;
5279 clock_t c;
5280 errno = 0;
5281 c = times(&t);
5282 if (c == (clock_t) -1)
5283 return posix_error();
5284 return Py_BuildValue("ddddd",
5285 (double)t.tms_utime / ticks_per_second,
5286 (double)t.tms_stime / ticks_per_second,
5287 (double)t.tms_cutime / ticks_per_second,
5288 (double)t.tms_cstime / ticks_per_second,
5289 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005290}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005291#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005292#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005293
5294
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005295#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005296#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005297static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005298posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005299{
Victor Stinner8c62be82010-05-06 00:08:46 +00005300 FILETIME create, exit, kernel, user;
5301 HANDLE hProc;
5302 hProc = GetCurrentProcess();
5303 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5304 /* The fields of a FILETIME structure are the hi and lo part
5305 of a 64-bit value expressed in 100 nanosecond units.
5306 1e7 is one second in such units; 1e-7 the inverse.
5307 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5308 */
5309 return Py_BuildValue(
5310 "ddddd",
5311 (double)(user.dwHighDateTime*429.4967296 +
5312 user.dwLowDateTime*1e-7),
5313 (double)(kernel.dwHighDateTime*429.4967296 +
5314 kernel.dwLowDateTime*1e-7),
5315 (double)0,
5316 (double)0,
5317 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005318}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005319#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005320
5321#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005322PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005323"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005324Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005325#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005326
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005327
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005328#ifdef HAVE_GETSID
5329PyDoc_STRVAR(posix_getsid__doc__,
5330"getsid(pid) -> sid\n\n\
5331Call the system call getsid().");
5332
5333static PyObject *
5334posix_getsid(PyObject *self, PyObject *args)
5335{
Victor Stinner8c62be82010-05-06 00:08:46 +00005336 pid_t pid;
5337 int sid;
5338 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
5339 return NULL;
5340 sid = getsid(pid);
5341 if (sid < 0)
5342 return posix_error();
5343 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005344}
5345#endif /* HAVE_GETSID */
5346
5347
Guido van Rossumb6775db1994-08-01 11:34:53 +00005348#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005349PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005350"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005351Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005352
Barry Warsaw53699e91996-12-10 23:23:01 +00005353static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005354posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005355{
Victor Stinner8c62be82010-05-06 00:08:46 +00005356 if (setsid() < 0)
5357 return posix_error();
5358 Py_INCREF(Py_None);
5359 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005360}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005361#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005362
Guido van Rossumb6775db1994-08-01 11:34:53 +00005363#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005364PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005365"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005366Call the system call setpgid().");
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_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005370{
Victor Stinner8c62be82010-05-06 00:08:46 +00005371 pid_t pid;
5372 int pgrp;
5373 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
5374 return NULL;
5375 if (setpgid(pid, pgrp) < 0)
5376 return posix_error();
5377 Py_INCREF(Py_None);
5378 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005379}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005380#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005381
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005382
Guido van Rossumb6775db1994-08-01 11:34:53 +00005383#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005384PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005385"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005386Return the process group associated with the terminal given by a fd.");
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_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005390{
Victor Stinner8c62be82010-05-06 00:08:46 +00005391 int fd;
5392 pid_t pgid;
5393 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
5394 return NULL;
5395 pgid = tcgetpgrp(fd);
5396 if (pgid < 0)
5397 return posix_error();
5398 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005399}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005400#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005401
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005402
Guido van Rossumb6775db1994-08-01 11:34:53 +00005403#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005404PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005405"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005406Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005407
Barry Warsaw53699e91996-12-10 23:23:01 +00005408static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005409posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005410{
Victor Stinner8c62be82010-05-06 00:08:46 +00005411 int fd;
5412 pid_t pgid;
5413 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
5414 return NULL;
5415 if (tcsetpgrp(fd, pgid) < 0)
5416 return posix_error();
5417 Py_INCREF(Py_None);
5418 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005419}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005420#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005421
Guido van Rossum687dd131993-05-17 08:34:16 +00005422/* Functions acting on file descriptors */
5423
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005424PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005425"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005426Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005427
Barry Warsaw53699e91996-12-10 23:23:01 +00005428static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005429posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005430{
Victor Stinner8c62be82010-05-06 00:08:46 +00005431 PyObject *ofile;
5432 char *file;
5433 int flag;
5434 int mode = 0777;
5435 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005436
5437#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005438 PyUnicodeObject *po;
5439 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5440 Py_BEGIN_ALLOW_THREADS
5441 /* PyUnicode_AS_UNICODE OK without thread
5442 lock as it is a simple dereference. */
5443 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5444 Py_END_ALLOW_THREADS
5445 if (fd < 0)
5446 return posix_error();
5447 return PyLong_FromLong((long)fd);
5448 }
5449 /* Drop the argument parsing error as narrow strings
5450 are also valid. */
5451 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005452#endif
5453
Victor Stinner8c62be82010-05-06 00:08:46 +00005454 if (!PyArg_ParseTuple(args, "O&i|i",
5455 PyUnicode_FSConverter, &ofile,
5456 &flag, &mode))
5457 return NULL;
5458 file = PyBytes_AsString(ofile);
5459 Py_BEGIN_ALLOW_THREADS
5460 fd = open(file, flag, mode);
5461 Py_END_ALLOW_THREADS
5462 if (fd < 0)
5463 return posix_error_with_allocated_filename(ofile);
5464 Py_DECREF(ofile);
5465 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005466}
5467
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005468
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005469PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005470"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005471Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005472
Barry Warsaw53699e91996-12-10 23:23:01 +00005473static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005474posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005475{
Victor Stinner8c62be82010-05-06 00:08:46 +00005476 int fd, res;
5477 if (!PyArg_ParseTuple(args, "i:close", &fd))
5478 return NULL;
5479 if (!_PyVerify_fd(fd))
5480 return posix_error();
5481 Py_BEGIN_ALLOW_THREADS
5482 res = close(fd);
5483 Py_END_ALLOW_THREADS
5484 if (res < 0)
5485 return posix_error();
5486 Py_INCREF(Py_None);
5487 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005488}
5489
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005490
Victor Stinner8c62be82010-05-06 00:08:46 +00005491PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00005492"closerange(fd_low, fd_high)\n\n\
5493Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
5494
5495static PyObject *
5496posix_closerange(PyObject *self, PyObject *args)
5497{
Victor Stinner8c62be82010-05-06 00:08:46 +00005498 int fd_from, fd_to, i;
5499 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
5500 return NULL;
5501 Py_BEGIN_ALLOW_THREADS
5502 for (i = fd_from; i < fd_to; i++)
5503 if (_PyVerify_fd(i))
5504 close(i);
5505 Py_END_ALLOW_THREADS
5506 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00005507}
5508
5509
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005510PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005511"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005512Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005513
Barry Warsaw53699e91996-12-10 23:23:01 +00005514static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005515posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005516{
Victor Stinner8c62be82010-05-06 00:08:46 +00005517 int fd;
5518 if (!PyArg_ParseTuple(args, "i:dup", &fd))
5519 return NULL;
5520 if (!_PyVerify_fd(fd))
5521 return posix_error();
5522 Py_BEGIN_ALLOW_THREADS
5523 fd = dup(fd);
5524 Py_END_ALLOW_THREADS
5525 if (fd < 0)
5526 return posix_error();
5527 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005528}
5529
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005530
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005531PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005532"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005533Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005534
Barry Warsaw53699e91996-12-10 23:23:01 +00005535static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005536posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005537{
Victor Stinner8c62be82010-05-06 00:08:46 +00005538 int fd, fd2, res;
5539 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5540 return NULL;
5541 if (!_PyVerify_fd_dup2(fd, fd2))
5542 return posix_error();
5543 Py_BEGIN_ALLOW_THREADS
5544 res = dup2(fd, fd2);
5545 Py_END_ALLOW_THREADS
5546 if (res < 0)
5547 return posix_error();
5548 Py_INCREF(Py_None);
5549 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005550}
5551
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005552
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005553PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005554"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005555Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005556
Barry Warsaw53699e91996-12-10 23:23:01 +00005557static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005558posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005559{
Victor Stinner8c62be82010-05-06 00:08:46 +00005560 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005561#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005562 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005563#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005564 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005565#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005566 PyObject *posobj;
5567 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5568 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005569#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00005570 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5571 switch (how) {
5572 case 0: how = SEEK_SET; break;
5573 case 1: how = SEEK_CUR; break;
5574 case 2: how = SEEK_END; break;
5575 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005576#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005577
5578#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005579 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005580#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005581 pos = PyLong_Check(posobj) ?
5582 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005583#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005584 if (PyErr_Occurred())
5585 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005586
Victor Stinner8c62be82010-05-06 00:08:46 +00005587 if (!_PyVerify_fd(fd))
5588 return posix_error();
5589 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005590#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005591 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005592#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005593 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005594#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005595 Py_END_ALLOW_THREADS
5596 if (res < 0)
5597 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005598
5599#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005600 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005601#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005602 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005603#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005604}
5605
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005606
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005607PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005608"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005609Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005610
Barry Warsaw53699e91996-12-10 23:23:01 +00005611static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005612posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005613{
Victor Stinner8c62be82010-05-06 00:08:46 +00005614 int fd, size;
5615 Py_ssize_t n;
5616 PyObject *buffer;
5617 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5618 return NULL;
5619 if (size < 0) {
5620 errno = EINVAL;
5621 return posix_error();
5622 }
5623 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
5624 if (buffer == NULL)
5625 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00005626 if (!_PyVerify_fd(fd)) {
5627 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00005628 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00005629 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005630 Py_BEGIN_ALLOW_THREADS
5631 n = read(fd, PyBytes_AS_STRING(buffer), size);
5632 Py_END_ALLOW_THREADS
5633 if (n < 0) {
5634 Py_DECREF(buffer);
5635 return posix_error();
5636 }
5637 if (n != size)
5638 _PyBytes_Resize(&buffer, n);
5639 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00005640}
5641
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005642
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005643PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005644"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005645Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005646
Barry Warsaw53699e91996-12-10 23:23:01 +00005647static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005648posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005649{
Victor Stinner8c62be82010-05-06 00:08:46 +00005650 Py_buffer pbuf;
5651 int fd;
5652 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005653
Victor Stinner8c62be82010-05-06 00:08:46 +00005654 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
5655 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00005656 if (!_PyVerify_fd(fd)) {
5657 PyBuffer_Release(&pbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00005658 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00005659 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005660 Py_BEGIN_ALLOW_THREADS
5661 size = write(fd, pbuf.buf, (size_t)pbuf.len);
5662 Py_END_ALLOW_THREADS
Stefan Krah99439262010-11-26 12:58:05 +00005663 PyBuffer_Release(&pbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00005664 if (size < 0)
5665 return posix_error();
5666 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005667}
5668
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005669
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005670PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005671"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005672Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005673
Barry Warsaw53699e91996-12-10 23:23:01 +00005674static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005675posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005676{
Victor Stinner8c62be82010-05-06 00:08:46 +00005677 int fd;
5678 STRUCT_STAT st;
5679 int res;
5680 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5681 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005682#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00005683 /* on OpenVMS we must ensure that all bytes are written to the file */
5684 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005685#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005686 if (!_PyVerify_fd(fd))
5687 return posix_error();
5688 Py_BEGIN_ALLOW_THREADS
5689 res = FSTAT(fd, &st);
5690 Py_END_ALLOW_THREADS
5691 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00005692#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005693 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00005694#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005695 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005696#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005697 }
Tim Peters5aa91602002-01-30 05:46:57 +00005698
Victor Stinner8c62be82010-05-06 00:08:46 +00005699 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005700}
5701
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005702PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005703"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005704Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005705connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005706
5707static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005708posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005709{
Victor Stinner8c62be82010-05-06 00:08:46 +00005710 int fd;
5711 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5712 return NULL;
5713 if (!_PyVerify_fd(fd))
5714 return PyBool_FromLong(0);
5715 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005716}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005717
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005718#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005719PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005720"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005721Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005722
Barry Warsaw53699e91996-12-10 23:23:01 +00005723static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005724posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005725{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005726#if defined(PYOS_OS2)
5727 HFILE read, write;
5728 APIRET rc;
5729
Victor Stinner8c62be82010-05-06 00:08:46 +00005730 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005731 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinner8c62be82010-05-06 00:08:46 +00005732 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005733 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005734 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005735
5736 return Py_BuildValue("(ii)", read, write);
5737#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005738#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005739 int fds[2];
5740 int res;
5741 Py_BEGIN_ALLOW_THREADS
5742 res = pipe(fds);
5743 Py_END_ALLOW_THREADS
5744 if (res != 0)
5745 return posix_error();
5746 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005747#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00005748 HANDLE read, write;
5749 int read_fd, write_fd;
5750 BOOL ok;
5751 Py_BEGIN_ALLOW_THREADS
5752 ok = CreatePipe(&read, &write, NULL, 0);
5753 Py_END_ALLOW_THREADS
5754 if (!ok)
5755 return win32_error("CreatePipe", NULL);
5756 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5757 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5758 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005759#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005760#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005761}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005762#endif /* HAVE_PIPE */
5763
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005764
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005765#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005766PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005767"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005768Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005769
Barry Warsaw53699e91996-12-10 23:23:01 +00005770static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005771posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005772{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005773 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005774 char *filename;
5775 int mode = 0666;
5776 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005777 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
5778 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00005779 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005780 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005781 Py_BEGIN_ALLOW_THREADS
5782 res = mkfifo(filename, mode);
5783 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005784 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005785 if (res < 0)
5786 return posix_error();
5787 Py_INCREF(Py_None);
5788 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005789}
5790#endif
5791
5792
Neal Norwitz11690112002-07-30 01:08:28 +00005793#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005794PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005795"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005796Create a filesystem node (file, device special file or named pipe)\n\
5797named filename. mode specifies both the permissions to use and the\n\
5798type of node to be created, being combined (bitwise OR) with one of\n\
5799S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005800device defines the newly created device special file (probably using\n\
5801os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005802
5803
5804static PyObject *
5805posix_mknod(PyObject *self, PyObject *args)
5806{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005807 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005808 char *filename;
5809 int mode = 0600;
5810 int device = 0;
5811 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005812 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
5813 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00005814 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005815 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005816 Py_BEGIN_ALLOW_THREADS
5817 res = mknod(filename, mode, device);
5818 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005819 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005820 if (res < 0)
5821 return posix_error();
5822 Py_INCREF(Py_None);
5823 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005824}
5825#endif
5826
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005827#ifdef HAVE_DEVICE_MACROS
5828PyDoc_STRVAR(posix_major__doc__,
5829"major(device) -> major number\n\
5830Extracts a device major number from a raw device number.");
5831
5832static PyObject *
5833posix_major(PyObject *self, PyObject *args)
5834{
Victor Stinner8c62be82010-05-06 00:08:46 +00005835 int device;
5836 if (!PyArg_ParseTuple(args, "i:major", &device))
5837 return NULL;
5838 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005839}
5840
5841PyDoc_STRVAR(posix_minor__doc__,
5842"minor(device) -> minor number\n\
5843Extracts a device minor number from a raw device number.");
5844
5845static PyObject *
5846posix_minor(PyObject *self, PyObject *args)
5847{
Victor Stinner8c62be82010-05-06 00:08:46 +00005848 int device;
5849 if (!PyArg_ParseTuple(args, "i:minor", &device))
5850 return NULL;
5851 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005852}
5853
5854PyDoc_STRVAR(posix_makedev__doc__,
5855"makedev(major, minor) -> device number\n\
5856Composes a raw device number from the major and minor device numbers.");
5857
5858static PyObject *
5859posix_makedev(PyObject *self, PyObject *args)
5860{
Victor Stinner8c62be82010-05-06 00:08:46 +00005861 int major, minor;
5862 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5863 return NULL;
5864 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005865}
5866#endif /* device macros */
5867
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005868
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005869#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005870PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005871"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005872Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005873
Barry Warsaw53699e91996-12-10 23:23:01 +00005874static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005875posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005876{
Victor Stinner8c62be82010-05-06 00:08:46 +00005877 int fd;
5878 off_t length;
5879 int res;
5880 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005881
Victor Stinner8c62be82010-05-06 00:08:46 +00005882 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
5883 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005884
5885#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005886 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005887#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005888 length = PyLong_Check(lenobj) ?
5889 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005890#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005891 if (PyErr_Occurred())
5892 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005893
Victor Stinner8c62be82010-05-06 00:08:46 +00005894 Py_BEGIN_ALLOW_THREADS
5895 res = ftruncate(fd, length);
5896 Py_END_ALLOW_THREADS
5897 if (res < 0)
5898 return posix_error();
5899 Py_INCREF(Py_None);
5900 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005901}
5902#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005903
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005904#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005905PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005906"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005907Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005908
Fred Drake762e2061999-08-26 17:23:54 +00005909/* Save putenv() parameters as values here, so we can collect them when they
5910 * get re-set with another call for the same key. */
5911static PyObject *posix_putenv_garbage;
5912
Tim Peters5aa91602002-01-30 05:46:57 +00005913static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005914posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005915{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005916#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005917 wchar_t *s1, *s2;
5918 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005919#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005920 PyObject *os1, *os2;
5921 char *s1, *s2;
5922 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005923#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005924 PyObject *newstr = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005925 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005926
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005927#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005928 if (!PyArg_ParseTuple(args,
5929 "uu:putenv",
5930 &s1, &s2))
5931 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005932#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005933 if (!PyArg_ParseTuple(args,
5934 "O&O&:putenv",
5935 PyUnicode_FSConverter, &os1,
5936 PyUnicode_FSConverter, &os2))
5937 return NULL;
5938 s1 = PyBytes_AsString(os1);
5939 s2 = PyBytes_AsString(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005940#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005941
5942#if defined(PYOS_OS2)
5943 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5944 APIRET rc;
5945
Guido van Rossumd48f2521997-12-05 22:19:34 +00005946 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005947 if (rc != NO_ERROR) {
5948 os2_error(rc);
5949 goto error;
5950 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005951
5952 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5953 APIRET rc;
5954
Guido van Rossumd48f2521997-12-05 22:19:34 +00005955 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005956 if (rc != NO_ERROR) {
5957 os2_error(rc);
5958 goto error;
5959 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005960 } else {
5961#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005962 /* XXX This can leak memory -- not easy to fix :-( */
5963 /* len includes space for a trailing \0; the size arg to
5964 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005965#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005966 len = wcslen(s1) + wcslen(s2) + 2;
5967 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005968#else
Victor Stinner84ae1182010-05-06 22:05:07 +00005969 len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2;
Victor Stinner8c62be82010-05-06 00:08:46 +00005970 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005971#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005972 if (newstr == NULL) {
5973 PyErr_NoMemory();
5974 goto error;
5975 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005976#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005977 newenv = PyUnicode_AsUnicode(newstr);
5978 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5979 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005980 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00005981 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005982 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005983#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005984 newenv = PyBytes_AS_STRING(newstr);
5985 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5986 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005987 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00005988 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005989 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005990#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005991
Victor Stinner8c62be82010-05-06 00:08:46 +00005992 /* Install the first arg and newstr in posix_putenv_garbage;
5993 * this will cause previous value to be collected. This has to
5994 * happen after the real putenv() call because the old value
5995 * was still accessible until then. */
5996 if (PyDict_SetItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00005997#ifdef MS_WINDOWS
5998 PyTuple_GET_ITEM(args, 0),
5999#else
6000 os1,
6001#endif
6002 newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006003 /* really not much we can do; just leak */
6004 PyErr_Clear();
6005 }
6006 else {
6007 Py_DECREF(newstr);
6008 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006009
6010#if defined(PYOS_OS2)
6011 }
6012#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006013
Martin v. Löwis011e8422009-05-05 04:43:17 +00006014#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006015 Py_DECREF(os1);
6016 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00006017#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006018 Py_RETURN_NONE;
6019
6020error:
6021#ifndef MS_WINDOWS
6022 Py_DECREF(os1);
6023 Py_DECREF(os2);
6024#endif
6025 Py_XDECREF(newstr);
6026 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006027}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006028#endif /* putenv */
6029
Guido van Rossumc524d952001-10-19 01:31:59 +00006030#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006031PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006032"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006033Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006034
6035static PyObject *
6036posix_unsetenv(PyObject *self, PyObject *args)
6037{
Victor Stinner84ae1182010-05-06 22:05:07 +00006038#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006039 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00006040
Victor Stinner8c62be82010-05-06 00:08:46 +00006041 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6042 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00006043#else
6044 PyObject *os1;
6045 char *s1;
6046
6047 if (!PyArg_ParseTuple(args, "O&:unsetenv",
6048 PyUnicode_FSConverter, &os1))
6049 return NULL;
6050 s1 = PyBytes_AsString(os1);
6051#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006052
Victor Stinner8c62be82010-05-06 00:08:46 +00006053 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00006054
Victor Stinner8c62be82010-05-06 00:08:46 +00006055 /* Remove the key from posix_putenv_garbage;
6056 * this will cause it to be collected. This has to
6057 * happen after the real unsetenv() call because the
6058 * old value was still accessible until then.
6059 */
6060 if (PyDict_DelItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00006061#ifdef MS_WINDOWS
6062 PyTuple_GET_ITEM(args, 0)
6063#else
6064 os1
6065#endif
6066 )) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006067 /* really not much we can do; just leak */
6068 PyErr_Clear();
6069 }
Guido van Rossumc524d952001-10-19 01:31:59 +00006070
Victor Stinner84ae1182010-05-06 22:05:07 +00006071#ifndef MS_WINDOWS
6072 Py_DECREF(os1);
6073#endif
6074 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00006075}
6076#endif /* unsetenv */
6077
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006078PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006079"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006080Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006081
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006082static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006083posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006084{
Victor Stinner8c62be82010-05-06 00:08:46 +00006085 int code;
6086 char *message;
6087 if (!PyArg_ParseTuple(args, "i:strerror", &code))
6088 return NULL;
6089 message = strerror(code);
6090 if (message == NULL) {
6091 PyErr_SetString(PyExc_ValueError,
6092 "strerror() argument out of range");
6093 return NULL;
6094 }
6095 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006096}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006097
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006098
Guido van Rossumc9641791998-08-04 15:26:23 +00006099#ifdef HAVE_SYS_WAIT_H
6100
Fred Drake106c1a02002-04-23 15:58:02 +00006101#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006102PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006103"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006104Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006105
6106static PyObject *
6107posix_WCOREDUMP(PyObject *self, PyObject *args)
6108{
Victor Stinner8c62be82010-05-06 00:08:46 +00006109 WAIT_TYPE status;
6110 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006111
Victor Stinner8c62be82010-05-06 00:08:46 +00006112 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
6113 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006114
Victor Stinner8c62be82010-05-06 00:08:46 +00006115 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006116}
6117#endif /* WCOREDUMP */
6118
6119#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006120PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006121"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006122Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006123job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006124
6125static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006126posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006127{
Victor Stinner8c62be82010-05-06 00:08:46 +00006128 WAIT_TYPE status;
6129 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006130
Victor Stinner8c62be82010-05-06 00:08:46 +00006131 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
6132 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006133
Victor Stinner8c62be82010-05-06 00:08:46 +00006134 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006135}
6136#endif /* WIFCONTINUED */
6137
Guido van Rossumc9641791998-08-04 15:26:23 +00006138#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006139PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006140"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006141Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006142
6143static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006144posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006145{
Victor Stinner8c62be82010-05-06 00:08:46 +00006146 WAIT_TYPE status;
6147 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006148
Victor Stinner8c62be82010-05-06 00:08:46 +00006149 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
6150 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006151
Victor Stinner8c62be82010-05-06 00:08:46 +00006152 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006153}
6154#endif /* WIFSTOPPED */
6155
6156#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006157PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006158"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006159Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006160
6161static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006162posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006163{
Victor Stinner8c62be82010-05-06 00:08:46 +00006164 WAIT_TYPE status;
6165 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006166
Victor Stinner8c62be82010-05-06 00:08:46 +00006167 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
6168 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006169
Victor Stinner8c62be82010-05-06 00:08:46 +00006170 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006171}
6172#endif /* WIFSIGNALED */
6173
6174#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006175PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006176"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006177Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006178system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006179
6180static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006181posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006182{
Victor Stinner8c62be82010-05-06 00:08:46 +00006183 WAIT_TYPE status;
6184 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006185
Victor Stinner8c62be82010-05-06 00:08:46 +00006186 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
6187 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006188
Victor Stinner8c62be82010-05-06 00:08:46 +00006189 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006190}
6191#endif /* WIFEXITED */
6192
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006193#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006194PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006195"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006196Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006197
6198static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006199posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006200{
Victor Stinner8c62be82010-05-06 00:08:46 +00006201 WAIT_TYPE status;
6202 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006203
Victor Stinner8c62be82010-05-06 00:08:46 +00006204 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
6205 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006206
Victor Stinner8c62be82010-05-06 00:08:46 +00006207 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006208}
6209#endif /* WEXITSTATUS */
6210
6211#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006212PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006213"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006214Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006215value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006216
6217static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006218posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006219{
Victor Stinner8c62be82010-05-06 00:08:46 +00006220 WAIT_TYPE status;
6221 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006222
Victor Stinner8c62be82010-05-06 00:08:46 +00006223 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
6224 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006225
Victor Stinner8c62be82010-05-06 00:08:46 +00006226 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006227}
6228#endif /* WTERMSIG */
6229
6230#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006231PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006232"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006233Return the signal that stopped the process that provided\n\
6234the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006235
6236static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006237posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006238{
Victor Stinner8c62be82010-05-06 00:08:46 +00006239 WAIT_TYPE status;
6240 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006241
Victor Stinner8c62be82010-05-06 00:08:46 +00006242 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
6243 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006244
Victor Stinner8c62be82010-05-06 00:08:46 +00006245 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006246}
6247#endif /* WSTOPSIG */
6248
6249#endif /* HAVE_SYS_WAIT_H */
6250
6251
Thomas Wouters477c8d52006-05-27 19:21:47 +00006252#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006253#ifdef _SCO_DS
6254/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6255 needed definitions in sys/statvfs.h */
6256#define _SVID3
6257#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006258#include <sys/statvfs.h>
6259
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006260static PyObject*
6261_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006262 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6263 if (v == NULL)
6264 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006265
6266#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006267 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6268 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6269 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
6270 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
6271 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
6272 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
6273 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
6274 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
6275 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6276 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006277#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006278 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6279 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6280 PyStructSequence_SET_ITEM(v, 2,
6281 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
6282 PyStructSequence_SET_ITEM(v, 3,
6283 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
6284 PyStructSequence_SET_ITEM(v, 4,
6285 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
6286 PyStructSequence_SET_ITEM(v, 5,
6287 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
6288 PyStructSequence_SET_ITEM(v, 6,
6289 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
6290 PyStructSequence_SET_ITEM(v, 7,
6291 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
6292 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6293 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006294#endif
6295
Victor Stinner8c62be82010-05-06 00:08:46 +00006296 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006297}
6298
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006299PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006300"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006301Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006302
6303static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006304posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006305{
Victor Stinner8c62be82010-05-06 00:08:46 +00006306 int fd, res;
6307 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006308
Victor Stinner8c62be82010-05-06 00:08:46 +00006309 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
6310 return NULL;
6311 Py_BEGIN_ALLOW_THREADS
6312 res = fstatvfs(fd, &st);
6313 Py_END_ALLOW_THREADS
6314 if (res != 0)
6315 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006316
Victor Stinner8c62be82010-05-06 00:08:46 +00006317 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006318}
Thomas Wouters477c8d52006-05-27 19:21:47 +00006319#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006320
6321
Thomas Wouters477c8d52006-05-27 19:21:47 +00006322#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006323#include <sys/statvfs.h>
6324
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006325PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006326"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006327Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006328
6329static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006330posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006331{
Victor Stinner8c62be82010-05-06 00:08:46 +00006332 char *path;
6333 int res;
6334 struct statvfs st;
6335 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
6336 return NULL;
6337 Py_BEGIN_ALLOW_THREADS
6338 res = statvfs(path, &st);
6339 Py_END_ALLOW_THREADS
6340 if (res != 0)
6341 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006342
Victor Stinner8c62be82010-05-06 00:08:46 +00006343 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006344}
6345#endif /* HAVE_STATVFS */
6346
Fred Drakec9680921999-12-13 16:37:25 +00006347/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6348 * It maps strings representing configuration variable names to
6349 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006350 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006351 * rarely-used constants. There are three separate tables that use
6352 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006353 *
6354 * This code is always included, even if none of the interfaces that
6355 * need it are included. The #if hackery needed to avoid it would be
6356 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006357 */
6358struct constdef {
6359 char *name;
6360 long value;
6361};
6362
Fred Drake12c6e2d1999-12-14 21:25:03 +00006363static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006364conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00006365 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006366{
Christian Heimes217cfd12007-12-02 14:31:20 +00006367 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006368 *valuep = PyLong_AS_LONG(arg);
6369 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006370 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00006371 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00006372 /* look up the value in the table using a binary search */
6373 size_t lo = 0;
6374 size_t mid;
6375 size_t hi = tablesize;
6376 int cmp;
6377 const char *confname;
6378 if (!PyUnicode_Check(arg)) {
6379 PyErr_SetString(PyExc_TypeError,
6380 "configuration names must be strings or integers");
6381 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006382 }
Stefan Krah0e803b32010-11-26 16:16:47 +00006383 confname = _PyUnicode_AsString(arg);
6384 if (confname == NULL)
6385 return 0;
6386 while (lo < hi) {
6387 mid = (lo + hi) / 2;
6388 cmp = strcmp(confname, table[mid].name);
6389 if (cmp < 0)
6390 hi = mid;
6391 else if (cmp > 0)
6392 lo = mid + 1;
6393 else {
6394 *valuep = table[mid].value;
6395 return 1;
6396 }
6397 }
6398 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6399 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006400 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00006401}
6402
6403
6404#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6405static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006406#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006407 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006408#endif
6409#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006410 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006411#endif
Fred Drakec9680921999-12-13 16:37:25 +00006412#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006413 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006414#endif
6415#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00006416 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00006417#endif
6418#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00006419 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00006420#endif
6421#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00006422 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00006423#endif
6424#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006425 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006426#endif
6427#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00006428 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00006429#endif
6430#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00006431 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00006432#endif
6433#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006434 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006435#endif
6436#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006437 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00006438#endif
6439#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006440 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006441#endif
6442#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006443 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00006444#endif
6445#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006446 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006447#endif
6448#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006449 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00006450#endif
6451#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006452 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006453#endif
6454#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00006455 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00006456#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00006457#ifdef _PC_ACL_ENABLED
6458 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
6459#endif
6460#ifdef _PC_MIN_HOLE_SIZE
6461 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
6462#endif
6463#ifdef _PC_ALLOC_SIZE_MIN
6464 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
6465#endif
6466#ifdef _PC_REC_INCR_XFER_SIZE
6467 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
6468#endif
6469#ifdef _PC_REC_MAX_XFER_SIZE
6470 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
6471#endif
6472#ifdef _PC_REC_MIN_XFER_SIZE
6473 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
6474#endif
6475#ifdef _PC_REC_XFER_ALIGN
6476 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
6477#endif
6478#ifdef _PC_SYMLINK_MAX
6479 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
6480#endif
6481#ifdef _PC_XATTR_ENABLED
6482 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
6483#endif
6484#ifdef _PC_XATTR_EXISTS
6485 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
6486#endif
6487#ifdef _PC_TIMESTAMP_RESOLUTION
6488 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
6489#endif
Fred Drakec9680921999-12-13 16:37:25 +00006490};
6491
Fred Drakec9680921999-12-13 16:37:25 +00006492static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006493conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006494{
6495 return conv_confname(arg, valuep, posix_constants_pathconf,
6496 sizeof(posix_constants_pathconf)
6497 / sizeof(struct constdef));
6498}
6499#endif
6500
6501#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006502PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006503"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006504Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006505If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006506
6507static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006508posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006509{
6510 PyObject *result = NULL;
6511 int name, fd;
6512
Fred Drake12c6e2d1999-12-14 21:25:03 +00006513 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6514 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006515 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006516
Stefan Krah0e803b32010-11-26 16:16:47 +00006517 errno = 0;
6518 limit = fpathconf(fd, name);
6519 if (limit == -1 && errno != 0)
6520 posix_error();
6521 else
6522 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006523 }
6524 return result;
6525}
6526#endif
6527
6528
6529#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006530PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006531"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006532Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006533If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006534
6535static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006536posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006537{
6538 PyObject *result = NULL;
6539 int name;
6540 char *path;
6541
6542 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6543 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006544 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006545
Victor Stinner8c62be82010-05-06 00:08:46 +00006546 errno = 0;
6547 limit = pathconf(path, name);
6548 if (limit == -1 && errno != 0) {
6549 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00006550 /* could be a path or name problem */
6551 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00006552 else
Stefan Krah99439262010-11-26 12:58:05 +00006553 posix_error_with_filename(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00006554 }
6555 else
6556 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006557 }
6558 return result;
6559}
6560#endif
6561
6562#ifdef HAVE_CONFSTR
6563static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006564#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00006565 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00006566#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00006567#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006568 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006569#endif
6570#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006571 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006572#endif
Fred Draked86ed291999-12-15 15:34:33 +00006573#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006574 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006575#endif
6576#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006577 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006578#endif
6579#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006580 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006581#endif
6582#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006583 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006584#endif
Fred Drakec9680921999-12-13 16:37:25 +00006585#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006586 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006587#endif
6588#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006589 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006590#endif
6591#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006592 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006593#endif
6594#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006595 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006596#endif
6597#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006598 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006599#endif
6600#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006601 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006602#endif
6603#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006604 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006605#endif
6606#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006607 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006608#endif
Fred Draked86ed291999-12-15 15:34:33 +00006609#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00006610 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00006611#endif
Fred Drakec9680921999-12-13 16:37:25 +00006612#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00006613 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00006614#endif
Fred Draked86ed291999-12-15 15:34:33 +00006615#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006616 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00006617#endif
6618#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006619 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00006620#endif
6621#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006622 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006623#endif
6624#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006625 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00006626#endif
Fred Drakec9680921999-12-13 16:37:25 +00006627#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006628 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006629#endif
6630#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006631 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006632#endif
6633#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006634 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006635#endif
6636#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006637 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006638#endif
6639#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006640 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006641#endif
6642#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006643 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006644#endif
6645#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006646 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006647#endif
6648#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006649 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006650#endif
6651#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006652 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006653#endif
6654#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006655 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006656#endif
6657#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006658 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006659#endif
6660#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006661 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006662#endif
6663#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006664 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006665#endif
6666#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006667 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006668#endif
6669#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006670 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006671#endif
6672#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006673 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006674#endif
Fred Draked86ed291999-12-15 15:34:33 +00006675#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006676 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006677#endif
6678#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006679 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00006680#endif
6681#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00006682 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00006683#endif
6684#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006685 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006686#endif
6687#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006688 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006689#endif
6690#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00006691 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00006692#endif
6693#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006694 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00006695#endif
6696#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00006697 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00006698#endif
6699#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006700 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006701#endif
6702#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006703 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006704#endif
6705#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006706 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006707#endif
6708#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006709 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006710#endif
6711#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00006712 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00006713#endif
Fred Drakec9680921999-12-13 16:37:25 +00006714};
6715
6716static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006717conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006718{
6719 return conv_confname(arg, valuep, posix_constants_confstr,
6720 sizeof(posix_constants_confstr)
6721 / sizeof(struct constdef));
6722}
6723
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006724PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006725"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006726Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006727
6728static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006729posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006730{
6731 PyObject *result = NULL;
6732 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00006733 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00006734 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006735
Victor Stinnercb043522010-09-10 23:49:04 +00006736 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
6737 return NULL;
6738
6739 errno = 0;
6740 len = confstr(name, buffer, sizeof(buffer));
6741 if (len == 0) {
6742 if (errno) {
6743 posix_error();
6744 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00006745 }
6746 else {
Victor Stinnercb043522010-09-10 23:49:04 +00006747 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00006748 }
6749 }
Victor Stinnercb043522010-09-10 23:49:04 +00006750
6751 if ((unsigned int)len >= sizeof(buffer)) {
6752 char *buf = PyMem_Malloc(len);
6753 if (buf == NULL)
6754 return PyErr_NoMemory();
6755 confstr(name, buf, len);
6756 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
6757 PyMem_Free(buf);
6758 }
6759 else
6760 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006761 return result;
6762}
6763#endif
6764
6765
6766#ifdef HAVE_SYSCONF
6767static struct constdef posix_constants_sysconf[] = {
6768#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00006769 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00006770#endif
6771#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00006772 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00006773#endif
6774#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006775 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006776#endif
6777#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006778 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006779#endif
6780#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006781 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006782#endif
6783#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00006784 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00006785#endif
6786#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00006787 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00006788#endif
6789#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006790 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006791#endif
6792#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00006793 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00006794#endif
6795#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006796 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006797#endif
Fred Draked86ed291999-12-15 15:34:33 +00006798#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006800#endif
6801#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00006803#endif
Fred Drakec9680921999-12-13 16:37:25 +00006804#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006805 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006806#endif
Fred Drakec9680921999-12-13 16:37:25 +00006807#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006808 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006809#endif
6810#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006811 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006812#endif
6813#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006814 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006815#endif
6816#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006818#endif
6819#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006820 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006821#endif
Fred Draked86ed291999-12-15 15:34:33 +00006822#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006823 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00006824#endif
Fred Drakec9680921999-12-13 16:37:25 +00006825#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006827#endif
6828#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006829 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006830#endif
6831#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006832 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006833#endif
6834#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006835 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006836#endif
6837#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006838 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006839#endif
Fred Draked86ed291999-12-15 15:34:33 +00006840#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00006841 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00006842#endif
Fred Drakec9680921999-12-13 16:37:25 +00006843#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006844 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006845#endif
6846#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006847 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006848#endif
6849#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006850 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006851#endif
6852#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006853 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006854#endif
6855#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006856 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006857#endif
6858#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006859 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00006860#endif
6861#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006862 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006863#endif
6864#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006865 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006866#endif
6867#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006869#endif
6870#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006871 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006872#endif
6873#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006874 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006875#endif
6876#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006877 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006878#endif
6879#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006880 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006881#endif
6882#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006883 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006884#endif
6885#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006886 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006887#endif
6888#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006889 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006890#endif
6891#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006892 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00006893#endif
6894#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006895 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006896#endif
6897#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006898 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006899#endif
6900#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006901 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006902#endif
6903#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006904 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006905#endif
6906#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006907 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006908#endif
6909#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006910 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006911#endif
Fred Draked86ed291999-12-15 15:34:33 +00006912#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00006913 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00006914#endif
Fred Drakec9680921999-12-13 16:37:25 +00006915#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006916 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006917#endif
6918#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006919 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006920#endif
6921#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006922 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006923#endif
Fred Draked86ed291999-12-15 15:34:33 +00006924#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006925 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00006926#endif
Fred Drakec9680921999-12-13 16:37:25 +00006927#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00006928 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00006929#endif
Fred Draked86ed291999-12-15 15:34:33 +00006930#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00006931 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00006932#endif
6933#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00006934 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00006935#endif
Fred Drakec9680921999-12-13 16:37:25 +00006936#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006937 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006938#endif
6939#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006940 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006941#endif
6942#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006943 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006944#endif
6945#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006946 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006947#endif
Fred Draked86ed291999-12-15 15:34:33 +00006948#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00006949 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00006950#endif
Fred Drakec9680921999-12-13 16:37:25 +00006951#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00006952 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00006953#endif
6954#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00006955 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00006956#endif
6957#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006958 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006959#endif
6960#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006961 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00006962#endif
6963#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00006964 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00006965#endif
6966#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00006967 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00006968#endif
6969#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00006970 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00006971#endif
Fred Draked86ed291999-12-15 15:34:33 +00006972#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00006973 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00006974#endif
Fred Drakec9680921999-12-13 16:37:25 +00006975#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006976 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006977#endif
6978#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006979 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006980#endif
Fred Draked86ed291999-12-15 15:34:33 +00006981#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006982 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006983#endif
Fred Drakec9680921999-12-13 16:37:25 +00006984#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006985 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006986#endif
6987#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006988 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006989#endif
6990#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006991 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006992#endif
6993#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006994 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006995#endif
6996#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006997 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006998#endif
6999#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007000 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007001#endif
7002#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007003 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007004#endif
7005#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007006 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00007007#endif
7008#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00007009 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00007010#endif
Fred Draked86ed291999-12-15 15:34:33 +00007011#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007012 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00007013#endif
7014#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00007015 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00007016#endif
Fred Drakec9680921999-12-13 16:37:25 +00007017#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00007018 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00007019#endif
7020#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007021 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007022#endif
7023#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007024 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007025#endif
7026#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007027 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007028#endif
7029#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007030 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007031#endif
7032#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00007033 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00007034#endif
7035#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00007036 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00007037#endif
7038#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00007039 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00007040#endif
7041#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00007042 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00007043#endif
7044#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00007045 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00007046#endif
7047#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00007048 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00007049#endif
7050#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007051 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00007052#endif
7053#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007054 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00007055#endif
7056#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00007057 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00007058#endif
7059#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00007060 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00007061#endif
7062#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00007063 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00007064#endif
7065#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00007066 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00007067#endif
7068#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007069 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007070#endif
7071#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007072 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007073#endif
7074#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00007075 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00007076#endif
7077#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007078 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007079#endif
7080#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007081 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007082#endif
7083#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00007084 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00007085#endif
7086#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007087 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007088#endif
7089#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007090 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007091#endif
7092#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007093 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00007094#endif
7095#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00007096 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00007097#endif
7098#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007099 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007100#endif
7101#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007102 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007103#endif
7104#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007105 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00007106#endif
7107#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007108 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007109#endif
7110#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007111 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007112#endif
7113#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007114 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007115#endif
7116#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007117 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007118#endif
7119#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007120 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007121#endif
Fred Draked86ed291999-12-15 15:34:33 +00007122#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00007123 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00007124#endif
Fred Drakec9680921999-12-13 16:37:25 +00007125#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00007126 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00007127#endif
7128#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007129 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007130#endif
7131#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00007132 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00007133#endif
7134#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007135 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007136#endif
7137#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007138 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007139#endif
7140#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007141 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007142#endif
7143#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00007144 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00007145#endif
7146#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007147 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007148#endif
7149#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007150 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007151#endif
7152#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007153 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007154#endif
7155#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007156 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007157#endif
7158#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007159 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00007160#endif
7161#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007162 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00007163#endif
7164#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00007165 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00007166#endif
7167#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007168 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007169#endif
7170#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007171 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007172#endif
7173#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007174 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007175#endif
7176#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00007177 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00007178#endif
7179#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007180 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007181#endif
7182#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007183 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007184#endif
7185#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007186 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007187#endif
7188#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007189 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007190#endif
7191#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007192 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007193#endif
7194#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007195 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007196#endif
7197#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00007198 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00007199#endif
7200#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007201 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007202#endif
7203#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007204 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007205#endif
7206#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007207 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007208#endif
7209#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007210 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007211#endif
7212#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00007213 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00007214#endif
7215#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007216 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007217#endif
7218#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00007219 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00007220#endif
7221#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007222 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007223#endif
7224#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00007225 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00007226#endif
7227#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00007228 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00007229#endif
7230#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00007231 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00007232#endif
7233#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00007234 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00007235#endif
7236#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007237 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007238#endif
7239#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00007240 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00007241#endif
7242#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00007243 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00007244#endif
7245#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007246 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007247#endif
7248#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007249 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007250#endif
7251#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00007252 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00007253#endif
7254#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00007255 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00007256#endif
7257#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00007258 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00007259#endif
7260};
7261
7262static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007263conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007264{
7265 return conv_confname(arg, valuep, posix_constants_sysconf,
7266 sizeof(posix_constants_sysconf)
7267 / sizeof(struct constdef));
7268}
7269
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007270PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007271"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007272Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007273
7274static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007275posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007276{
7277 PyObject *result = NULL;
7278 int name;
7279
7280 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7281 int value;
7282
7283 errno = 0;
7284 value = sysconf(name);
7285 if (value == -1 && errno != 0)
7286 posix_error();
7287 else
Christian Heimes217cfd12007-12-02 14:31:20 +00007288 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00007289 }
7290 return result;
7291}
7292#endif
7293
7294
Fred Drakebec628d1999-12-15 18:31:10 +00007295/* This code is used to ensure that the tables of configuration value names
7296 * are in sorted order as required by conv_confname(), and also to build the
7297 * the exported dictionaries that are used to publish information about the
7298 * names available on the host platform.
7299 *
7300 * Sorting the table at runtime ensures that the table is properly ordered
7301 * when used, even for platforms we're not able to test on. It also makes
7302 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007303 */
Fred Drakebec628d1999-12-15 18:31:10 +00007304
7305static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007306cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007307{
7308 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007309 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00007310 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007311 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00007312
7313 return strcmp(c1->name, c2->name);
7314}
7315
7316static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007317setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00007318 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007319{
Fred Drakebec628d1999-12-15 18:31:10 +00007320 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007321 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007322
7323 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7324 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007325 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00007326 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007327
Barry Warsaw3155db32000-04-13 15:20:40 +00007328 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007329 PyObject *o = PyLong_FromLong(table[i].value);
7330 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7331 Py_XDECREF(o);
7332 Py_DECREF(d);
7333 return -1;
7334 }
7335 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007336 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007337 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007338}
7339
Fred Drakebec628d1999-12-15 18:31:10 +00007340/* Return -1 on failure, 0 on success. */
7341static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007342setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007343{
7344#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007345 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007346 sizeof(posix_constants_pathconf)
7347 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007348 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00007349 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007350#endif
7351#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007352 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007353 sizeof(posix_constants_confstr)
7354 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007355 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00007356 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007357#endif
7358#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007359 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007360 sizeof(posix_constants_sysconf)
7361 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007362 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00007363 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007364#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007365 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007366}
Fred Draked86ed291999-12-15 15:34:33 +00007367
7368
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007369PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007370"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007371Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007372in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007373
7374static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007375posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007376{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007377 abort();
7378 /*NOTREACHED*/
7379 Py_FatalError("abort() called from Python code didn't abort!");
7380 return NULL;
7381}
Fred Drakebec628d1999-12-15 18:31:10 +00007382
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007383#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007384PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007385"startfile(filepath [, operation]) - Start a file with its associated\n\
7386application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007387\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007388When \"operation\" is not specified or \"open\", this acts like\n\
7389double-clicking the file in Explorer, or giving the file name as an\n\
7390argument to the DOS \"start\" command: the file is opened with whatever\n\
7391application (if any) its extension is associated.\n\
7392When another \"operation\" is given, it specifies what should be done with\n\
7393the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007394\n\
7395startfile returns as soon as the associated application is launched.\n\
7396There is no option to wait for the application to close, and no way\n\
7397to retrieve the application's exit status.\n\
7398\n\
7399The filepath is relative to the current directory. If you want to use\n\
7400an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007401the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007402
7403static PyObject *
7404win32_startfile(PyObject *self, PyObject *args)
7405{
Victor Stinner8c62be82010-05-06 00:08:46 +00007406 PyObject *ofilepath;
7407 char *filepath;
7408 char *operation = NULL;
7409 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00007410
Victor Stinner8c62be82010-05-06 00:08:46 +00007411 PyObject *unipath, *woperation = NULL;
7412 if (!PyArg_ParseTuple(args, "U|s:startfile",
7413 &unipath, &operation)) {
7414 PyErr_Clear();
7415 goto normal;
7416 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007417
Victor Stinner8c62be82010-05-06 00:08:46 +00007418 if (operation) {
7419 woperation = PyUnicode_DecodeASCII(operation,
7420 strlen(operation), NULL);
7421 if (!woperation) {
7422 PyErr_Clear();
7423 operation = NULL;
7424 goto normal;
7425 }
7426 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007427
Victor Stinner8c62be82010-05-06 00:08:46 +00007428 Py_BEGIN_ALLOW_THREADS
7429 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
7430 PyUnicode_AS_UNICODE(unipath),
7431 NULL, NULL, SW_SHOWNORMAL);
7432 Py_END_ALLOW_THREADS
7433
7434 Py_XDECREF(woperation);
7435 if (rc <= (HINSTANCE)32) {
7436 PyObject *errval = win32_error_unicode("startfile",
7437 PyUnicode_AS_UNICODE(unipath));
7438 return errval;
7439 }
7440 Py_INCREF(Py_None);
7441 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007442
7443normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00007444 if (!PyArg_ParseTuple(args, "O&|s:startfile",
7445 PyUnicode_FSConverter, &ofilepath,
7446 &operation))
7447 return NULL;
7448 filepath = PyBytes_AsString(ofilepath);
7449 Py_BEGIN_ALLOW_THREADS
7450 rc = ShellExecute((HWND)0, operation, filepath,
7451 NULL, NULL, SW_SHOWNORMAL);
7452 Py_END_ALLOW_THREADS
7453 if (rc <= (HINSTANCE)32) {
7454 PyObject *errval = win32_error("startfile", filepath);
7455 Py_DECREF(ofilepath);
7456 return errval;
7457 }
7458 Py_DECREF(ofilepath);
7459 Py_INCREF(Py_None);
7460 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007461}
7462#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007463
Martin v. Löwis438b5342002-12-27 10:16:42 +00007464#ifdef HAVE_GETLOADAVG
7465PyDoc_STRVAR(posix_getloadavg__doc__,
7466"getloadavg() -> (float, float, float)\n\n\
7467Return the number of processes in the system run queue averaged over\n\
7468the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7469was unobtainable");
7470
7471static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007472posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007473{
7474 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007475 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00007476 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7477 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00007478 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00007479 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00007480}
7481#endif
7482
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007483#ifdef MS_WINDOWS
7484
7485PyDoc_STRVAR(win32_urandom__doc__,
7486"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007487Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007488
7489typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7490 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7491 DWORD dwFlags );
7492typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7493 BYTE *pbBuffer );
7494
7495static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00007496/* This handle is never explicitly released. Instead, the operating
7497 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007498static HCRYPTPROV hCryptProv = 0;
7499
Tim Peters4ad82172004-08-30 17:02:04 +00007500static PyObject*
7501win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007502{
Victor Stinner8c62be82010-05-06 00:08:46 +00007503 int howMany;
7504 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007505
Victor Stinner8c62be82010-05-06 00:08:46 +00007506 /* Read arguments */
7507 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7508 return NULL;
7509 if (howMany < 0)
7510 return PyErr_Format(PyExc_ValueError,
7511 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007512
Victor Stinner8c62be82010-05-06 00:08:46 +00007513 if (hCryptProv == 0) {
7514 HINSTANCE hAdvAPI32 = NULL;
7515 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007516
Victor Stinner8c62be82010-05-06 00:08:46 +00007517 /* Obtain handle to the DLL containing CryptoAPI
7518 This should not fail */
7519 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7520 if(hAdvAPI32 == NULL)
7521 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007522
Victor Stinner8c62be82010-05-06 00:08:46 +00007523 /* Obtain pointers to the CryptoAPI functions
7524 This will fail on some early versions of Win95 */
7525 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7526 hAdvAPI32,
7527 "CryptAcquireContextA");
7528 if (pCryptAcquireContext == NULL)
7529 return PyErr_Format(PyExc_NotImplementedError,
7530 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007531
Victor Stinner8c62be82010-05-06 00:08:46 +00007532 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7533 hAdvAPI32, "CryptGenRandom");
7534 if (pCryptGenRandom == NULL)
7535 return PyErr_Format(PyExc_NotImplementedError,
7536 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007537
Victor Stinner8c62be82010-05-06 00:08:46 +00007538 /* Acquire context */
7539 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7540 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7541 return win32_error("CryptAcquireContext", NULL);
7542 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007543
Victor Stinner8c62be82010-05-06 00:08:46 +00007544 /* Allocate bytes */
7545 result = PyBytes_FromStringAndSize(NULL, howMany);
7546 if (result != NULL) {
7547 /* Get random data */
7548 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
7549 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7550 PyBytes_AS_STRING(result))) {
7551 Py_DECREF(result);
7552 return win32_error("CryptGenRandom", NULL);
7553 }
7554 }
7555 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007556}
7557#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007558
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007559PyDoc_STRVAR(device_encoding__doc__,
7560"device_encoding(fd) -> str\n\n\
7561Return a string describing the encoding of the device\n\
7562if the output is a terminal; else return None.");
7563
7564static PyObject *
7565device_encoding(PyObject *self, PyObject *args)
7566{
Victor Stinner8c62be82010-05-06 00:08:46 +00007567 int fd;
7568 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
7569 return NULL;
7570 if (!_PyVerify_fd(fd) || !isatty(fd)) {
7571 Py_INCREF(Py_None);
7572 return Py_None;
7573 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007574#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner8c62be82010-05-06 00:08:46 +00007575 if (fd == 0) {
7576 char buf[100];
7577 sprintf(buf, "cp%d", GetConsoleCP());
7578 return PyUnicode_FromString(buf);
7579 }
7580 if (fd == 1 || fd == 2) {
7581 char buf[100];
7582 sprintf(buf, "cp%d", GetConsoleOutputCP());
7583 return PyUnicode_FromString(buf);
7584 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007585#elif defined(CODESET)
Victor Stinner8c62be82010-05-06 00:08:46 +00007586 {
7587 char *codeset = nl_langinfo(CODESET);
7588 if (codeset != NULL && codeset[0] != 0)
7589 return PyUnicode_FromString(codeset);
7590 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007591#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007592 Py_INCREF(Py_None);
7593 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007594}
7595
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007596#ifdef __VMS
7597/* Use openssl random routine */
7598#include <openssl/rand.h>
7599PyDoc_STRVAR(vms_urandom__doc__,
7600"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007601Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007602
7603static PyObject*
7604vms_urandom(PyObject *self, PyObject *args)
7605{
Victor Stinner8c62be82010-05-06 00:08:46 +00007606 int howMany;
7607 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007608
Victor Stinner8c62be82010-05-06 00:08:46 +00007609 /* Read arguments */
7610 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7611 return NULL;
7612 if (howMany < 0)
7613 return PyErr_Format(PyExc_ValueError,
7614 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007615
Victor Stinner8c62be82010-05-06 00:08:46 +00007616 /* Allocate bytes */
7617 result = PyBytes_FromStringAndSize(NULL, howMany);
7618 if (result != NULL) {
7619 /* Get random data */
7620 if (RAND_pseudo_bytes((unsigned char*)
7621 PyBytes_AS_STRING(result),
7622 howMany) < 0) {
7623 Py_DECREF(result);
7624 return PyErr_Format(PyExc_ValueError,
7625 "RAND_pseudo_bytes");
7626 }
7627 }
7628 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007629}
7630#endif
7631
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007632#ifdef HAVE_SETRESUID
7633PyDoc_STRVAR(posix_setresuid__doc__,
7634"setresuid(ruid, euid, suid)\n\n\
7635Set the current process's real, effective, and saved user ids.");
7636
7637static PyObject*
7638posix_setresuid (PyObject *self, PyObject *args)
7639{
Victor Stinner8c62be82010-05-06 00:08:46 +00007640 /* We assume uid_t is no larger than a long. */
7641 long ruid, euid, suid;
7642 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
7643 return NULL;
7644 if (setresuid(ruid, euid, suid) < 0)
7645 return posix_error();
7646 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007647}
7648#endif
7649
7650#ifdef HAVE_SETRESGID
7651PyDoc_STRVAR(posix_setresgid__doc__,
7652"setresgid(rgid, egid, sgid)\n\n\
7653Set the current process's real, effective, and saved group ids.");
7654
7655static PyObject*
7656posix_setresgid (PyObject *self, PyObject *args)
7657{
Victor Stinner8c62be82010-05-06 00:08:46 +00007658 /* We assume uid_t is no larger than a long. */
7659 long rgid, egid, sgid;
7660 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
7661 return NULL;
7662 if (setresgid(rgid, egid, sgid) < 0)
7663 return posix_error();
7664 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007665}
7666#endif
7667
7668#ifdef HAVE_GETRESUID
7669PyDoc_STRVAR(posix_getresuid__doc__,
7670"getresuid() -> (ruid, euid, suid)\n\n\
7671Get tuple of the current process's real, effective, and saved user ids.");
7672
7673static PyObject*
7674posix_getresuid (PyObject *self, PyObject *noargs)
7675{
Victor Stinner8c62be82010-05-06 00:08:46 +00007676 uid_t ruid, euid, suid;
7677 long l_ruid, l_euid, l_suid;
7678 if (getresuid(&ruid, &euid, &suid) < 0)
7679 return posix_error();
7680 /* Force the values into long's as we don't know the size of uid_t. */
7681 l_ruid = ruid;
7682 l_euid = euid;
7683 l_suid = suid;
7684 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007685}
7686#endif
7687
7688#ifdef HAVE_GETRESGID
7689PyDoc_STRVAR(posix_getresgid__doc__,
7690"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00007691Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007692
7693static PyObject*
7694posix_getresgid (PyObject *self, PyObject *noargs)
7695{
Victor Stinner8c62be82010-05-06 00:08:46 +00007696 uid_t rgid, egid, sgid;
7697 long l_rgid, l_egid, l_sgid;
7698 if (getresgid(&rgid, &egid, &sgid) < 0)
7699 return posix_error();
7700 /* Force the values into long's as we don't know the size of uid_t. */
7701 l_rgid = rgid;
7702 l_egid = egid;
7703 l_sgid = sgid;
7704 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007705}
7706#endif
7707
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007708static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00007709 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007710#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007711 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007712#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007713 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007714#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007715 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007716#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007717 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007718#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007719 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007720#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007721#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007722 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007723#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00007724#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007725 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007726#endif /* HAVE_LCHMOD */
7727#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007728 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007729#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00007730#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007731 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007732#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007733#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007734 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007735#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007736#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +00007737 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00007738#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007739#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +00007740 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007741#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007742#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +00007743 {"getcwd", (PyCFunction)posix_getcwd_unicode,
7744 METH_NOARGS, posix_getcwd__doc__},
7745 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
7746 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007747#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007748#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007749 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007750#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +00007751 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7752 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7753 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007754#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +00007755 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007756#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007757#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007758 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007759#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007760#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007761 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007762#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007763 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7764 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7765 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +00007766 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007767#ifdef HAVE_SYMLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007768 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007769#endif /* HAVE_SYMLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007770#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin74e45612010-07-09 15:58:59 +00007771 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
7772 win_symlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007773#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007774#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +00007775 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007776#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007777 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007778#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007779 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007780#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +00007781 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7782 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7783 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007784#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00007785 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007786#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00007787 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007788#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +00007789 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7790 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007791#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007792#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +00007793 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7794 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007795#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00007796 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7797 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007798#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007799#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007800#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +00007801 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007802#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007803#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +00007804 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007805#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007806#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +00007807 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007808#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007809#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007810 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007811#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007812#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007813 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007814#endif /* HAVE_GETEGID */
7815#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007816 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007817#endif /* HAVE_GETEUID */
7818#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007819 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007820#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007821#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007822 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007823#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007824 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007825#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007826 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007827#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007828#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +00007829 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007830#endif /* HAVE_GETPPID */
7831#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007832 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007833#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007834#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007835 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007836#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007837#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +00007838 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007839#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007840#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +00007841 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007842#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007843#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007844 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007845#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007846#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007847 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7848 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Brian Curtin1b9df392010-11-24 20:24:31 +00007849 {"link", win32_link, METH_VARARGS, win32_link__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +00007850#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007851#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007852 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007853#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007854#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007855 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007856#endif /* HAVE_SETEUID */
7857#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007858 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007859#endif /* HAVE_SETEGID */
7860#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007861 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007862#endif /* HAVE_SETREUID */
7863#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007864 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007865#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007866#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007867 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007868#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007869#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007870 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007871#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +00007872#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007873 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +00007874#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007875#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007876 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00007877#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007878#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007879 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007880#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007881#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007882 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007883#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007884#ifdef HAVE_WAIT3
Victor Stinner8c62be82010-05-06 00:08:46 +00007885 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007886#endif /* HAVE_WAIT3 */
7887#ifdef HAVE_WAIT4
Victor Stinner8c62be82010-05-06 00:08:46 +00007888 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007889#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007890#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007891 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007892#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007893#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007894 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007895#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007896#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007897 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007898#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007899#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007900 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007901#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007902#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007903 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007904#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007905#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007906 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007907#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +00007908 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7909 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7910 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
7911 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
7912 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7913 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7914 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7915 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7916 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7917 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7918 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007919#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +00007920 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007921#endif
7922#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +00007923 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007924#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007925#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +00007926 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007927#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007928#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +00007929 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7930 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7931 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007932#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007933#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +00007934 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007935#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007936#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007937 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007938#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007939#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007940 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00007941#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007942 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007943#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +00007944 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007945#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007946#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007947 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007948#endif
7949#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007950 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007951#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007952#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007953#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +00007954 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00007955#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007956#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00007957 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007958#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007959#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +00007960 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007961#endif /* WIFSTOPPED */
7962#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +00007963 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007964#endif /* WIFSIGNALED */
7965#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +00007966 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007967#endif /* WIFEXITED */
7968#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +00007969 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007970#endif /* WEXITSTATUS */
7971#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007972 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007973#endif /* WTERMSIG */
7974#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007975 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007976#endif /* WSTOPSIG */
7977#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007978#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007979 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007980#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007981#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007982 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007983#endif
Fred Drakec9680921999-12-13 16:37:25 +00007984#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +00007985 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007986#endif
7987#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007988 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007989#endif
7990#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007991 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007992#endif
7993#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007994 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007995#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007996 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007997#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007998 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +00007999 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +00008000 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Mark Hammondef8b6542001-05-13 08:04:26 +00008001#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008002#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +00008003 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008004#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008005 #ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008006 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008007 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008008 #ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008009 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008010 #endif
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008011#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008012 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008013#endif
8014#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008015 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008016#endif
8017#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008018 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008019#endif
8020#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008021 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008022#endif
8023
Victor Stinner8c62be82010-05-06 00:08:46 +00008024 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008025};
8026
8027
Barry Warsaw4a342091996-12-19 23:50:02 +00008028static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008029ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008030{
Victor Stinner8c62be82010-05-06 00:08:46 +00008031 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008032}
8033
Guido van Rossumd48f2521997-12-05 22:19:34 +00008034#if defined(PYOS_OS2)
8035/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008036static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008037{
8038 APIRET rc;
8039 ULONG values[QSV_MAX+1];
8040 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008041 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008042
8043 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008044 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008045 Py_END_ALLOW_THREADS
8046
8047 if (rc != NO_ERROR) {
8048 os2_error(rc);
8049 return -1;
8050 }
8051
Fred Drake4d1e64b2002-04-15 19:40:07 +00008052 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8053 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8054 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8055 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8056 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8057 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8058 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008059
8060 switch (values[QSV_VERSION_MINOR]) {
8061 case 0: ver = "2.00"; break;
8062 case 10: ver = "2.10"; break;
8063 case 11: ver = "2.11"; break;
8064 case 30: ver = "3.00"; break;
8065 case 40: ver = "4.00"; break;
8066 case 50: ver = "5.00"; break;
8067 default:
Tim Peters885d4572001-11-28 20:27:42 +00008068 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +00008069 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00008070 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008071 ver = &tmp[0];
8072 }
8073
8074 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008075 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008076 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008077
8078 /* Add Indicator of Which Drive was Used to Boot the System */
8079 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8080 tmp[1] = ':';
8081 tmp[2] = '\0';
8082
Fred Drake4d1e64b2002-04-15 19:40:07 +00008083 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008084}
8085#endif
8086
Barry Warsaw4a342091996-12-19 23:50:02 +00008087static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008088all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008089{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008090#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008091 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008092#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008093#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008094 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008095#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008096#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008097 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008098#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008099#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008100 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008101#endif
Fred Drakec9680921999-12-13 16:37:25 +00008102#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008103 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00008104#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008105#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008106 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008107#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008108#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00008109 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008110#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008111#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +00008112 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008113#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008114#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +00008115 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008116#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008117#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008118 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008119#endif
8120#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008121 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008122#endif
8123#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +00008124 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008125#endif
8126#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +00008127 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008128#endif
8129#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008130 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008131#endif
8132#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +00008133 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008134#endif
8135#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008136 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008137#endif
8138#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008139 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008140#endif
8141#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008142 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008143#endif
8144#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +00008145 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008146#endif
8147#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008148 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008149#endif
8150#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +00008151 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008152#endif
8153#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008154 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008155#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008156#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008157 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008158#endif
8159#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +00008160 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008161#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008162#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008163 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008164#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008165#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008166 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008167#endif
8168#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008169 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008170#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008171
Tim Peters5aa91602002-01-30 05:46:57 +00008172/* MS Windows */
8173#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008174 /* Don't inherit in child processes. */
8175 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008176#endif
8177#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +00008178 /* Optimize for short life (keep in memory). */
8179 /* MS forgot to define this one with a non-underscore form too. */
8180 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008181#endif
8182#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008183 /* Automatically delete when last handle is closed. */
8184 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008185#endif
8186#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +00008187 /* Optimize for random access. */
8188 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008189#endif
8190#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008191 /* Optimize for sequential access. */
8192 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008193#endif
8194
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008195/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008196#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008197 /* Send a SIGIO signal whenever input or output
8198 becomes available on file descriptor */
8199 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008200#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008201#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008202 /* Direct disk access. */
8203 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008204#endif
8205#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +00008206 /* Must be a directory. */
8207 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008208#endif
8209#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +00008210 /* Do not follow links. */
8211 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008212#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008213#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +00008214 /* Do not update the access time. */
8215 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008216#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008217
Victor Stinner8c62be82010-05-06 00:08:46 +00008218 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008219#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008220 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008221#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008222#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008223 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008224#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008225#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008226 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008227#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008228#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008229 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008230#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008231#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +00008232 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008233#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008234#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +00008235 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008236#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008237#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008238 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008239#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008240#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +00008241 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008242#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008243#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008244 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008245#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008246#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008247 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008248#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008249#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008250 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008251#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008252#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008253 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008254#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008255#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +00008256 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008257#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008258#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +00008259 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008260#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008261#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008262 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008263#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008264#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008265 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008266#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008267#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +00008268 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008269#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008270
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008271 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008272#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008273 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008274#endif /* ST_RDONLY */
8275#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008276 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008277#endif /* ST_NOSUID */
8278
Guido van Rossum246bc171999-02-01 23:54:31 +00008279#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008280#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00008281 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8282 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8283 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8284 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8285 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8286 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8287 if (ins(d, "P_PM", (long)P_PM)) return -1;
8288 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8289 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8290 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8291 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8292 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8293 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8294 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8295 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8296 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8297 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8298 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8299 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8300 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008301#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008302 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8303 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8304 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8305 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8306 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008307#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008308#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008309
Guido van Rossumd48f2521997-12-05 22:19:34 +00008310#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00008311 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008312#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008313 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00008314}
8315
8316
Tim Peters5aa91602002-01-30 05:46:57 +00008317#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008318#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008319#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008320
8321#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008322#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008323#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008324
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008325#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00008326#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008327#define MODNAME "posix"
8328#endif
8329
Martin v. Löwis1a214512008-06-11 05:26:20 +00008330static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +00008331 PyModuleDef_HEAD_INIT,
8332 MODNAME,
8333 posix__doc__,
8334 -1,
8335 posix_methods,
8336 NULL,
8337 NULL,
8338 NULL,
8339 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00008340};
8341
8342
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008343PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008344INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008345{
Victor Stinner8c62be82010-05-06 00:08:46 +00008346 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008347
Victor Stinner8c62be82010-05-06 00:08:46 +00008348 m = PyModule_Create(&posixmodule);
8349 if (m == NULL)
8350 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008351
Victor Stinner8c62be82010-05-06 00:08:46 +00008352 /* Initialize environ dictionary */
8353 v = convertenviron();
8354 Py_XINCREF(v);
8355 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
8356 return NULL;
8357 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008358
Victor Stinner8c62be82010-05-06 00:08:46 +00008359 if (all_ins(m))
8360 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00008361
Victor Stinner8c62be82010-05-06 00:08:46 +00008362 if (setup_confname_tables(m))
8363 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00008364
Victor Stinner8c62be82010-05-06 00:08:46 +00008365 Py_INCREF(PyExc_OSError);
8366 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008367
Guido van Rossumb3d39562000-01-31 18:41:26 +00008368#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00008369 if (posix_putenv_garbage == NULL)
8370 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008371#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008372
Victor Stinner8c62be82010-05-06 00:08:46 +00008373 if (!initialized) {
8374 stat_result_desc.name = MODNAME ".stat_result";
8375 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8376 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8377 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8378 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8379 structseq_new = StatResultType.tp_new;
8380 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008381
Victor Stinner8c62be82010-05-06 00:08:46 +00008382 statvfs_result_desc.name = MODNAME ".statvfs_result";
8383 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008384#ifdef NEED_TICKS_PER_SECOND
8385# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +00008386 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008387# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +00008388 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008389# else
Victor Stinner8c62be82010-05-06 00:08:46 +00008390 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008391# endif
8392#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008393 }
8394 Py_INCREF((PyObject*) &StatResultType);
8395 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
8396 Py_INCREF((PyObject*) &StatVFSResultType);
8397 PyModule_AddObject(m, "statvfs_result",
8398 (PyObject*) &StatVFSResultType);
8399 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008400
8401#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +00008402 /*
8403 * Step 2 of weak-linking support on Mac OS X.
8404 *
8405 * The code below removes functions that are not available on the
8406 * currently active platform.
8407 *
8408 * This block allow one to use a python binary that was build on
8409 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8410 * OSX 10.4.
8411 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008412#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008413 if (fstatvfs == NULL) {
8414 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8415 return NULL;
8416 }
8417 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008418#endif /* HAVE_FSTATVFS */
8419
8420#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008421 if (statvfs == NULL) {
8422 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8423 return NULL;
8424 }
8425 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008426#endif /* HAVE_STATVFS */
8427
8428# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00008429 if (lchown == NULL) {
8430 if (PyObject_DelAttrString(m, "lchown") == -1) {
8431 return NULL;
8432 }
8433 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008434#endif /* HAVE_LCHOWN */
8435
8436
8437#endif /* __APPLE__ */
Victor Stinner8c62be82010-05-06 00:08:46 +00008438 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008439
Guido van Rossumb6775db1994-08-01 11:34:53 +00008440}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008441
8442#ifdef __cplusplus
8443}
8444#endif