blob: 028516541a42254fcf4eb357d9614d49a60d685e [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
2266 if (rslt == 0)
2267 return posix_error();
2268
2269 Py_RETURN_NONE;
2270}
2271#endif /* MS_WINDOWS */
2272
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002273
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002274PyDoc_STRVAR(posix_listdir__doc__,
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002275"listdir([path]) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002276Return a list containing the names of the entries in the directory.\n\
2277\n\
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002278 path: path of directory to list (default: '.')\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002279\n\
2280The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002281entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002282
Barry Warsaw53699e91996-12-10 23:23:01 +00002283static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002284posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002285{
Victor Stinner8c62be82010-05-06 00:08:46 +00002286 /* XXX Should redo this putting the (now four) versions of opendir
2287 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002288#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002289
Victor Stinner8c62be82010-05-06 00:08:46 +00002290 PyObject *d, *v;
2291 HANDLE hFindFile;
2292 BOOL result;
2293 WIN32_FIND_DATA FileData;
2294 PyObject *opath;
2295 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2296 char *bufptr = namebuf;
2297 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002298
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002299 PyObject *po = NULL;
2300 if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002301 WIN32_FIND_DATAW wFileData;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002302 Py_UNICODE *wnamebuf, *po_wchars;
2303
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002304 if (po == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002305 po_wchars = L".";
2306 len = 1;
2307 } else {
2308 po_wchars = PyUnicode_AS_UNICODE(po);
2309 len = PyUnicode_GET_SIZE(po);
2310 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002311 /* Overallocate for \\*.*\0 */
Victor Stinner8c62be82010-05-06 00:08:46 +00002312 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2313 if (!wnamebuf) {
2314 PyErr_NoMemory();
2315 return NULL;
2316 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002317 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00002318 if (len > 0) {
2319 Py_UNICODE wch = wnamebuf[len-1];
2320 if (wch != L'/' && wch != L'\\' && wch != L':')
2321 wnamebuf[len++] = L'\\';
2322 wcscpy(wnamebuf + len, L"*.*");
2323 }
2324 if ((d = PyList_New(0)) == NULL) {
2325 free(wnamebuf);
2326 return NULL;
2327 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00002328 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002329 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002330 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002331 if (hFindFile == INVALID_HANDLE_VALUE) {
2332 int error = GetLastError();
2333 if (error == ERROR_FILE_NOT_FOUND) {
2334 free(wnamebuf);
2335 return d;
2336 }
2337 Py_DECREF(d);
2338 win32_error_unicode("FindFirstFileW", wnamebuf);
2339 free(wnamebuf);
2340 return NULL;
2341 }
2342 do {
2343 /* Skip over . and .. */
2344 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2345 wcscmp(wFileData.cFileName, L"..") != 0) {
2346 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2347 if (v == NULL) {
2348 Py_DECREF(d);
2349 d = NULL;
2350 break;
2351 }
2352 if (PyList_Append(d, v) != 0) {
2353 Py_DECREF(v);
2354 Py_DECREF(d);
2355 d = NULL;
2356 break;
2357 }
2358 Py_DECREF(v);
2359 }
2360 Py_BEGIN_ALLOW_THREADS
2361 result = FindNextFileW(hFindFile, &wFileData);
2362 Py_END_ALLOW_THREADS
2363 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2364 it got to the end of the directory. */
2365 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2366 Py_DECREF(d);
2367 win32_error_unicode("FindNextFileW", wnamebuf);
2368 FindClose(hFindFile);
2369 free(wnamebuf);
2370 return NULL;
2371 }
2372 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002373
Victor Stinner8c62be82010-05-06 00:08:46 +00002374 if (FindClose(hFindFile) == FALSE) {
2375 Py_DECREF(d);
2376 win32_error_unicode("FindClose", wnamebuf);
2377 free(wnamebuf);
2378 return NULL;
2379 }
2380 free(wnamebuf);
2381 return d;
2382 }
2383 /* Drop the argument parsing error as narrow strings
2384 are also valid. */
2385 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002386
Victor Stinner8c62be82010-05-06 00:08:46 +00002387 if (!PyArg_ParseTuple(args, "O&:listdir",
2388 PyUnicode_FSConverter, &opath))
2389 return NULL;
2390 if (PyBytes_GET_SIZE(opath)+1 > MAX_PATH) {
2391 PyErr_SetString(PyExc_ValueError, "path too long");
2392 Py_DECREF(opath);
2393 return NULL;
2394 }
2395 strcpy(namebuf, PyBytes_AsString(opath));
2396 len = PyObject_Size(opath);
2397 if (len > 0) {
2398 char ch = namebuf[len-1];
2399 if (ch != SEP && ch != ALTSEP && ch != ':')
2400 namebuf[len++] = '/';
2401 strcpy(namebuf + len, "*.*");
2402 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002403
Victor Stinner8c62be82010-05-06 00:08:46 +00002404 if ((d = PyList_New(0)) == NULL)
2405 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002406
Antoine Pitroub73caab2010-08-09 23:39:31 +00002407 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002408 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002409 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002410 if (hFindFile == INVALID_HANDLE_VALUE) {
2411 int error = GetLastError();
2412 if (error == ERROR_FILE_NOT_FOUND)
2413 return d;
2414 Py_DECREF(d);
2415 return win32_error("FindFirstFile", namebuf);
2416 }
2417 do {
2418 /* Skip over . and .. */
2419 if (strcmp(FileData.cFileName, ".") != 0 &&
2420 strcmp(FileData.cFileName, "..") != 0) {
2421 v = PyBytes_FromString(FileData.cFileName);
2422 if (v == NULL) {
2423 Py_DECREF(d);
2424 d = NULL;
2425 break;
2426 }
2427 if (PyList_Append(d, v) != 0) {
2428 Py_DECREF(v);
2429 Py_DECREF(d);
2430 d = NULL;
2431 break;
2432 }
2433 Py_DECREF(v);
2434 }
2435 Py_BEGIN_ALLOW_THREADS
2436 result = FindNextFile(hFindFile, &FileData);
2437 Py_END_ALLOW_THREADS
2438 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2439 it got to the end of the directory. */
2440 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2441 Py_DECREF(d);
2442 win32_error("FindNextFile", namebuf);
2443 FindClose(hFindFile);
2444 return NULL;
2445 }
2446 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002447
Victor Stinner8c62be82010-05-06 00:08:46 +00002448 if (FindClose(hFindFile) == FALSE) {
2449 Py_DECREF(d);
2450 return win32_error("FindClose", namebuf);
2451 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002452
Victor Stinner8c62be82010-05-06 00:08:46 +00002453 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002454
Tim Peters0bb44a42000-09-15 07:44:49 +00002455#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002456
2457#ifndef MAX_PATH
2458#define MAX_PATH CCHMAXPATH
2459#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002460 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002461 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002462 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002463 PyObject *d, *v;
2464 char namebuf[MAX_PATH+5];
2465 HDIR hdir = 1;
2466 ULONG srchcnt = 1;
2467 FILEFINDBUF3 ep;
2468 APIRET rc;
2469
Victor Stinner8c62be82010-05-06 00:08:46 +00002470 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002471 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002472 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002473 name = PyBytes_AsString(oname);
2474 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002475 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002476 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002477 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002478 return NULL;
2479 }
2480 strcpy(namebuf, name);
2481 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002482 if (*pt == ALTSEP)
2483 *pt = SEP;
2484 if (namebuf[len-1] != SEP)
2485 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002486 strcpy(namebuf + len, "*.*");
2487
Neal Norwitz6c913782007-10-14 03:23:09 +00002488 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002489 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002490 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002491 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002492
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002493 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2494 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002495 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002496 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2497 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2498 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002499
2500 if (rc != NO_ERROR) {
2501 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002502 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002503 }
2504
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002505 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002506 do {
2507 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002508 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002509 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002510
2511 strcpy(namebuf, ep.achName);
2512
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002513 /* Leave Case of Name Alone -- In Native Form */
2514 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002515
Christian Heimes72b710a2008-05-26 13:28:38 +00002516 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002517 if (v == NULL) {
2518 Py_DECREF(d);
2519 d = NULL;
2520 break;
2521 }
2522 if (PyList_Append(d, v) != 0) {
2523 Py_DECREF(v);
2524 Py_DECREF(d);
2525 d = NULL;
2526 break;
2527 }
2528 Py_DECREF(v);
2529 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2530 }
2531
Victor Stinnerdcb24032010-04-22 12:08:36 +00002532 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002533 return d;
2534#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002535 PyObject *oname;
2536 char *name;
2537 PyObject *d, *v;
2538 DIR *dirp;
2539 struct dirent *ep;
2540 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002541
Victor Stinner8c62be82010-05-06 00:08:46 +00002542 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002543 /* v is never read, so it does not need to be initialized yet. */
2544 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002545 arg_is_unicode = 0;
2546 PyErr_Clear();
2547 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002548 oname = NULL;
2549 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
Victor Stinner8c62be82010-05-06 00:08:46 +00002550 return NULL;
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002551 if (oname == NULL) { /* Default arg: "." */
Stefan Krah0e803b32010-11-26 16:16:47 +00002552 oname = PyBytes_FromString(".");
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002553 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002554 name = PyBytes_AsString(oname);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002555 Py_BEGIN_ALLOW_THREADS
2556 dirp = opendir(name);
2557 Py_END_ALLOW_THREADS
2558 if (dirp == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002559 return posix_error_with_allocated_filename(oname);
2560 }
2561 if ((d = PyList_New(0)) == NULL) {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002562 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002563 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002564 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002565 Py_DECREF(oname);
2566 return NULL;
2567 }
2568 for (;;) {
2569 errno = 0;
2570 Py_BEGIN_ALLOW_THREADS
2571 ep = readdir(dirp);
2572 Py_END_ALLOW_THREADS
2573 if (ep == NULL) {
2574 if (errno == 0) {
2575 break;
2576 } else {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002577 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002578 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002579 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002580 Py_DECREF(d);
2581 return posix_error_with_allocated_filename(oname);
2582 }
2583 }
2584 if (ep->d_name[0] == '.' &&
2585 (NAMLEN(ep) == 1 ||
2586 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2587 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002588 if (arg_is_unicode)
2589 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2590 else
2591 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002592 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002593 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002594 break;
2595 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002596 if (PyList_Append(d, v) != 0) {
2597 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002598 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002599 break;
2600 }
2601 Py_DECREF(v);
2602 }
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002603 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002604 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002605 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002606 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002607
Victor Stinner8c62be82010-05-06 00:08:46 +00002608 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002609
Tim Peters0bb44a42000-09-15 07:44:49 +00002610#endif /* which OS */
2611} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002612
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002613#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002614/* A helper function for abspath on win32 */
2615static PyObject *
2616posix__getfullpathname(PyObject *self, PyObject *args)
2617{
Victor Stinner8c62be82010-05-06 00:08:46 +00002618 PyObject *opath;
2619 char *path;
2620 char outbuf[MAX_PATH*2];
2621 char *temp;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002622#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002623 PyUnicodeObject *po;
2624 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2625 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2626 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2627 Py_UNICODE *wtemp;
2628 DWORD result;
2629 PyObject *v;
2630 result = GetFullPathNameW(wpath,
2631 sizeof(woutbuf)/sizeof(woutbuf[0]),
2632 woutbuf, &wtemp);
2633 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2634 woutbufp = malloc(result * sizeof(Py_UNICODE));
2635 if (!woutbufp)
2636 return PyErr_NoMemory();
2637 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2638 }
2639 if (result)
2640 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2641 else
2642 v = win32_error_unicode("GetFullPathNameW", wpath);
2643 if (woutbufp != woutbuf)
2644 free(woutbufp);
2645 return v;
2646 }
2647 /* Drop the argument parsing error as narrow strings
2648 are also valid. */
2649 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002650
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002651#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002652 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2653 PyUnicode_FSConverter, &opath))
2654 return NULL;
2655 path = PyBytes_AsString(opath);
2656 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2657 outbuf, &temp)) {
2658 win32_error("GetFullPathName", path);
2659 Py_DECREF(opath);
2660 return NULL;
2661 }
2662 Py_DECREF(opath);
2663 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2664 return PyUnicode_Decode(outbuf, strlen(outbuf),
2665 Py_FileSystemDefaultEncoding, NULL);
2666 }
2667 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002668} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00002669
Brian Curtinf5e76d02010-11-24 13:14:05 +00002670/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
2671static int has_GetFinalPathNameByHandle = 0;
2672static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
2673 DWORD);
2674static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
2675 DWORD);
2676static int
2677check_GetFinalPathNameByHandle()
2678{
2679 HINSTANCE hKernel32;
2680 /* only recheck */
2681 if (!has_GetFinalPathNameByHandle)
2682 {
2683 hKernel32 = GetModuleHandle("KERNEL32");
2684 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
2685 "GetFinalPathNameByHandleA");
2686 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
2687 "GetFinalPathNameByHandleW");
2688 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
2689 Py_GetFinalPathNameByHandleW;
2690 }
2691 return has_GetFinalPathNameByHandle;
2692}
2693
Brian Curtind40e6f72010-07-08 21:39:08 +00002694/* A helper function for samepath on windows */
2695static PyObject *
2696posix__getfinalpathname(PyObject *self, PyObject *args)
2697{
2698 HANDLE hFile;
2699 int buf_size;
2700 wchar_t *target_path;
2701 int result_length;
2702 PyObject *result;
2703 wchar_t *path;
2704
Brian Curtin94622b02010-09-24 00:03:39 +00002705 if (!PyArg_ParseTuple(args, "u|:_getfinalpathname", &path)) {
Brian Curtind40e6f72010-07-08 21:39:08 +00002706 return NULL;
2707 }
2708
2709 if(!check_GetFinalPathNameByHandle()) {
2710 /* If the OS doesn't have GetFinalPathNameByHandle, return a
2711 NotImplementedError. */
2712 return PyErr_Format(PyExc_NotImplementedError,
2713 "GetFinalPathNameByHandle not available on this platform");
2714 }
2715
2716 hFile = CreateFileW(
2717 path,
2718 0, /* desired access */
2719 0, /* share mode */
2720 NULL, /* security attributes */
2721 OPEN_EXISTING,
2722 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
2723 FILE_FLAG_BACKUP_SEMANTICS,
2724 NULL);
2725
2726 if(hFile == INVALID_HANDLE_VALUE) {
2727 return win32_error_unicode("GetFinalPathNamyByHandle", path);
Brian Curtin74e45612010-07-09 15:58:59 +00002728 return PyErr_Format(PyExc_RuntimeError,
2729 "Could not get a handle to file.");
Brian Curtind40e6f72010-07-08 21:39:08 +00002730 }
2731
2732 /* We have a good handle to the target, use it to determine the
2733 target path name. */
2734 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
2735
2736 if(!buf_size)
2737 return win32_error_unicode("GetFinalPathNameByHandle", path);
2738
2739 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
2740 if(!target_path)
2741 return PyErr_NoMemory();
2742
2743 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
2744 buf_size, VOLUME_NAME_DOS);
2745 if(!result_length)
2746 return win32_error_unicode("GetFinalPathNamyByHandle", path);
2747
2748 if(!CloseHandle(hFile))
2749 return win32_error_unicode("GetFinalPathNameByHandle", path);
2750
2751 target_path[result_length] = 0;
2752 result = PyUnicode_FromUnicode(target_path, result_length);
2753 free(target_path);
2754 return result;
2755
2756} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00002757
2758static PyObject *
2759posix__getfileinformation(PyObject *self, PyObject *args)
2760{
2761 HANDLE hFile;
2762 BY_HANDLE_FILE_INFORMATION info;
2763 int fd;
2764
2765 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
2766 return NULL;
2767
2768 if (!_PyVerify_fd(fd)) {
2769 PyErr_SetString(PyExc_ValueError, "received invalid file descriptor");
2770 return NULL;
2771 }
2772
2773 hFile = (HANDLE)_get_osfhandle(fd);
2774 if (hFile == INVALID_HANDLE_VALUE)
2775 return win32_error("_getfileinformation", NULL);
2776
2777 if (!GetFileInformationByHandle(hFile, &info))
2778 return win32_error("_getfileinformation", NULL);
2779
2780 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
2781 info.nFileIndexHigh,
2782 info.nFileIndexLow);
2783}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002784#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002785
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002786PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002787"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002788Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002789
Barry Warsaw53699e91996-12-10 23:23:01 +00002790static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002791posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002792{
Victor Stinner8c62be82010-05-06 00:08:46 +00002793 int res;
2794 PyObject *opath;
2795 char *path;
2796 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002797
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002798#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002799 PyUnicodeObject *po;
2800 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2801 Py_BEGIN_ALLOW_THREADS
2802 /* PyUnicode_AS_UNICODE OK without thread lock as
2803 it is a simple dereference. */
2804 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2805 Py_END_ALLOW_THREADS
2806 if (!res)
2807 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2808 Py_INCREF(Py_None);
2809 return Py_None;
2810 }
2811 /* Drop the argument parsing error as narrow strings
2812 are also valid. */
2813 PyErr_Clear();
2814 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2815 PyUnicode_FSConverter, &opath, &mode))
2816 return NULL;
2817 path = PyBytes_AsString(opath);
2818 Py_BEGIN_ALLOW_THREADS
2819 /* PyUnicode_AS_UNICODE OK without thread lock as
2820 it is a simple dereference. */
2821 res = CreateDirectoryA(path, NULL);
2822 Py_END_ALLOW_THREADS
2823 if (!res) {
2824 win32_error("mkdir", path);
2825 Py_DECREF(opath);
2826 return NULL;
2827 }
2828 Py_DECREF(opath);
2829 Py_INCREF(Py_None);
2830 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002831#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002832
Victor Stinner8c62be82010-05-06 00:08:46 +00002833 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2834 PyUnicode_FSConverter, &opath, &mode))
2835 return NULL;
2836 path = PyBytes_AsString(opath);
2837 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002838#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00002839 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002840#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002841 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002842#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002843 Py_END_ALLOW_THREADS
2844 if (res < 0)
2845 return posix_error_with_allocated_filename(opath);
2846 Py_DECREF(opath);
2847 Py_INCREF(Py_None);
2848 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002849#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002850}
2851
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002852
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002853/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2854#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002855#include <sys/resource.h>
2856#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002857
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002858
2859#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002860PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002861"nice(inc) -> new_priority\n\n\
2862Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002863
Barry Warsaw53699e91996-12-10 23:23:01 +00002864static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002865posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002866{
Victor Stinner8c62be82010-05-06 00:08:46 +00002867 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002868
Victor Stinner8c62be82010-05-06 00:08:46 +00002869 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2870 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002871
Victor Stinner8c62be82010-05-06 00:08:46 +00002872 /* There are two flavours of 'nice': one that returns the new
2873 priority (as required by almost all standards out there) and the
2874 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2875 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002876
Victor Stinner8c62be82010-05-06 00:08:46 +00002877 If we are of the nice family that returns the new priority, we
2878 need to clear errno before the call, and check if errno is filled
2879 before calling posix_error() on a returnvalue of -1, because the
2880 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002881
Victor Stinner8c62be82010-05-06 00:08:46 +00002882 errno = 0;
2883 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002884#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00002885 if (value == 0)
2886 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002887#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002888 if (value == -1 && errno != 0)
2889 /* either nice() or getpriority() returned an error */
2890 return posix_error();
2891 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002892}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002893#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002894
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002895PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002896"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002897Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002898
Barry Warsaw53699e91996-12-10 23:23:01 +00002899static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002900posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002901{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002902#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002903 PyObject *o1, *o2;
2904 char *p1, *p2;
2905 BOOL result;
2906 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2907 goto error;
2908 if (!convert_to_unicode(&o1))
2909 goto error;
2910 if (!convert_to_unicode(&o2)) {
2911 Py_DECREF(o1);
2912 goto error;
2913 }
2914 Py_BEGIN_ALLOW_THREADS
2915 result = MoveFileW(PyUnicode_AsUnicode(o1),
2916 PyUnicode_AsUnicode(o2));
2917 Py_END_ALLOW_THREADS
2918 Py_DECREF(o1);
2919 Py_DECREF(o2);
2920 if (!result)
2921 return win32_error("rename", NULL);
2922 Py_INCREF(Py_None);
2923 return Py_None;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002924error:
Victor Stinner8c62be82010-05-06 00:08:46 +00002925 PyErr_Clear();
2926 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2927 return NULL;
2928 Py_BEGIN_ALLOW_THREADS
2929 result = MoveFileA(p1, p2);
2930 Py_END_ALLOW_THREADS
2931 if (!result)
2932 return win32_error("rename", NULL);
2933 Py_INCREF(Py_None);
2934 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002935#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002936 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002937#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002938}
2939
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002940
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002941PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002942"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002943Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002944
Barry Warsaw53699e91996-12-10 23:23:01 +00002945static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002946posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002947{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002948#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002949 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002950#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002951 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002952#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002953}
2954
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002955
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002956PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002957"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002958Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002959
Barry Warsaw53699e91996-12-10 23:23:01 +00002960static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002961posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002962{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002963#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00002964 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002965#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002966 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002967#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002968}
2969
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002970
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002971#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002972PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002973"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002974Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002975
Barry Warsaw53699e91996-12-10 23:23:01 +00002976static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002977posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002978{
Victor Stinner8c62be82010-05-06 00:08:46 +00002979 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002980#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002981 wchar_t *command;
2982 if (!PyArg_ParseTuple(args, "u:system", &command))
2983 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00002984
Victor Stinner8c62be82010-05-06 00:08:46 +00002985 Py_BEGIN_ALLOW_THREADS
2986 sts = _wsystem(command);
2987 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00002988#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002989 PyObject *command_obj;
2990 char *command;
2991 if (!PyArg_ParseTuple(args, "O&:system",
2992 PyUnicode_FSConverter, &command_obj))
2993 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00002994
Victor Stinner8c62be82010-05-06 00:08:46 +00002995 command = PyBytes_AsString(command_obj);
2996 Py_BEGIN_ALLOW_THREADS
2997 sts = system(command);
2998 Py_END_ALLOW_THREADS
2999 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00003000#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003001 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003002}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003003#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003004
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003005
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003006PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003007"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003008Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003009
Barry Warsaw53699e91996-12-10 23:23:01 +00003010static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003011posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003012{
Victor Stinner8c62be82010-05-06 00:08:46 +00003013 int i;
3014 if (!PyArg_ParseTuple(args, "i:umask", &i))
3015 return NULL;
3016 i = (int)umask(i);
3017 if (i < 0)
3018 return posix_error();
3019 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003020}
3021
Brian Curtind40e6f72010-07-08 21:39:08 +00003022#ifdef MS_WINDOWS
3023
3024/* override the default DeleteFileW behavior so that directory
3025symlinks can be removed with this function, the same as with
3026Unix symlinks */
3027BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
3028{
3029 WIN32_FILE_ATTRIBUTE_DATA info;
3030 WIN32_FIND_DATAW find_data;
3031 HANDLE find_data_handle;
3032 int is_directory = 0;
3033 int is_link = 0;
3034
3035 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3036 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
3037
3038 /* Get WIN32_FIND_DATA structure for the path to determine if
3039 it is a symlink */
3040 if(is_directory &&
3041 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3042 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3043
3044 if(find_data_handle != INVALID_HANDLE_VALUE) {
3045 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3046 FindClose(find_data_handle);
3047 }
3048 }
3049 }
3050
3051 if (is_directory && is_link)
3052 return RemoveDirectoryW(lpFileName);
3053
3054 return DeleteFileW(lpFileName);
3055}
3056#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003057
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003058PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003059"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003060Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003061
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003062PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003063"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003064Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003065
Barry Warsaw53699e91996-12-10 23:23:01 +00003066static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003067posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003068{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003069#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003070 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3071 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003072#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003073 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003074#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003075}
3076
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003077
Guido van Rossumb6775db1994-08-01 11:34:53 +00003078#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003079PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003080"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003081Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003082
Barry Warsaw53699e91996-12-10 23:23:01 +00003083static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003084posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003085{
Victor Stinner8c62be82010-05-06 00:08:46 +00003086 struct utsname u;
3087 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003088
Victor Stinner8c62be82010-05-06 00:08:46 +00003089 Py_BEGIN_ALLOW_THREADS
3090 res = uname(&u);
3091 Py_END_ALLOW_THREADS
3092 if (res < 0)
3093 return posix_error();
3094 return Py_BuildValue("(sssss)",
3095 u.sysname,
3096 u.nodename,
3097 u.release,
3098 u.version,
3099 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003100}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003101#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003102
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003103static int
3104extract_time(PyObject *t, long* sec, long* usec)
3105{
Victor Stinner8c62be82010-05-06 00:08:46 +00003106 long intval;
3107 if (PyFloat_Check(t)) {
3108 double tval = PyFloat_AsDouble(t);
3109 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
3110 if (!intobj)
3111 return -1;
3112 intval = PyLong_AsLong(intobj);
3113 Py_DECREF(intobj);
3114 if (intval == -1 && PyErr_Occurred())
3115 return -1;
3116 *sec = intval;
3117 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
3118 if (*usec < 0)
3119 /* If rounding gave us a negative number,
3120 truncate. */
3121 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00003122 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003123 }
3124 intval = PyLong_AsLong(t);
3125 if (intval == -1 && PyErr_Occurred())
3126 return -1;
3127 *sec = intval;
3128 *usec = 0;
3129 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003130}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003131
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003132PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00003133"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00003134utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00003135Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003136second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003137
Barry Warsaw53699e91996-12-10 23:23:01 +00003138static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003139posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003140{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003141#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003142 PyObject *arg;
3143 PyUnicodeObject *obwpath;
3144 wchar_t *wpath = NULL;
3145 PyObject *oapath;
3146 char *apath;
3147 HANDLE hFile;
3148 long atimesec, mtimesec, ausec, musec;
3149 FILETIME atime, mtime;
3150 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003151
Victor Stinner8c62be82010-05-06 00:08:46 +00003152 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
3153 wpath = PyUnicode_AS_UNICODE(obwpath);
3154 Py_BEGIN_ALLOW_THREADS
3155 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3156 NULL, OPEN_EXISTING,
3157 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3158 Py_END_ALLOW_THREADS
3159 if (hFile == INVALID_HANDLE_VALUE)
3160 return win32_error_unicode("utime", wpath);
3161 } else
3162 /* Drop the argument parsing error as narrow strings
3163 are also valid. */
3164 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003165
Victor Stinner8c62be82010-05-06 00:08:46 +00003166 if (!wpath) {
3167 if (!PyArg_ParseTuple(args, "O&O:utime",
3168 PyUnicode_FSConverter, &oapath, &arg))
3169 return NULL;
3170 apath = PyBytes_AsString(oapath);
3171 Py_BEGIN_ALLOW_THREADS
3172 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3173 NULL, OPEN_EXISTING,
3174 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3175 Py_END_ALLOW_THREADS
3176 if (hFile == INVALID_HANDLE_VALUE) {
3177 win32_error("utime", apath);
3178 Py_DECREF(oapath);
3179 return NULL;
3180 }
3181 Py_DECREF(oapath);
3182 }
3183
3184 if (arg == Py_None) {
3185 SYSTEMTIME now;
3186 GetSystemTime(&now);
3187 if (!SystemTimeToFileTime(&now, &mtime) ||
3188 !SystemTimeToFileTime(&now, &atime)) {
3189 win32_error("utime", NULL);
3190 goto done;
Stefan Krah0e803b32010-11-26 16:16:47 +00003191 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003192 }
3193 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3194 PyErr_SetString(PyExc_TypeError,
3195 "utime() arg 2 must be a tuple (atime, mtime)");
3196 goto done;
3197 }
3198 else {
3199 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3200 &atimesec, &ausec) == -1)
3201 goto done;
3202 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3203 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3204 &mtimesec, &musec) == -1)
3205 goto done;
3206 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3207 }
3208 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3209 /* Avoid putting the file name into the error here,
3210 as that may confuse the user into believing that
3211 something is wrong with the file, when it also
3212 could be the time stamp that gives a problem. */
3213 win32_error("utime", NULL);
3214 }
3215 Py_INCREF(Py_None);
3216 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003217done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003218 CloseHandle(hFile);
3219 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003220#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003221
Victor Stinner8c62be82010-05-06 00:08:46 +00003222 PyObject *opath;
3223 char *path;
3224 long atime, mtime, ausec, musec;
3225 int res;
3226 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003227
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003228#if defined(HAVE_UTIMES)
Victor Stinner8c62be82010-05-06 00:08:46 +00003229 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003230#define ATIME buf[0].tv_sec
3231#define MTIME buf[1].tv_sec
3232#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003233/* XXX should define struct utimbuf instead, above */
Victor Stinner8c62be82010-05-06 00:08:46 +00003234 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003235#define ATIME buf.actime
3236#define MTIME buf.modtime
3237#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003238#else /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003239 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003240#define ATIME buf[0]
3241#define MTIME buf[1]
3242#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003243#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003244
Mark Hammond817c9292003-12-03 01:22:38 +00003245
Victor Stinner8c62be82010-05-06 00:08:46 +00003246 if (!PyArg_ParseTuple(args, "O&O:utime",
3247 PyUnicode_FSConverter, &opath, &arg))
3248 return NULL;
3249 path = PyBytes_AsString(opath);
3250 if (arg == Py_None) {
3251 /* optional time values not given */
3252 Py_BEGIN_ALLOW_THREADS
3253 res = utime(path, NULL);
3254 Py_END_ALLOW_THREADS
3255 }
3256 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3257 PyErr_SetString(PyExc_TypeError,
3258 "utime() arg 2 must be a tuple (atime, mtime)");
3259 Py_DECREF(opath);
3260 return NULL;
3261 }
3262 else {
3263 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3264 &atime, &ausec) == -1) {
3265 Py_DECREF(opath);
3266 return NULL;
3267 }
3268 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3269 &mtime, &musec) == -1) {
3270 Py_DECREF(opath);
3271 return NULL;
3272 }
3273 ATIME = atime;
3274 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003275#ifdef HAVE_UTIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00003276 buf[0].tv_usec = ausec;
3277 buf[1].tv_usec = musec;
3278 Py_BEGIN_ALLOW_THREADS
3279 res = utimes(path, buf);
3280 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003281#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003282 Py_BEGIN_ALLOW_THREADS
3283 res = utime(path, UTIME_ARG);
3284 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003285#endif /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003286 }
3287 if (res < 0) {
3288 return posix_error_with_allocated_filename(opath);
3289 }
3290 Py_DECREF(opath);
3291 Py_INCREF(Py_None);
3292 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003293#undef UTIME_ARG
3294#undef ATIME
3295#undef MTIME
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003296#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003297}
3298
Guido van Rossum85e3b011991-06-03 12:42:10 +00003299
Guido van Rossum3b066191991-06-04 19:40:25 +00003300/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003301
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003302PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003303"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003304Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003305
Barry Warsaw53699e91996-12-10 23:23:01 +00003306static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003307posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003308{
Victor Stinner8c62be82010-05-06 00:08:46 +00003309 int sts;
3310 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3311 return NULL;
3312 _exit(sts);
3313 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003314}
3315
Martin v. Löwis114619e2002-10-07 06:44:21 +00003316#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3317static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003318free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003319{
Victor Stinner8c62be82010-05-06 00:08:46 +00003320 Py_ssize_t i;
3321 for (i = 0; i < count; i++)
3322 PyMem_Free(array[i]);
3323 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003324}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003325
Antoine Pitrou69f71142009-05-24 21:25:49 +00003326static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003327int fsconvert_strdup(PyObject *o, char**out)
3328{
Victor Stinner8c62be82010-05-06 00:08:46 +00003329 PyObject *bytes;
3330 Py_ssize_t size;
3331 if (!PyUnicode_FSConverter(o, &bytes))
3332 return 0;
3333 size = PyBytes_GET_SIZE(bytes);
3334 *out = PyMem_Malloc(size+1);
3335 if (!*out)
3336 return 0;
3337 memcpy(*out, PyBytes_AsString(bytes), size+1);
3338 Py_DECREF(bytes);
3339 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003340}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003341#endif
3342
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003343
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003344#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003345PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003346"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003347Execute an executable path with arguments, replacing current process.\n\
3348\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003349 path: path of executable file\n\
3350 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003351
Barry Warsaw53699e91996-12-10 23:23:01 +00003352static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003353posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003354{
Victor Stinner8c62be82010-05-06 00:08:46 +00003355 PyObject *opath;
3356 char *path;
3357 PyObject *argv;
3358 char **argvlist;
3359 Py_ssize_t i, argc;
3360 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003361
Victor Stinner8c62be82010-05-06 00:08:46 +00003362 /* execv has two arguments: (path, argv), where
3363 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003364
Victor Stinner8c62be82010-05-06 00:08:46 +00003365 if (!PyArg_ParseTuple(args, "O&O:execv",
3366 PyUnicode_FSConverter,
3367 &opath, &argv))
3368 return NULL;
3369 path = PyBytes_AsString(opath);
3370 if (PyList_Check(argv)) {
3371 argc = PyList_Size(argv);
3372 getitem = PyList_GetItem;
3373 }
3374 else if (PyTuple_Check(argv)) {
3375 argc = PyTuple_Size(argv);
3376 getitem = PyTuple_GetItem;
3377 }
3378 else {
3379 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3380 Py_DECREF(opath);
3381 return NULL;
3382 }
3383 if (argc < 1) {
3384 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3385 Py_DECREF(opath);
3386 return NULL;
3387 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003388
Victor Stinner8c62be82010-05-06 00:08:46 +00003389 argvlist = PyMem_NEW(char *, argc+1);
3390 if (argvlist == NULL) {
3391 Py_DECREF(opath);
3392 return PyErr_NoMemory();
3393 }
3394 for (i = 0; i < argc; i++) {
3395 if (!fsconvert_strdup((*getitem)(argv, i),
3396 &argvlist[i])) {
3397 free_string_array(argvlist, i);
3398 PyErr_SetString(PyExc_TypeError,
3399 "execv() arg 2 must contain only strings");
3400 Py_DECREF(opath);
3401 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003402
Victor Stinner8c62be82010-05-06 00:08:46 +00003403 }
3404 }
3405 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003406
Victor Stinner8c62be82010-05-06 00:08:46 +00003407 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003408
Victor Stinner8c62be82010-05-06 00:08:46 +00003409 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003410
Victor Stinner8c62be82010-05-06 00:08:46 +00003411 free_string_array(argvlist, argc);
3412 Py_DECREF(opath);
3413 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003414}
3415
Victor Stinner13bb71c2010-04-23 21:41:56 +00003416static char**
3417parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3418{
Victor Stinner8c62be82010-05-06 00:08:46 +00003419 char **envlist;
3420 Py_ssize_t i, pos, envc;
3421 PyObject *keys=NULL, *vals=NULL;
3422 PyObject *key, *val, *key2, *val2;
3423 char *p, *k, *v;
3424 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003425
Victor Stinner8c62be82010-05-06 00:08:46 +00003426 i = PyMapping_Size(env);
3427 if (i < 0)
3428 return NULL;
3429 envlist = PyMem_NEW(char *, i + 1);
3430 if (envlist == NULL) {
3431 PyErr_NoMemory();
3432 return NULL;
3433 }
3434 envc = 0;
3435 keys = PyMapping_Keys(env);
3436 vals = PyMapping_Values(env);
3437 if (!keys || !vals)
3438 goto error;
3439 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3440 PyErr_Format(PyExc_TypeError,
3441 "env.keys() or env.values() is not a list");
3442 goto error;
3443 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003444
Victor Stinner8c62be82010-05-06 00:08:46 +00003445 for (pos = 0; pos < i; pos++) {
3446 key = PyList_GetItem(keys, pos);
3447 val = PyList_GetItem(vals, pos);
3448 if (!key || !val)
3449 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003450
Victor Stinner8c62be82010-05-06 00:08:46 +00003451 if (PyUnicode_FSConverter(key, &key2) == 0)
3452 goto error;
3453 if (PyUnicode_FSConverter(val, &val2) == 0) {
3454 Py_DECREF(key2);
3455 goto error;
3456 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003457
3458#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003459 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3460 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00003461#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003462 k = PyBytes_AsString(key2);
3463 v = PyBytes_AsString(val2);
3464 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003465
Victor Stinner8c62be82010-05-06 00:08:46 +00003466 p = PyMem_NEW(char, len);
3467 if (p == NULL) {
3468 PyErr_NoMemory();
3469 Py_DECREF(key2);
3470 Py_DECREF(val2);
3471 goto error;
3472 }
3473 PyOS_snprintf(p, len, "%s=%s", k, v);
3474 envlist[envc++] = p;
3475 Py_DECREF(key2);
3476 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003477#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003478 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003479#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003480 }
3481 Py_DECREF(vals);
3482 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003483
Victor Stinner8c62be82010-05-06 00:08:46 +00003484 envlist[envc] = 0;
3485 *envc_ptr = envc;
3486 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003487
3488error:
Victor Stinner8c62be82010-05-06 00:08:46 +00003489 Py_XDECREF(keys);
3490 Py_XDECREF(vals);
3491 while (--envc >= 0)
3492 PyMem_DEL(envlist[envc]);
3493 PyMem_DEL(envlist);
3494 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003495}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003496
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003497PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003498"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003499Execute a path with arguments and environment, replacing current process.\n\
3500\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003501 path: path of executable file\n\
3502 args: tuple or list of arguments\n\
3503 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003504
Barry Warsaw53699e91996-12-10 23:23:01 +00003505static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003506posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003507{
Victor Stinner8c62be82010-05-06 00:08:46 +00003508 PyObject *opath;
3509 char *path;
3510 PyObject *argv, *env;
3511 char **argvlist;
3512 char **envlist;
3513 Py_ssize_t i, argc, envc;
3514 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3515 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003516
Victor Stinner8c62be82010-05-06 00:08:46 +00003517 /* execve has three arguments: (path, argv, env), where
3518 argv is a list or tuple of strings and env is a dictionary
3519 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003520
Victor Stinner8c62be82010-05-06 00:08:46 +00003521 if (!PyArg_ParseTuple(args, "O&OO:execve",
3522 PyUnicode_FSConverter,
3523 &opath, &argv, &env))
3524 return NULL;
3525 path = PyBytes_AsString(opath);
3526 if (PyList_Check(argv)) {
3527 argc = PyList_Size(argv);
3528 getitem = PyList_GetItem;
3529 }
3530 else if (PyTuple_Check(argv)) {
3531 argc = PyTuple_Size(argv);
3532 getitem = PyTuple_GetItem;
3533 }
3534 else {
3535 PyErr_SetString(PyExc_TypeError,
3536 "execve() arg 2 must be a tuple or list");
3537 goto fail_0;
3538 }
3539 if (!PyMapping_Check(env)) {
3540 PyErr_SetString(PyExc_TypeError,
3541 "execve() arg 3 must be a mapping object");
3542 goto fail_0;
3543 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003544
Victor Stinner8c62be82010-05-06 00:08:46 +00003545 argvlist = PyMem_NEW(char *, argc+1);
3546 if (argvlist == NULL) {
3547 PyErr_NoMemory();
3548 goto fail_0;
3549 }
3550 for (i = 0; i < argc; i++) {
3551 if (!fsconvert_strdup((*getitem)(argv, i),
3552 &argvlist[i]))
3553 {
3554 lastarg = i;
3555 goto fail_1;
3556 }
3557 }
3558 lastarg = argc;
3559 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003560
Victor Stinner8c62be82010-05-06 00:08:46 +00003561 envlist = parse_envlist(env, &envc);
3562 if (envlist == NULL)
3563 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003564
Victor Stinner8c62be82010-05-06 00:08:46 +00003565 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003566
Victor Stinner8c62be82010-05-06 00:08:46 +00003567 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003568
Victor Stinner8c62be82010-05-06 00:08:46 +00003569 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003570
Victor Stinner8c62be82010-05-06 00:08:46 +00003571 while (--envc >= 0)
3572 PyMem_DEL(envlist[envc]);
3573 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003574 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003575 free_string_array(argvlist, lastarg);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003576 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003577 Py_DECREF(opath);
3578 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003579}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003580#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003581
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003582
Guido van Rossuma1065681999-01-25 23:20:23 +00003583#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003584PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003585"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003586Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003587\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003588 mode: mode of process creation\n\
3589 path: path of executable file\n\
3590 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003591
3592static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003593posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003594{
Victor Stinner8c62be82010-05-06 00:08:46 +00003595 PyObject *opath;
3596 char *path;
3597 PyObject *argv;
3598 char **argvlist;
3599 int mode, i;
3600 Py_ssize_t argc;
3601 Py_intptr_t spawnval;
3602 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003603
Victor Stinner8c62be82010-05-06 00:08:46 +00003604 /* spawnv has three arguments: (mode, path, argv), where
3605 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003606
Victor Stinner8c62be82010-05-06 00:08:46 +00003607 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3608 PyUnicode_FSConverter,
3609 &opath, &argv))
3610 return NULL;
3611 path = PyBytes_AsString(opath);
3612 if (PyList_Check(argv)) {
3613 argc = PyList_Size(argv);
3614 getitem = PyList_GetItem;
3615 }
3616 else if (PyTuple_Check(argv)) {
3617 argc = PyTuple_Size(argv);
3618 getitem = PyTuple_GetItem;
3619 }
3620 else {
3621 PyErr_SetString(PyExc_TypeError,
3622 "spawnv() arg 2 must be a tuple or list");
3623 Py_DECREF(opath);
3624 return NULL;
3625 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003626
Victor Stinner8c62be82010-05-06 00:08:46 +00003627 argvlist = PyMem_NEW(char *, argc+1);
3628 if (argvlist == NULL) {
3629 Py_DECREF(opath);
3630 return PyErr_NoMemory();
3631 }
3632 for (i = 0; i < argc; i++) {
3633 if (!fsconvert_strdup((*getitem)(argv, i),
3634 &argvlist[i])) {
3635 free_string_array(argvlist, i);
3636 PyErr_SetString(
3637 PyExc_TypeError,
3638 "spawnv() arg 2 must contain only strings");
3639 Py_DECREF(opath);
3640 return NULL;
3641 }
3642 }
3643 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003644
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003645#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003646 Py_BEGIN_ALLOW_THREADS
3647 spawnval = spawnv(mode, path, argvlist);
3648 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003649#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003650 if (mode == _OLD_P_OVERLAY)
3651 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003652
Victor Stinner8c62be82010-05-06 00:08:46 +00003653 Py_BEGIN_ALLOW_THREADS
3654 spawnval = _spawnv(mode, path, argvlist);
3655 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003656#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003657
Victor Stinner8c62be82010-05-06 00:08:46 +00003658 free_string_array(argvlist, argc);
3659 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003660
Victor Stinner8c62be82010-05-06 00:08:46 +00003661 if (spawnval == -1)
3662 return posix_error();
3663 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003664#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003665 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003666#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003667 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003668#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003669}
3670
3671
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003672PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003673"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003674Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003675\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003676 mode: mode of process creation\n\
3677 path: path of executable file\n\
3678 args: tuple or list of arguments\n\
3679 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003680
3681static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003682posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003683{
Victor Stinner8c62be82010-05-06 00:08:46 +00003684 PyObject *opath;
3685 char *path;
3686 PyObject *argv, *env;
3687 char **argvlist;
3688 char **envlist;
3689 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003690 int mode;
3691 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003692 Py_intptr_t spawnval;
3693 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3694 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003695
Victor Stinner8c62be82010-05-06 00:08:46 +00003696 /* spawnve has four arguments: (mode, path, argv, env), where
3697 argv is a list or tuple of strings and env is a dictionary
3698 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003699
Victor Stinner8c62be82010-05-06 00:08:46 +00003700 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3701 PyUnicode_FSConverter,
3702 &opath, &argv, &env))
3703 return NULL;
3704 path = PyBytes_AsString(opath);
3705 if (PyList_Check(argv)) {
3706 argc = PyList_Size(argv);
3707 getitem = PyList_GetItem;
3708 }
3709 else if (PyTuple_Check(argv)) {
3710 argc = PyTuple_Size(argv);
3711 getitem = PyTuple_GetItem;
3712 }
3713 else {
3714 PyErr_SetString(PyExc_TypeError,
3715 "spawnve() arg 2 must be a tuple or list");
3716 goto fail_0;
3717 }
3718 if (!PyMapping_Check(env)) {
3719 PyErr_SetString(PyExc_TypeError,
3720 "spawnve() arg 3 must be a mapping object");
3721 goto fail_0;
3722 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003723
Victor Stinner8c62be82010-05-06 00:08:46 +00003724 argvlist = PyMem_NEW(char *, argc+1);
3725 if (argvlist == NULL) {
3726 PyErr_NoMemory();
3727 goto fail_0;
3728 }
3729 for (i = 0; i < argc; i++) {
3730 if (!fsconvert_strdup((*getitem)(argv, i),
3731 &argvlist[i]))
3732 {
3733 lastarg = i;
3734 goto fail_1;
3735 }
3736 }
3737 lastarg = argc;
3738 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003739
Victor Stinner8c62be82010-05-06 00:08:46 +00003740 envlist = parse_envlist(env, &envc);
3741 if (envlist == NULL)
3742 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003743
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003744#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003745 Py_BEGIN_ALLOW_THREADS
3746 spawnval = spawnve(mode, path, argvlist, envlist);
3747 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003748#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003749 if (mode == _OLD_P_OVERLAY)
3750 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003751
Victor Stinner8c62be82010-05-06 00:08:46 +00003752 Py_BEGIN_ALLOW_THREADS
3753 spawnval = _spawnve(mode, path, argvlist, envlist);
3754 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003755#endif
Tim Peters25059d32001-12-07 20:35:43 +00003756
Victor Stinner8c62be82010-05-06 00:08:46 +00003757 if (spawnval == -1)
3758 (void) posix_error();
3759 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003760#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003761 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003762#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003763 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003764#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003765
Victor Stinner8c62be82010-05-06 00:08:46 +00003766 while (--envc >= 0)
3767 PyMem_DEL(envlist[envc]);
3768 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003769 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003770 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003771 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003772 Py_DECREF(opath);
3773 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003774}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003775
3776/* OS/2 supports spawnvp & spawnvpe natively */
3777#if defined(PYOS_OS2)
3778PyDoc_STRVAR(posix_spawnvp__doc__,
3779"spawnvp(mode, file, args)\n\n\
3780Execute the program 'file' in a new process, using the environment\n\
3781search path to find the file.\n\
3782\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003783 mode: mode of process creation\n\
3784 file: executable file name\n\
3785 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003786
3787static PyObject *
3788posix_spawnvp(PyObject *self, PyObject *args)
3789{
Victor Stinner8c62be82010-05-06 00:08:46 +00003790 PyObject *opath;
3791 char *path;
3792 PyObject *argv;
3793 char **argvlist;
3794 int mode, i, argc;
3795 Py_intptr_t spawnval;
3796 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003797
Victor Stinner8c62be82010-05-06 00:08:46 +00003798 /* spawnvp has three arguments: (mode, path, argv), where
3799 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003800
Victor Stinner8c62be82010-05-06 00:08:46 +00003801 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3802 PyUnicode_FSConverter,
3803 &opath, &argv))
3804 return NULL;
3805 path = PyBytes_AsString(opath);
3806 if (PyList_Check(argv)) {
3807 argc = PyList_Size(argv);
3808 getitem = PyList_GetItem;
3809 }
3810 else if (PyTuple_Check(argv)) {
3811 argc = PyTuple_Size(argv);
3812 getitem = PyTuple_GetItem;
3813 }
3814 else {
3815 PyErr_SetString(PyExc_TypeError,
3816 "spawnvp() arg 2 must be a tuple or list");
3817 Py_DECREF(opath);
3818 return NULL;
3819 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003820
Victor Stinner8c62be82010-05-06 00:08:46 +00003821 argvlist = PyMem_NEW(char *, argc+1);
3822 if (argvlist == NULL) {
3823 Py_DECREF(opath);
3824 return PyErr_NoMemory();
3825 }
3826 for (i = 0; i < argc; i++) {
3827 if (!fsconvert_strdup((*getitem)(argv, i),
3828 &argvlist[i])) {
3829 free_string_array(argvlist, i);
3830 PyErr_SetString(
3831 PyExc_TypeError,
3832 "spawnvp() arg 2 must contain only strings");
3833 Py_DECREF(opath);
3834 return NULL;
3835 }
3836 }
3837 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003838
Victor Stinner8c62be82010-05-06 00:08:46 +00003839 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003840#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003841 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003842#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003843 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003844#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003845 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003846
Victor Stinner8c62be82010-05-06 00:08:46 +00003847 free_string_array(argvlist, argc);
3848 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003849
Victor Stinner8c62be82010-05-06 00:08:46 +00003850 if (spawnval == -1)
3851 return posix_error();
3852 else
3853 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003854}
3855
3856
3857PyDoc_STRVAR(posix_spawnvpe__doc__,
3858"spawnvpe(mode, file, args, env)\n\n\
3859Execute the program 'file' in a new process, using the environment\n\
3860search path to find the file.\n\
3861\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003862 mode: mode of process creation\n\
3863 file: executable file name\n\
3864 args: tuple or list of arguments\n\
3865 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003866
3867static PyObject *
3868posix_spawnvpe(PyObject *self, PyObject *args)
3869{
Victor Stinner8c62be82010-05-06 00:08:46 +00003870 PyObject *opath
3871 char *path;
3872 PyObject *argv, *env;
3873 char **argvlist;
3874 char **envlist;
3875 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003876 int mode;
3877 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003878 Py_intptr_t spawnval;
3879 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3880 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003881
Victor Stinner8c62be82010-05-06 00:08:46 +00003882 /* spawnvpe has four arguments: (mode, path, argv, env), where
3883 argv is a list or tuple of strings and env is a dictionary
3884 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003885
Victor Stinner8c62be82010-05-06 00:08:46 +00003886 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3887 PyUnicode_FSConverter,
3888 &opath, &argv, &env))
3889 return NULL;
3890 path = PyBytes_AsString(opath);
3891 if (PyList_Check(argv)) {
3892 argc = PyList_Size(argv);
3893 getitem = PyList_GetItem;
3894 }
3895 else if (PyTuple_Check(argv)) {
3896 argc = PyTuple_Size(argv);
3897 getitem = PyTuple_GetItem;
3898 }
3899 else {
3900 PyErr_SetString(PyExc_TypeError,
3901 "spawnvpe() arg 2 must be a tuple or list");
3902 goto fail_0;
3903 }
3904 if (!PyMapping_Check(env)) {
3905 PyErr_SetString(PyExc_TypeError,
3906 "spawnvpe() arg 3 must be a mapping object");
3907 goto fail_0;
3908 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003909
Victor Stinner8c62be82010-05-06 00:08:46 +00003910 argvlist = PyMem_NEW(char *, argc+1);
3911 if (argvlist == NULL) {
3912 PyErr_NoMemory();
3913 goto fail_0;
3914 }
3915 for (i = 0; i < argc; i++) {
3916 if (!fsconvert_strdup((*getitem)(argv, i),
3917 &argvlist[i]))
3918 {
3919 lastarg = i;
3920 goto fail_1;
3921 }
3922 }
3923 lastarg = argc;
3924 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003925
Victor Stinner8c62be82010-05-06 00:08:46 +00003926 envlist = parse_envlist(env, &envc);
3927 if (envlist == NULL)
3928 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003929
Victor Stinner8c62be82010-05-06 00:08:46 +00003930 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003931#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003932 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003933#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003934 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003935#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003936 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003937
Victor Stinner8c62be82010-05-06 00:08:46 +00003938 if (spawnval == -1)
3939 (void) posix_error();
3940 else
3941 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003942
Victor Stinner8c62be82010-05-06 00:08:46 +00003943 while (--envc >= 0)
3944 PyMem_DEL(envlist[envc]);
3945 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003946 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003947 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003948 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003949 Py_DECREF(opath);
3950 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003951}
3952#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003953#endif /* HAVE_SPAWNV */
3954
3955
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003956#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003957PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003958"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003959Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3960\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003961Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003962
3963static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003964posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003965{
Victor Stinner8c62be82010-05-06 00:08:46 +00003966 pid_t pid;
3967 int result = 0;
3968 _PyImport_AcquireLock();
3969 pid = fork1();
3970 if (pid == 0) {
3971 /* child: this clobbers and resets the import lock. */
3972 PyOS_AfterFork();
3973 } else {
3974 /* parent: release the import lock. */
3975 result = _PyImport_ReleaseLock();
3976 }
3977 if (pid == -1)
3978 return posix_error();
3979 if (result < 0) {
3980 /* Don't clobber the OSError if the fork failed. */
3981 PyErr_SetString(PyExc_RuntimeError,
3982 "not holding the import lock");
3983 return NULL;
3984 }
3985 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003986}
3987#endif
3988
3989
Guido van Rossumad0ee831995-03-01 10:34:45 +00003990#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003991PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003992"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003993Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003994Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003995
Barry Warsaw53699e91996-12-10 23:23:01 +00003996static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003997posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003998{
Victor Stinner8c62be82010-05-06 00:08:46 +00003999 pid_t pid;
4000 int result = 0;
4001 _PyImport_AcquireLock();
4002 pid = fork();
4003 if (pid == 0) {
4004 /* child: this clobbers and resets the import lock. */
4005 PyOS_AfterFork();
4006 } else {
4007 /* parent: release the import lock. */
4008 result = _PyImport_ReleaseLock();
4009 }
4010 if (pid == -1)
4011 return posix_error();
4012 if (result < 0) {
4013 /* Don't clobber the OSError if the fork failed. */
4014 PyErr_SetString(PyExc_RuntimeError,
4015 "not holding the import lock");
4016 return NULL;
4017 }
4018 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00004019}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004020#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004021
Neal Norwitzb59798b2003-03-21 01:43:31 +00004022/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00004023/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
4024#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00004025#define DEV_PTY_FILE "/dev/ptc"
4026#define HAVE_DEV_PTMX
4027#else
4028#define DEV_PTY_FILE "/dev/ptmx"
4029#endif
4030
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004031#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004032#ifdef HAVE_PTY_H
4033#include <pty.h>
4034#else
4035#ifdef HAVE_LIBUTIL_H
4036#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00004037#else
4038#ifdef HAVE_UTIL_H
4039#include <util.h>
4040#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004041#endif /* HAVE_LIBUTIL_H */
4042#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00004043#ifdef HAVE_STROPTS_H
4044#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004045#endif
4046#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004047
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004048#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004049PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004050"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004051Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004052
4053static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004054posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004055{
Victor Stinner8c62be82010-05-06 00:08:46 +00004056 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004057#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004058 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004059#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004060#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004061 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004062#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00004063 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004064#endif
4065#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00004066
Thomas Wouters70c21a12000-07-14 14:28:33 +00004067#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004068 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
4069 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004070#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004071 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
4072 if (slave_name == NULL)
4073 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00004074
Victor Stinner8c62be82010-05-06 00:08:46 +00004075 slave_fd = open(slave_name, O_RDWR);
4076 if (slave_fd < 0)
4077 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004078#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004079 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
4080 if (master_fd < 0)
4081 return posix_error();
4082 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
4083 /* change permission of slave */
4084 if (grantpt(master_fd) < 0) {
4085 PyOS_setsig(SIGCHLD, sig_saved);
4086 return posix_error();
4087 }
4088 /* unlock slave */
4089 if (unlockpt(master_fd) < 0) {
4090 PyOS_setsig(SIGCHLD, sig_saved);
4091 return posix_error();
4092 }
4093 PyOS_setsig(SIGCHLD, sig_saved);
4094 slave_name = ptsname(master_fd); /* get name of slave */
4095 if (slave_name == NULL)
4096 return posix_error();
4097 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
4098 if (slave_fd < 0)
4099 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004100#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004101 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
4102 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00004103#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00004104 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00004105#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004106#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00004107#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00004108
Victor Stinner8c62be82010-05-06 00:08:46 +00004109 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00004110
Fred Drake8cef4cf2000-06-28 16:40:38 +00004111}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004112#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004113
4114#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004115PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004116"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00004117Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
4118Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004119To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004120
4121static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004122posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004123{
Victor Stinner8c62be82010-05-06 00:08:46 +00004124 int master_fd = -1, result = 0;
4125 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00004126
Victor Stinner8c62be82010-05-06 00:08:46 +00004127 _PyImport_AcquireLock();
4128 pid = forkpty(&master_fd, NULL, NULL, NULL);
4129 if (pid == 0) {
4130 /* child: this clobbers and resets the import lock. */
4131 PyOS_AfterFork();
4132 } else {
4133 /* parent: release the import lock. */
4134 result = _PyImport_ReleaseLock();
4135 }
4136 if (pid == -1)
4137 return posix_error();
4138 if (result < 0) {
4139 /* Don't clobber the OSError if the fork failed. */
4140 PyErr_SetString(PyExc_RuntimeError,
4141 "not holding the import lock");
4142 return NULL;
4143 }
4144 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004145}
4146#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004147
Guido van Rossumad0ee831995-03-01 10:34:45 +00004148#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004149PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004150"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004151Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004152
Barry Warsaw53699e91996-12-10 23:23:01 +00004153static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004154posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004155{
Victor Stinner8c62be82010-05-06 00:08:46 +00004156 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004157}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004158#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004159
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004160
Guido van Rossumad0ee831995-03-01 10:34:45 +00004161#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004162PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004163"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004164Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004165
Barry Warsaw53699e91996-12-10 23:23:01 +00004166static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004167posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004168{
Victor Stinner8c62be82010-05-06 00:08:46 +00004169 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004170}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004171#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004172
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004173
Guido van Rossumad0ee831995-03-01 10:34:45 +00004174#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004175PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004176"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004177Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004178
Barry Warsaw53699e91996-12-10 23:23:01 +00004179static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004180posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004181{
Victor Stinner8c62be82010-05-06 00:08:46 +00004182 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004183}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004184#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004185
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004186
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004187PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004188"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004189Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004190
Barry Warsaw53699e91996-12-10 23:23:01 +00004191static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004192posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004193{
Victor Stinner8c62be82010-05-06 00:08:46 +00004194 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004195}
4196
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004197
Fred Drakec9680921999-12-13 16:37:25 +00004198#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004199PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004200"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004201Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004202
4203static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004204posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004205{
4206 PyObject *result = NULL;
4207
Fred Drakec9680921999-12-13 16:37:25 +00004208#ifdef NGROUPS_MAX
4209#define MAX_GROUPS NGROUPS_MAX
4210#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004211 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004212#define MAX_GROUPS 64
4213#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004214 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004215
4216 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
4217 * This is a helper variable to store the intermediate result when
4218 * that happens.
4219 *
4220 * To keep the code readable the OSX behaviour is unconditional,
4221 * according to the POSIX spec this should be safe on all unix-y
4222 * systems.
4223 */
4224 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00004225 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004226
Victor Stinner8c62be82010-05-06 00:08:46 +00004227 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004228 if (n < 0) {
4229 if (errno == EINVAL) {
4230 n = getgroups(0, NULL);
4231 if (n == -1) {
4232 return posix_error();
4233 }
4234 if (n == 0) {
4235 /* Avoid malloc(0) */
4236 alt_grouplist = grouplist;
4237 } else {
4238 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4239 if (alt_grouplist == NULL) {
4240 errno = EINVAL;
4241 return posix_error();
4242 }
4243 n = getgroups(n, alt_grouplist);
4244 if (n == -1) {
4245 PyMem_Free(alt_grouplist);
4246 return posix_error();
4247 }
4248 }
4249 } else {
4250 return posix_error();
4251 }
4252 }
4253 result = PyList_New(n);
4254 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004255 int i;
4256 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004257 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00004258 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00004259 Py_DECREF(result);
4260 result = NULL;
4261 break;
Fred Drakec9680921999-12-13 16:37:25 +00004262 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004263 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004264 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004265 }
4266
4267 if (alt_grouplist != grouplist) {
4268 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00004269 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004270
Fred Drakec9680921999-12-13 16:37:25 +00004271 return result;
4272}
4273#endif
4274
Antoine Pitroub7572f02009-12-02 20:46:48 +00004275#ifdef HAVE_INITGROUPS
4276PyDoc_STRVAR(posix_initgroups__doc__,
4277"initgroups(username, gid) -> None\n\n\
4278Call the system initgroups() to initialize the group access list with all of\n\
4279the groups of which the specified username is a member, plus the specified\n\
4280group id.");
4281
4282static PyObject *
4283posix_initgroups(PyObject *self, PyObject *args)
4284{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004285 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00004286 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004287 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00004288 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004289
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004290 if (!PyArg_ParseTuple(args, "O&l:initgroups",
4291 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00004292 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004293 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004294
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004295 res = initgroups(username, (gid_t) gid);
4296 Py_DECREF(oname);
4297 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00004298 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004299
Victor Stinner8c62be82010-05-06 00:08:46 +00004300 Py_INCREF(Py_None);
4301 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004302}
4303#endif
4304
Martin v. Löwis606edc12002-06-13 21:09:11 +00004305#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004306PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004307"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004308Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004309
4310static PyObject *
4311posix_getpgid(PyObject *self, PyObject *args)
4312{
Victor Stinner8c62be82010-05-06 00:08:46 +00004313 pid_t pid, pgid;
4314 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
4315 return NULL;
4316 pgid = getpgid(pid);
4317 if (pgid < 0)
4318 return posix_error();
4319 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004320}
4321#endif /* HAVE_GETPGID */
4322
4323
Guido van Rossumb6775db1994-08-01 11:34:53 +00004324#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004325PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004326"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004327Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004328
Barry Warsaw53699e91996-12-10 23:23:01 +00004329static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004330posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004331{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004332#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004333 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004334#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004335 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004336#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004337}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004338#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004339
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004340
Guido van Rossumb6775db1994-08-01 11:34:53 +00004341#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004342PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004343"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00004344Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004345
Barry Warsaw53699e91996-12-10 23:23:01 +00004346static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004347posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004348{
Guido van Rossum64933891994-10-20 21:56:42 +00004349#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004350 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004351#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004352 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004353#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004354 return posix_error();
4355 Py_INCREF(Py_None);
4356 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004357}
4358
Guido van Rossumb6775db1994-08-01 11:34:53 +00004359#endif /* HAVE_SETPGRP */
4360
Guido van Rossumad0ee831995-03-01 10:34:45 +00004361#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004362
4363#ifdef MS_WINDOWS
4364#include <tlhelp32.h>
4365
4366static PyObject*
4367win32_getppid()
4368{
4369 HANDLE snapshot;
4370 pid_t mypid;
4371 PyObject* result = NULL;
4372 BOOL have_record;
4373 PROCESSENTRY32 pe;
4374
4375 mypid = getpid(); /* This function never fails */
4376
4377 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
4378 if (snapshot == INVALID_HANDLE_VALUE)
4379 return PyErr_SetFromWindowsErr(GetLastError());
4380
4381 pe.dwSize = sizeof(pe);
4382 have_record = Process32First(snapshot, &pe);
4383 while (have_record) {
4384 if (mypid == (pid_t)pe.th32ProcessID) {
4385 /* We could cache the ulong value in a static variable. */
4386 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
4387 break;
4388 }
4389
4390 have_record = Process32Next(snapshot, &pe);
4391 }
4392
4393 /* If our loop exits and our pid was not found (result will be NULL)
4394 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
4395 * error anyway, so let's raise it. */
4396 if (!result)
4397 result = PyErr_SetFromWindowsErr(GetLastError());
4398
4399 CloseHandle(snapshot);
4400
4401 return result;
4402}
4403#endif /*MS_WINDOWS*/
4404
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004405PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004406"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004407Return the parent's process id. If the parent process has already exited,\n\
4408Windows machines will still return its id; others systems will return the id\n\
4409of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004410
Barry Warsaw53699e91996-12-10 23:23:01 +00004411static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004412posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004413{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004414#ifdef MS_WINDOWS
4415 return win32_getppid();
4416#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004417 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00004418#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004419}
4420#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004421
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004422
Fred Drake12c6e2d1999-12-14 21:25:03 +00004423#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004424PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004425"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004426Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004427
4428static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004429posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004430{
Victor Stinner8c62be82010-05-06 00:08:46 +00004431 PyObject *result = NULL;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004432#ifdef MS_WINDOWS
4433 wchar_t user_name[UNLEN + 1];
4434 DWORD num_chars = sizeof(user_name)/sizeof(user_name[0]);
4435
4436 if (GetUserNameW(user_name, &num_chars)) {
4437 /* num_chars is the number of unicode chars plus null terminator */
4438 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
4439 }
4440 else
4441 result = PyErr_SetFromWindowsErr(GetLastError());
4442#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004443 char *name;
4444 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004445
Victor Stinner8c62be82010-05-06 00:08:46 +00004446 errno = 0;
4447 name = getlogin();
4448 if (name == NULL) {
4449 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00004450 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004451 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004452 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00004453 }
4454 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004455 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00004456 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004457#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00004458 return result;
4459}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004460#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00004461
Guido van Rossumad0ee831995-03-01 10:34:45 +00004462#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004463PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004464"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004465Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004466
Barry Warsaw53699e91996-12-10 23:23:01 +00004467static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004468posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004469{
Victor Stinner8c62be82010-05-06 00:08:46 +00004470 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004471}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004472#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004473
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004474
Guido van Rossumad0ee831995-03-01 10:34:45 +00004475#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004476PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004477"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004478Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004479
Barry Warsaw53699e91996-12-10 23:23:01 +00004480static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004481posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004482{
Victor Stinner8c62be82010-05-06 00:08:46 +00004483 pid_t pid;
4484 int sig;
4485 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
4486 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004487#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004488 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4489 APIRET rc;
4490 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004491 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004492
4493 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4494 APIRET rc;
4495 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004496 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004497
4498 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004499 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004500#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004501 if (kill(pid, sig) == -1)
4502 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004503#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004504 Py_INCREF(Py_None);
4505 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004506}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004507#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004508
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004509#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004510PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004511"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004512Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004513
4514static PyObject *
4515posix_killpg(PyObject *self, PyObject *args)
4516{
Victor Stinner8c62be82010-05-06 00:08:46 +00004517 int sig;
4518 pid_t pgid;
4519 /* XXX some man pages make the `pgid` parameter an int, others
4520 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4521 take the same type. Moreover, pid_t is always at least as wide as
4522 int (else compilation of this module fails), which is safe. */
4523 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
4524 return NULL;
4525 if (killpg(pgid, sig) == -1)
4526 return posix_error();
4527 Py_INCREF(Py_None);
4528 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004529}
4530#endif
4531
Brian Curtineb24d742010-04-12 17:16:38 +00004532#ifdef MS_WINDOWS
4533PyDoc_STRVAR(win32_kill__doc__,
4534"kill(pid, sig)\n\n\
4535Kill a process with a signal.");
4536
4537static PyObject *
4538win32_kill(PyObject *self, PyObject *args)
4539{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00004540 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004541 DWORD pid, sig, err;
4542 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00004543
Victor Stinner8c62be82010-05-06 00:08:46 +00004544 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4545 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00004546
Victor Stinner8c62be82010-05-06 00:08:46 +00004547 /* Console processes which share a common console can be sent CTRL+C or
4548 CTRL+BREAK events, provided they handle said events. */
4549 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4550 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4551 err = GetLastError();
4552 PyErr_SetFromWindowsErr(err);
4553 }
4554 else
4555 Py_RETURN_NONE;
4556 }
Brian Curtineb24d742010-04-12 17:16:38 +00004557
Victor Stinner8c62be82010-05-06 00:08:46 +00004558 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4559 attempt to open and terminate the process. */
4560 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4561 if (handle == NULL) {
4562 err = GetLastError();
4563 return PyErr_SetFromWindowsErr(err);
4564 }
Brian Curtineb24d742010-04-12 17:16:38 +00004565
Victor Stinner8c62be82010-05-06 00:08:46 +00004566 if (TerminateProcess(handle, sig) == 0) {
4567 err = GetLastError();
4568 result = PyErr_SetFromWindowsErr(err);
4569 } else {
4570 Py_INCREF(Py_None);
4571 result = Py_None;
4572 }
Brian Curtineb24d742010-04-12 17:16:38 +00004573
Victor Stinner8c62be82010-05-06 00:08:46 +00004574 CloseHandle(handle);
4575 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00004576}
4577#endif /* MS_WINDOWS */
4578
Guido van Rossumc0125471996-06-28 18:55:32 +00004579#ifdef HAVE_PLOCK
4580
4581#ifdef HAVE_SYS_LOCK_H
4582#include <sys/lock.h>
4583#endif
4584
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004585PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004586"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004587Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004588
Barry Warsaw53699e91996-12-10 23:23:01 +00004589static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004590posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004591{
Victor Stinner8c62be82010-05-06 00:08:46 +00004592 int op;
4593 if (!PyArg_ParseTuple(args, "i:plock", &op))
4594 return NULL;
4595 if (plock(op) == -1)
4596 return posix_error();
4597 Py_INCREF(Py_None);
4598 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004599}
4600#endif
4601
Guido van Rossumb6775db1994-08-01 11:34:53 +00004602#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004603PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004604"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004605Set the current process's user id.");
4606
Barry Warsaw53699e91996-12-10 23:23:01 +00004607static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004608posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004609{
Victor Stinner8c62be82010-05-06 00:08:46 +00004610 long uid_arg;
4611 uid_t uid;
4612 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
4613 return NULL;
4614 uid = uid_arg;
4615 if (uid != uid_arg) {
4616 PyErr_SetString(PyExc_OverflowError, "user id too big");
4617 return NULL;
4618 }
4619 if (setuid(uid) < 0)
4620 return posix_error();
4621 Py_INCREF(Py_None);
4622 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004623}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004624#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004625
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004626
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004627#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004628PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004629"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004630Set the current process's effective user id.");
4631
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004632static PyObject *
4633posix_seteuid (PyObject *self, PyObject *args)
4634{
Victor Stinner8c62be82010-05-06 00:08:46 +00004635 long euid_arg;
4636 uid_t euid;
4637 if (!PyArg_ParseTuple(args, "l", &euid_arg))
4638 return NULL;
4639 euid = euid_arg;
4640 if (euid != euid_arg) {
4641 PyErr_SetString(PyExc_OverflowError, "user id too big");
4642 return NULL;
4643 }
4644 if (seteuid(euid) < 0) {
4645 return posix_error();
4646 } else {
4647 Py_INCREF(Py_None);
4648 return Py_None;
4649 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004650}
4651#endif /* HAVE_SETEUID */
4652
4653#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004654PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004655"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004656Set the current process's effective group id.");
4657
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004658static PyObject *
4659posix_setegid (PyObject *self, PyObject *args)
4660{
Victor Stinner8c62be82010-05-06 00:08:46 +00004661 long egid_arg;
4662 gid_t egid;
4663 if (!PyArg_ParseTuple(args, "l", &egid_arg))
4664 return NULL;
4665 egid = egid_arg;
4666 if (egid != egid_arg) {
4667 PyErr_SetString(PyExc_OverflowError, "group id too big");
4668 return NULL;
4669 }
4670 if (setegid(egid) < 0) {
4671 return posix_error();
4672 } else {
4673 Py_INCREF(Py_None);
4674 return Py_None;
4675 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004676}
4677#endif /* HAVE_SETEGID */
4678
4679#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004680PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004681"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004682Set the current process's real and effective user ids.");
4683
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004684static PyObject *
4685posix_setreuid (PyObject *self, PyObject *args)
4686{
Victor Stinner8c62be82010-05-06 00:08:46 +00004687 long ruid_arg, euid_arg;
4688 uid_t ruid, euid;
4689 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
4690 return NULL;
4691 if (ruid_arg == -1)
4692 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
4693 else
4694 ruid = ruid_arg; /* otherwise, assign from our long */
4695 if (euid_arg == -1)
4696 euid = (uid_t)-1;
4697 else
4698 euid = euid_arg;
4699 if ((euid_arg != -1 && euid != euid_arg) ||
4700 (ruid_arg != -1 && ruid != ruid_arg)) {
4701 PyErr_SetString(PyExc_OverflowError, "user id too big");
4702 return NULL;
4703 }
4704 if (setreuid(ruid, euid) < 0) {
4705 return posix_error();
4706 } else {
4707 Py_INCREF(Py_None);
4708 return Py_None;
4709 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004710}
4711#endif /* HAVE_SETREUID */
4712
4713#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004714PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004715"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004716Set the current process's real and effective group ids.");
4717
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004718static PyObject *
4719posix_setregid (PyObject *self, PyObject *args)
4720{
Victor Stinner8c62be82010-05-06 00:08:46 +00004721 long rgid_arg, egid_arg;
4722 gid_t rgid, egid;
4723 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
4724 return NULL;
4725 if (rgid_arg == -1)
4726 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
4727 else
4728 rgid = rgid_arg; /* otherwise, assign from our long */
4729 if (egid_arg == -1)
4730 egid = (gid_t)-1;
4731 else
4732 egid = egid_arg;
4733 if ((egid_arg != -1 && egid != egid_arg) ||
4734 (rgid_arg != -1 && rgid != rgid_arg)) {
4735 PyErr_SetString(PyExc_OverflowError, "group id too big");
4736 return NULL;
4737 }
4738 if (setregid(rgid, egid) < 0) {
4739 return posix_error();
4740 } else {
4741 Py_INCREF(Py_None);
4742 return Py_None;
4743 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004744}
4745#endif /* HAVE_SETREGID */
4746
Guido van Rossumb6775db1994-08-01 11:34:53 +00004747#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004748PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004749"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004750Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004751
Barry Warsaw53699e91996-12-10 23:23:01 +00004752static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004753posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004754{
Victor Stinner8c62be82010-05-06 00:08:46 +00004755 long gid_arg;
4756 gid_t gid;
4757 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
4758 return NULL;
4759 gid = gid_arg;
4760 if (gid != gid_arg) {
4761 PyErr_SetString(PyExc_OverflowError, "group id too big");
4762 return NULL;
4763 }
4764 if (setgid(gid) < 0)
4765 return posix_error();
4766 Py_INCREF(Py_None);
4767 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004768}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004769#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004770
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004771#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004772PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004773"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004774Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004775
4776static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004777posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004778{
Victor Stinner8c62be82010-05-06 00:08:46 +00004779 int i, len;
4780 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004781
Victor Stinner8c62be82010-05-06 00:08:46 +00004782 if (!PySequence_Check(groups)) {
4783 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4784 return NULL;
4785 }
4786 len = PySequence_Size(groups);
4787 if (len > MAX_GROUPS) {
4788 PyErr_SetString(PyExc_ValueError, "too many groups");
4789 return NULL;
4790 }
4791 for(i = 0; i < len; i++) {
4792 PyObject *elem;
4793 elem = PySequence_GetItem(groups, i);
4794 if (!elem)
4795 return NULL;
4796 if (!PyLong_Check(elem)) {
4797 PyErr_SetString(PyExc_TypeError,
4798 "groups must be integers");
4799 Py_DECREF(elem);
4800 return NULL;
4801 } else {
4802 unsigned long x = PyLong_AsUnsignedLong(elem);
4803 if (PyErr_Occurred()) {
4804 PyErr_SetString(PyExc_TypeError,
4805 "group id too big");
4806 Py_DECREF(elem);
4807 return NULL;
4808 }
4809 grouplist[i] = x;
4810 /* read back the value to see if it fitted in gid_t */
4811 if (grouplist[i] != x) {
4812 PyErr_SetString(PyExc_TypeError,
4813 "group id too big");
4814 Py_DECREF(elem);
4815 return NULL;
4816 }
4817 }
4818 Py_DECREF(elem);
4819 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004820
Victor Stinner8c62be82010-05-06 00:08:46 +00004821 if (setgroups(len, grouplist) < 0)
4822 return posix_error();
4823 Py_INCREF(Py_None);
4824 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004825}
4826#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004827
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004828#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4829static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004830wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004831{
Victor Stinner8c62be82010-05-06 00:08:46 +00004832 PyObject *result;
4833 static PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004834
Victor Stinner8c62be82010-05-06 00:08:46 +00004835 if (pid == -1)
4836 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004837
Victor Stinner8c62be82010-05-06 00:08:46 +00004838 if (struct_rusage == NULL) {
4839 PyObject *m = PyImport_ImportModuleNoBlock("resource");
4840 if (m == NULL)
4841 return NULL;
4842 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4843 Py_DECREF(m);
4844 if (struct_rusage == NULL)
4845 return NULL;
4846 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004847
Victor Stinner8c62be82010-05-06 00:08:46 +00004848 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4849 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4850 if (!result)
4851 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004852
4853#ifndef doubletime
4854#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4855#endif
4856
Victor Stinner8c62be82010-05-06 00:08:46 +00004857 PyStructSequence_SET_ITEM(result, 0,
4858 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4859 PyStructSequence_SET_ITEM(result, 1,
4860 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004861#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00004862 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
4863 SET_INT(result, 2, ru->ru_maxrss);
4864 SET_INT(result, 3, ru->ru_ixrss);
4865 SET_INT(result, 4, ru->ru_idrss);
4866 SET_INT(result, 5, ru->ru_isrss);
4867 SET_INT(result, 6, ru->ru_minflt);
4868 SET_INT(result, 7, ru->ru_majflt);
4869 SET_INT(result, 8, ru->ru_nswap);
4870 SET_INT(result, 9, ru->ru_inblock);
4871 SET_INT(result, 10, ru->ru_oublock);
4872 SET_INT(result, 11, ru->ru_msgsnd);
4873 SET_INT(result, 12, ru->ru_msgrcv);
4874 SET_INT(result, 13, ru->ru_nsignals);
4875 SET_INT(result, 14, ru->ru_nvcsw);
4876 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004877#undef SET_INT
4878
Victor Stinner8c62be82010-05-06 00:08:46 +00004879 if (PyErr_Occurred()) {
4880 Py_DECREF(result);
4881 return NULL;
4882 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004883
Victor Stinner8c62be82010-05-06 00:08:46 +00004884 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004885}
4886#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4887
4888#ifdef HAVE_WAIT3
4889PyDoc_STRVAR(posix_wait3__doc__,
4890"wait3(options) -> (pid, status, rusage)\n\n\
4891Wait for completion of a child process.");
4892
4893static PyObject *
4894posix_wait3(PyObject *self, PyObject *args)
4895{
Victor Stinner8c62be82010-05-06 00:08:46 +00004896 pid_t pid;
4897 int options;
4898 struct rusage ru;
4899 WAIT_TYPE status;
4900 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004901
Victor Stinner8c62be82010-05-06 00:08:46 +00004902 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4903 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004904
Victor Stinner8c62be82010-05-06 00:08:46 +00004905 Py_BEGIN_ALLOW_THREADS
4906 pid = wait3(&status, options, &ru);
4907 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004908
Victor Stinner8c62be82010-05-06 00:08:46 +00004909 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004910}
4911#endif /* HAVE_WAIT3 */
4912
4913#ifdef HAVE_WAIT4
4914PyDoc_STRVAR(posix_wait4__doc__,
4915"wait4(pid, options) -> (pid, status, rusage)\n\n\
4916Wait for completion of a given child process.");
4917
4918static PyObject *
4919posix_wait4(PyObject *self, PyObject *args)
4920{
Victor Stinner8c62be82010-05-06 00:08:46 +00004921 pid_t pid;
4922 int options;
4923 struct rusage ru;
4924 WAIT_TYPE status;
4925 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004926
Victor Stinner8c62be82010-05-06 00:08:46 +00004927 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
4928 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004929
Victor Stinner8c62be82010-05-06 00:08:46 +00004930 Py_BEGIN_ALLOW_THREADS
4931 pid = wait4(pid, &status, options, &ru);
4932 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004933
Victor Stinner8c62be82010-05-06 00:08:46 +00004934 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004935}
4936#endif /* HAVE_WAIT4 */
4937
Guido van Rossumb6775db1994-08-01 11:34:53 +00004938#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004939PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004940"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004941Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004942
Barry Warsaw53699e91996-12-10 23:23:01 +00004943static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004944posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004945{
Victor Stinner8c62be82010-05-06 00:08:46 +00004946 pid_t pid;
4947 int options;
4948 WAIT_TYPE status;
4949 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004950
Victor Stinner8c62be82010-05-06 00:08:46 +00004951 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4952 return NULL;
4953 Py_BEGIN_ALLOW_THREADS
4954 pid = waitpid(pid, &status, options);
4955 Py_END_ALLOW_THREADS
4956 if (pid == -1)
4957 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004958
Victor Stinner8c62be82010-05-06 00:08:46 +00004959 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004960}
4961
Tim Petersab034fa2002-02-01 11:27:43 +00004962#elif defined(HAVE_CWAIT)
4963
4964/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004965PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004966"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004967"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004968
4969static PyObject *
4970posix_waitpid(PyObject *self, PyObject *args)
4971{
Victor Stinner8c62be82010-05-06 00:08:46 +00004972 Py_intptr_t pid;
4973 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004974
Victor Stinner8c62be82010-05-06 00:08:46 +00004975 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4976 return NULL;
4977 Py_BEGIN_ALLOW_THREADS
4978 pid = _cwait(&status, pid, options);
4979 Py_END_ALLOW_THREADS
4980 if (pid == -1)
4981 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004982
Victor Stinner8c62be82010-05-06 00:08:46 +00004983 /* shift the status left a byte so this is more like the POSIX waitpid */
4984 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004985}
4986#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004987
Guido van Rossumad0ee831995-03-01 10:34:45 +00004988#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004989PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004990"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004991Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004992
Barry Warsaw53699e91996-12-10 23:23:01 +00004993static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004994posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004995{
Victor Stinner8c62be82010-05-06 00:08:46 +00004996 pid_t pid;
4997 WAIT_TYPE status;
4998 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004999
Victor Stinner8c62be82010-05-06 00:08:46 +00005000 Py_BEGIN_ALLOW_THREADS
5001 pid = wait(&status);
5002 Py_END_ALLOW_THREADS
5003 if (pid == -1)
5004 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005005
Victor Stinner8c62be82010-05-06 00:08:46 +00005006 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005007}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005008#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005009
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005010
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005011PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005012"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005013Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005014
Barry Warsaw53699e91996-12-10 23:23:01 +00005015static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005016posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005017{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005018#ifdef HAVE_LSTAT
Victor Stinner8c62be82010-05-06 00:08:46 +00005019 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005020#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005021#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00005022 return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat",
5023 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005024#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005025 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005026#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005027#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005028}
5029
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005030
Guido van Rossumb6775db1994-08-01 11:34:53 +00005031#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005032PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005033"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005034Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005035
Barry Warsaw53699e91996-12-10 23:23:01 +00005036static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005037posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005038{
Victor Stinner8c62be82010-05-06 00:08:46 +00005039 PyObject* v;
5040 char buf[MAXPATHLEN];
5041 PyObject *opath;
5042 char *path;
5043 int n;
5044 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00005045
Victor Stinner8c62be82010-05-06 00:08:46 +00005046 if (!PyArg_ParseTuple(args, "O&:readlink",
5047 PyUnicode_FSConverter, &opath))
5048 return NULL;
5049 path = PyBytes_AsString(opath);
5050 v = PySequence_GetItem(args, 0);
5051 if (v == NULL) {
5052 Py_DECREF(opath);
5053 return NULL;
5054 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00005055
Victor Stinner8c62be82010-05-06 00:08:46 +00005056 if (PyUnicode_Check(v)) {
5057 arg_is_unicode = 1;
5058 }
5059 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005060
Victor Stinner8c62be82010-05-06 00:08:46 +00005061 Py_BEGIN_ALLOW_THREADS
5062 n = readlink(path, buf, (int) sizeof buf);
5063 Py_END_ALLOW_THREADS
5064 if (n < 0)
5065 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005066
Victor Stinner8c62be82010-05-06 00:08:46 +00005067 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00005068 if (arg_is_unicode)
5069 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
5070 else
5071 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005072}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005073#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005074
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005075
Guido van Rossumb6775db1994-08-01 11:34:53 +00005076#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005077PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005078"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005079Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005080
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005081static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005082posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005083{
Victor Stinner8c62be82010-05-06 00:08:46 +00005084 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005085}
5086#endif /* HAVE_SYMLINK */
5087
Brian Curtind40e6f72010-07-08 21:39:08 +00005088#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
5089
5090PyDoc_STRVAR(win_readlink__doc__,
5091"readlink(path) -> path\n\n\
5092Return a string representing the path to which the symbolic link points.");
5093
Brian Curtind40e6f72010-07-08 21:39:08 +00005094/* Windows readlink implementation */
5095static PyObject *
5096win_readlink(PyObject *self, PyObject *args)
5097{
5098 wchar_t *path;
5099 DWORD n_bytes_returned;
5100 DWORD io_result;
5101 PyObject *result;
5102 HANDLE reparse_point_handle;
5103
5104 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
5105 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
5106 wchar_t *print_name;
5107
5108 if (!PyArg_ParseTuple(args,
5109 "u:readlink",
5110 &path))
5111 return NULL;
5112
5113 /* First get a handle to the reparse point */
5114 Py_BEGIN_ALLOW_THREADS
5115 reparse_point_handle = CreateFileW(
5116 path,
5117 0,
5118 0,
5119 0,
5120 OPEN_EXISTING,
5121 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
5122 0);
5123 Py_END_ALLOW_THREADS
5124
5125 if (reparse_point_handle==INVALID_HANDLE_VALUE)
5126 {
5127 return win32_error_unicode("readlink", path);
5128 }
5129
5130 Py_BEGIN_ALLOW_THREADS
5131 /* New call DeviceIoControl to read the reparse point */
5132 io_result = DeviceIoControl(
5133 reparse_point_handle,
5134 FSCTL_GET_REPARSE_POINT,
5135 0, 0, /* in buffer */
5136 target_buffer, sizeof(target_buffer),
5137 &n_bytes_returned,
5138 0 /* we're not using OVERLAPPED_IO */
5139 );
5140 CloseHandle(reparse_point_handle);
5141 Py_END_ALLOW_THREADS
5142
5143 if (io_result==0)
5144 {
5145 return win32_error_unicode("readlink", path);
5146 }
5147
5148 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
5149 {
5150 PyErr_SetString(PyExc_ValueError,
5151 "not a symbolic link");
5152 return NULL;
5153 }
Brian Curtin74e45612010-07-09 15:58:59 +00005154 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
5155 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
5156
5157 result = PyUnicode_FromWideChar(print_name,
5158 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00005159 return result;
5160}
5161
5162#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
5163
5164#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
5165
5166/* Grab CreateSymbolicLinkW dynamically from kernel32 */
5167static int has_CreateSymbolicLinkW = 0;
5168static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
5169static int
5170check_CreateSymbolicLinkW()
5171{
5172 HINSTANCE hKernel32;
5173 /* only recheck */
5174 if (has_CreateSymbolicLinkW)
5175 return has_CreateSymbolicLinkW;
5176 hKernel32 = GetModuleHandle("KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00005177 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
5178 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00005179 if (Py_CreateSymbolicLinkW)
5180 has_CreateSymbolicLinkW = 1;
5181 return has_CreateSymbolicLinkW;
5182}
5183
5184PyDoc_STRVAR(win_symlink__doc__,
5185"symlink(src, dst, target_is_directory=False)\n\n\
5186Create a symbolic link pointing to src named dst.\n\
5187target_is_directory is required if the target is to be interpreted as\n\
5188a directory.\n\
5189This function requires Windows 6.0 or greater, and raises a\n\
5190NotImplementedError otherwise.");
5191
5192static PyObject *
5193win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
5194{
5195 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
5196 PyObject *src, *dest;
5197 int target_is_directory = 0;
5198 DWORD res;
5199 WIN32_FILE_ATTRIBUTE_DATA src_info;
5200
5201 if (!check_CreateSymbolicLinkW())
5202 {
5203 /* raise NotImplementedError */
5204 return PyErr_Format(PyExc_NotImplementedError,
5205 "CreateSymbolicLinkW not found");
5206 }
5207 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:symlink",
5208 kwlist, &src, &dest, &target_is_directory))
5209 return NULL;
5210 if (!convert_to_unicode(&src)) { return NULL; }
5211 if (!convert_to_unicode(&dest)) {
5212 Py_DECREF(src);
5213 return NULL;
5214 }
5215
5216 /* if src is a directory, ensure target_is_directory==1 */
5217 if(
5218 GetFileAttributesExW(
5219 PyUnicode_AsUnicode(src), GetFileExInfoStandard, &src_info
5220 ))
5221 {
5222 target_is_directory = target_is_directory ||
5223 (src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
5224 }
5225
5226 Py_BEGIN_ALLOW_THREADS
5227 res = Py_CreateSymbolicLinkW(
5228 PyUnicode_AsUnicode(dest),
5229 PyUnicode_AsUnicode(src),
5230 target_is_directory);
5231 Py_END_ALLOW_THREADS
5232 Py_DECREF(src);
5233 Py_DECREF(dest);
5234 if (!res)
5235 {
5236 return win32_error_unicode("symlink", PyUnicode_AsUnicode(src));
5237 }
5238
5239 Py_INCREF(Py_None);
5240 return Py_None;
5241}
5242#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005243
5244#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00005245#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5246static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005247system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005248{
5249 ULONG value = 0;
5250
5251 Py_BEGIN_ALLOW_THREADS
5252 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5253 Py_END_ALLOW_THREADS
5254
5255 return value;
5256}
5257
5258static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005259posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005260{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005261 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00005262 return Py_BuildValue("ddddd",
5263 (double)0 /* t.tms_utime / HZ */,
5264 (double)0 /* t.tms_stime / HZ */,
5265 (double)0 /* t.tms_cutime / HZ */,
5266 (double)0 /* t.tms_cstime / HZ */,
5267 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005268}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005269#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00005270#define NEED_TICKS_PER_SECOND
5271static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00005272static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005273posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005274{
Victor Stinner8c62be82010-05-06 00:08:46 +00005275 struct tms t;
5276 clock_t c;
5277 errno = 0;
5278 c = times(&t);
5279 if (c == (clock_t) -1)
5280 return posix_error();
5281 return Py_BuildValue("ddddd",
5282 (double)t.tms_utime / ticks_per_second,
5283 (double)t.tms_stime / ticks_per_second,
5284 (double)t.tms_cutime / ticks_per_second,
5285 (double)t.tms_cstime / ticks_per_second,
5286 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005287}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005288#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005289#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005290
5291
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005292#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005293#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005294static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005295posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005296{
Victor Stinner8c62be82010-05-06 00:08:46 +00005297 FILETIME create, exit, kernel, user;
5298 HANDLE hProc;
5299 hProc = GetCurrentProcess();
5300 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5301 /* The fields of a FILETIME structure are the hi and lo part
5302 of a 64-bit value expressed in 100 nanosecond units.
5303 1e7 is one second in such units; 1e-7 the inverse.
5304 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5305 */
5306 return Py_BuildValue(
5307 "ddddd",
5308 (double)(user.dwHighDateTime*429.4967296 +
5309 user.dwLowDateTime*1e-7),
5310 (double)(kernel.dwHighDateTime*429.4967296 +
5311 kernel.dwLowDateTime*1e-7),
5312 (double)0,
5313 (double)0,
5314 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005315}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005316#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005317
5318#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005319PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005320"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005321Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005322#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005323
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005324
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005325#ifdef HAVE_GETSID
5326PyDoc_STRVAR(posix_getsid__doc__,
5327"getsid(pid) -> sid\n\n\
5328Call the system call getsid().");
5329
5330static PyObject *
5331posix_getsid(PyObject *self, PyObject *args)
5332{
Victor Stinner8c62be82010-05-06 00:08:46 +00005333 pid_t pid;
5334 int sid;
5335 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
5336 return NULL;
5337 sid = getsid(pid);
5338 if (sid < 0)
5339 return posix_error();
5340 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005341}
5342#endif /* HAVE_GETSID */
5343
5344
Guido van Rossumb6775db1994-08-01 11:34:53 +00005345#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005346PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005347"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005348Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005349
Barry Warsaw53699e91996-12-10 23:23:01 +00005350static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005351posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005352{
Victor Stinner8c62be82010-05-06 00:08:46 +00005353 if (setsid() < 0)
5354 return posix_error();
5355 Py_INCREF(Py_None);
5356 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005357}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005358#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005359
Guido van Rossumb6775db1994-08-01 11:34:53 +00005360#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005361PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005362"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005363Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005364
Barry Warsaw53699e91996-12-10 23:23:01 +00005365static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005366posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005367{
Victor Stinner8c62be82010-05-06 00:08:46 +00005368 pid_t pid;
5369 int pgrp;
5370 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
5371 return NULL;
5372 if (setpgid(pid, pgrp) < 0)
5373 return posix_error();
5374 Py_INCREF(Py_None);
5375 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005376}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005377#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005378
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005379
Guido van Rossumb6775db1994-08-01 11:34:53 +00005380#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005381PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005382"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005383Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005384
Barry Warsaw53699e91996-12-10 23:23:01 +00005385static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005386posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005387{
Victor Stinner8c62be82010-05-06 00:08:46 +00005388 int fd;
5389 pid_t pgid;
5390 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
5391 return NULL;
5392 pgid = tcgetpgrp(fd);
5393 if (pgid < 0)
5394 return posix_error();
5395 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005396}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005397#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005398
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005399
Guido van Rossumb6775db1994-08-01 11:34:53 +00005400#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005401PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005402"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005403Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005404
Barry Warsaw53699e91996-12-10 23:23:01 +00005405static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005406posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005407{
Victor Stinner8c62be82010-05-06 00:08:46 +00005408 int fd;
5409 pid_t pgid;
5410 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
5411 return NULL;
5412 if (tcsetpgrp(fd, pgid) < 0)
5413 return posix_error();
5414 Py_INCREF(Py_None);
5415 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005416}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005417#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005418
Guido van Rossum687dd131993-05-17 08:34:16 +00005419/* Functions acting on file descriptors */
5420
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005421PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005422"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005423Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005424
Barry Warsaw53699e91996-12-10 23:23:01 +00005425static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005426posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005427{
Victor Stinner8c62be82010-05-06 00:08:46 +00005428 PyObject *ofile;
5429 char *file;
5430 int flag;
5431 int mode = 0777;
5432 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005433
5434#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005435 PyUnicodeObject *po;
5436 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5437 Py_BEGIN_ALLOW_THREADS
5438 /* PyUnicode_AS_UNICODE OK without thread
5439 lock as it is a simple dereference. */
5440 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5441 Py_END_ALLOW_THREADS
5442 if (fd < 0)
5443 return posix_error();
5444 return PyLong_FromLong((long)fd);
5445 }
5446 /* Drop the argument parsing error as narrow strings
5447 are also valid. */
5448 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005449#endif
5450
Victor Stinner8c62be82010-05-06 00:08:46 +00005451 if (!PyArg_ParseTuple(args, "O&i|i",
5452 PyUnicode_FSConverter, &ofile,
5453 &flag, &mode))
5454 return NULL;
5455 file = PyBytes_AsString(ofile);
5456 Py_BEGIN_ALLOW_THREADS
5457 fd = open(file, flag, mode);
5458 Py_END_ALLOW_THREADS
5459 if (fd < 0)
5460 return posix_error_with_allocated_filename(ofile);
5461 Py_DECREF(ofile);
5462 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005463}
5464
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005465
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005466PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005467"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005468Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005469
Barry Warsaw53699e91996-12-10 23:23:01 +00005470static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005471posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005472{
Victor Stinner8c62be82010-05-06 00:08:46 +00005473 int fd, res;
5474 if (!PyArg_ParseTuple(args, "i:close", &fd))
5475 return NULL;
5476 if (!_PyVerify_fd(fd))
5477 return posix_error();
5478 Py_BEGIN_ALLOW_THREADS
5479 res = close(fd);
5480 Py_END_ALLOW_THREADS
5481 if (res < 0)
5482 return posix_error();
5483 Py_INCREF(Py_None);
5484 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005485}
5486
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005487
Victor Stinner8c62be82010-05-06 00:08:46 +00005488PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00005489"closerange(fd_low, fd_high)\n\n\
5490Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
5491
5492static PyObject *
5493posix_closerange(PyObject *self, PyObject *args)
5494{
Victor Stinner8c62be82010-05-06 00:08:46 +00005495 int fd_from, fd_to, i;
5496 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
5497 return NULL;
5498 Py_BEGIN_ALLOW_THREADS
5499 for (i = fd_from; i < fd_to; i++)
5500 if (_PyVerify_fd(i))
5501 close(i);
5502 Py_END_ALLOW_THREADS
5503 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00005504}
5505
5506
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005507PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005508"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005509Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005510
Barry Warsaw53699e91996-12-10 23:23:01 +00005511static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005512posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005513{
Victor Stinner8c62be82010-05-06 00:08:46 +00005514 int fd;
5515 if (!PyArg_ParseTuple(args, "i:dup", &fd))
5516 return NULL;
5517 if (!_PyVerify_fd(fd))
5518 return posix_error();
5519 Py_BEGIN_ALLOW_THREADS
5520 fd = dup(fd);
5521 Py_END_ALLOW_THREADS
5522 if (fd < 0)
5523 return posix_error();
5524 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005525}
5526
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005527
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005528PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005529"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005530Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005531
Barry Warsaw53699e91996-12-10 23:23:01 +00005532static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005533posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005534{
Victor Stinner8c62be82010-05-06 00:08:46 +00005535 int fd, fd2, res;
5536 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5537 return NULL;
5538 if (!_PyVerify_fd_dup2(fd, fd2))
5539 return posix_error();
5540 Py_BEGIN_ALLOW_THREADS
5541 res = dup2(fd, fd2);
5542 Py_END_ALLOW_THREADS
5543 if (res < 0)
5544 return posix_error();
5545 Py_INCREF(Py_None);
5546 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005547}
5548
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005549
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005550PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005551"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005552Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005553
Barry Warsaw53699e91996-12-10 23:23:01 +00005554static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005555posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005556{
Victor Stinner8c62be82010-05-06 00:08:46 +00005557 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005558#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005559 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005560#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005561 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005562#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005563 PyObject *posobj;
5564 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5565 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005566#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00005567 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5568 switch (how) {
5569 case 0: how = SEEK_SET; break;
5570 case 1: how = SEEK_CUR; break;
5571 case 2: how = SEEK_END; break;
5572 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005573#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005574
5575#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005576 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005577#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005578 pos = PyLong_Check(posobj) ?
5579 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005580#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005581 if (PyErr_Occurred())
5582 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005583
Victor Stinner8c62be82010-05-06 00:08:46 +00005584 if (!_PyVerify_fd(fd))
5585 return posix_error();
5586 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005587#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005588 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005589#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005590 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005591#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005592 Py_END_ALLOW_THREADS
5593 if (res < 0)
5594 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005595
5596#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005597 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005598#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005599 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005600#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005601}
5602
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005603
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005604PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005605"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005606Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005607
Barry Warsaw53699e91996-12-10 23:23:01 +00005608static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005609posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005610{
Victor Stinner8c62be82010-05-06 00:08:46 +00005611 int fd, size;
5612 Py_ssize_t n;
5613 PyObject *buffer;
5614 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5615 return NULL;
5616 if (size < 0) {
5617 errno = EINVAL;
5618 return posix_error();
5619 }
5620 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
5621 if (buffer == NULL)
5622 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00005623 if (!_PyVerify_fd(fd)) {
5624 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00005625 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00005626 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005627 Py_BEGIN_ALLOW_THREADS
5628 n = read(fd, PyBytes_AS_STRING(buffer), size);
5629 Py_END_ALLOW_THREADS
5630 if (n < 0) {
5631 Py_DECREF(buffer);
5632 return posix_error();
5633 }
5634 if (n != size)
5635 _PyBytes_Resize(&buffer, n);
5636 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00005637}
5638
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005639
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005640PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005641"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005642Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005643
Barry Warsaw53699e91996-12-10 23:23:01 +00005644static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005645posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005646{
Victor Stinner8c62be82010-05-06 00:08:46 +00005647 Py_buffer pbuf;
5648 int fd;
5649 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005650
Victor Stinner8c62be82010-05-06 00:08:46 +00005651 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
5652 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00005653 if (!_PyVerify_fd(fd)) {
5654 PyBuffer_Release(&pbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00005655 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00005656 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005657 Py_BEGIN_ALLOW_THREADS
5658 size = write(fd, pbuf.buf, (size_t)pbuf.len);
5659 Py_END_ALLOW_THREADS
Stefan Krah99439262010-11-26 12:58:05 +00005660 PyBuffer_Release(&pbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00005661 if (size < 0)
5662 return posix_error();
5663 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005664}
5665
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005666
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005667PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005668"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005669Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005670
Barry Warsaw53699e91996-12-10 23:23:01 +00005671static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005672posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005673{
Victor Stinner8c62be82010-05-06 00:08:46 +00005674 int fd;
5675 STRUCT_STAT st;
5676 int res;
5677 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5678 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005679#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00005680 /* on OpenVMS we must ensure that all bytes are written to the file */
5681 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005682#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005683 if (!_PyVerify_fd(fd))
5684 return posix_error();
5685 Py_BEGIN_ALLOW_THREADS
5686 res = FSTAT(fd, &st);
5687 Py_END_ALLOW_THREADS
5688 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00005689#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005690 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00005691#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005692 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005693#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005694 }
Tim Peters5aa91602002-01-30 05:46:57 +00005695
Victor Stinner8c62be82010-05-06 00:08:46 +00005696 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005697}
5698
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005699PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005700"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005701Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005702connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005703
5704static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005705posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005706{
Victor Stinner8c62be82010-05-06 00:08:46 +00005707 int fd;
5708 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5709 return NULL;
5710 if (!_PyVerify_fd(fd))
5711 return PyBool_FromLong(0);
5712 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005713}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005714
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005715#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005716PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005717"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005718Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005719
Barry Warsaw53699e91996-12-10 23:23:01 +00005720static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005721posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005722{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005723#if defined(PYOS_OS2)
5724 HFILE read, write;
5725 APIRET rc;
5726
Victor Stinner8c62be82010-05-06 00:08:46 +00005727 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005728 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinner8c62be82010-05-06 00:08:46 +00005729 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005730 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005731 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005732
5733 return Py_BuildValue("(ii)", read, write);
5734#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005735#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005736 int fds[2];
5737 int res;
5738 Py_BEGIN_ALLOW_THREADS
5739 res = pipe(fds);
5740 Py_END_ALLOW_THREADS
5741 if (res != 0)
5742 return posix_error();
5743 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005744#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00005745 HANDLE read, write;
5746 int read_fd, write_fd;
5747 BOOL ok;
5748 Py_BEGIN_ALLOW_THREADS
5749 ok = CreatePipe(&read, &write, NULL, 0);
5750 Py_END_ALLOW_THREADS
5751 if (!ok)
5752 return win32_error("CreatePipe", NULL);
5753 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5754 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5755 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005756#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005757#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005758}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005759#endif /* HAVE_PIPE */
5760
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005761
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005762#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005763PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005764"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005765Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005766
Barry Warsaw53699e91996-12-10 23:23:01 +00005767static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005768posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005769{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005770 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005771 char *filename;
5772 int mode = 0666;
5773 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005774 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
5775 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00005776 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005777 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005778 Py_BEGIN_ALLOW_THREADS
5779 res = mkfifo(filename, mode);
5780 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005781 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005782 if (res < 0)
5783 return posix_error();
5784 Py_INCREF(Py_None);
5785 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005786}
5787#endif
5788
5789
Neal Norwitz11690112002-07-30 01:08:28 +00005790#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005791PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005792"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005793Create a filesystem node (file, device special file or named pipe)\n\
5794named filename. mode specifies both the permissions to use and the\n\
5795type of node to be created, being combined (bitwise OR) with one of\n\
5796S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005797device defines the newly created device special file (probably using\n\
5798os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005799
5800
5801static PyObject *
5802posix_mknod(PyObject *self, PyObject *args)
5803{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005804 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005805 char *filename;
5806 int mode = 0600;
5807 int device = 0;
5808 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005809 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
5810 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00005811 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005812 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005813 Py_BEGIN_ALLOW_THREADS
5814 res = mknod(filename, mode, device);
5815 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005816 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005817 if (res < 0)
5818 return posix_error();
5819 Py_INCREF(Py_None);
5820 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005821}
5822#endif
5823
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005824#ifdef HAVE_DEVICE_MACROS
5825PyDoc_STRVAR(posix_major__doc__,
5826"major(device) -> major number\n\
5827Extracts a device major number from a raw device number.");
5828
5829static PyObject *
5830posix_major(PyObject *self, PyObject *args)
5831{
Victor Stinner8c62be82010-05-06 00:08:46 +00005832 int device;
5833 if (!PyArg_ParseTuple(args, "i:major", &device))
5834 return NULL;
5835 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005836}
5837
5838PyDoc_STRVAR(posix_minor__doc__,
5839"minor(device) -> minor number\n\
5840Extracts a device minor number from a raw device number.");
5841
5842static PyObject *
5843posix_minor(PyObject *self, PyObject *args)
5844{
Victor Stinner8c62be82010-05-06 00:08:46 +00005845 int device;
5846 if (!PyArg_ParseTuple(args, "i:minor", &device))
5847 return NULL;
5848 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005849}
5850
5851PyDoc_STRVAR(posix_makedev__doc__,
5852"makedev(major, minor) -> device number\n\
5853Composes a raw device number from the major and minor device numbers.");
5854
5855static PyObject *
5856posix_makedev(PyObject *self, PyObject *args)
5857{
Victor Stinner8c62be82010-05-06 00:08:46 +00005858 int major, minor;
5859 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5860 return NULL;
5861 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005862}
5863#endif /* device macros */
5864
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005865
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005866#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005867PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005868"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005869Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005870
Barry Warsaw53699e91996-12-10 23:23:01 +00005871static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005872posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005873{
Victor Stinner8c62be82010-05-06 00:08:46 +00005874 int fd;
5875 off_t length;
5876 int res;
5877 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005878
Victor Stinner8c62be82010-05-06 00:08:46 +00005879 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
5880 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005881
5882#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005883 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005884#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005885 length = PyLong_Check(lenobj) ?
5886 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005887#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005888 if (PyErr_Occurred())
5889 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005890
Victor Stinner8c62be82010-05-06 00:08:46 +00005891 Py_BEGIN_ALLOW_THREADS
5892 res = ftruncate(fd, length);
5893 Py_END_ALLOW_THREADS
5894 if (res < 0)
5895 return posix_error();
5896 Py_INCREF(Py_None);
5897 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005898}
5899#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005900
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005901#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005902PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005903"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005904Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005905
Fred Drake762e2061999-08-26 17:23:54 +00005906/* Save putenv() parameters as values here, so we can collect them when they
5907 * get re-set with another call for the same key. */
5908static PyObject *posix_putenv_garbage;
5909
Tim Peters5aa91602002-01-30 05:46:57 +00005910static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005911posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005912{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005913#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005914 wchar_t *s1, *s2;
5915 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005916#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005917 PyObject *os1, *os2;
5918 char *s1, *s2;
5919 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005920#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005921 PyObject *newstr = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005922 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005923
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005924#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005925 if (!PyArg_ParseTuple(args,
5926 "uu:putenv",
5927 &s1, &s2))
5928 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005929#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005930 if (!PyArg_ParseTuple(args,
5931 "O&O&:putenv",
5932 PyUnicode_FSConverter, &os1,
5933 PyUnicode_FSConverter, &os2))
5934 return NULL;
5935 s1 = PyBytes_AsString(os1);
5936 s2 = PyBytes_AsString(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005937#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005938
5939#if defined(PYOS_OS2)
5940 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5941 APIRET rc;
5942
Guido van Rossumd48f2521997-12-05 22:19:34 +00005943 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005944 if (rc != NO_ERROR) {
5945 os2_error(rc);
5946 goto error;
5947 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005948
5949 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5950 APIRET rc;
5951
Guido van Rossumd48f2521997-12-05 22:19:34 +00005952 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005953 if (rc != NO_ERROR) {
5954 os2_error(rc);
5955 goto error;
5956 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005957 } else {
5958#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005959 /* XXX This can leak memory -- not easy to fix :-( */
5960 /* len includes space for a trailing \0; the size arg to
5961 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005962#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005963 len = wcslen(s1) + wcslen(s2) + 2;
5964 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005965#else
Victor Stinner84ae1182010-05-06 22:05:07 +00005966 len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2;
Victor Stinner8c62be82010-05-06 00:08:46 +00005967 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005968#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005969 if (newstr == NULL) {
5970 PyErr_NoMemory();
5971 goto error;
5972 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005973#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005974 newenv = PyUnicode_AsUnicode(newstr);
5975 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5976 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005977 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00005978 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005979 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005980#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005981 newenv = PyBytes_AS_STRING(newstr);
5982 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5983 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005984 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00005985 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005986 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005987#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005988
Victor Stinner8c62be82010-05-06 00:08:46 +00005989 /* Install the first arg and newstr in posix_putenv_garbage;
5990 * this will cause previous value to be collected. This has to
5991 * happen after the real putenv() call because the old value
5992 * was still accessible until then. */
5993 if (PyDict_SetItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00005994#ifdef MS_WINDOWS
5995 PyTuple_GET_ITEM(args, 0),
5996#else
5997 os1,
5998#endif
5999 newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006000 /* really not much we can do; just leak */
6001 PyErr_Clear();
6002 }
6003 else {
6004 Py_DECREF(newstr);
6005 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006006
6007#if defined(PYOS_OS2)
6008 }
6009#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006010
Martin v. Löwis011e8422009-05-05 04:43:17 +00006011#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006012 Py_DECREF(os1);
6013 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00006014#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006015 Py_RETURN_NONE;
6016
6017error:
6018#ifndef MS_WINDOWS
6019 Py_DECREF(os1);
6020 Py_DECREF(os2);
6021#endif
6022 Py_XDECREF(newstr);
6023 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006024}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006025#endif /* putenv */
6026
Guido van Rossumc524d952001-10-19 01:31:59 +00006027#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006028PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006029"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006030Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006031
6032static PyObject *
6033posix_unsetenv(PyObject *self, PyObject *args)
6034{
Victor Stinner84ae1182010-05-06 22:05:07 +00006035#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00006037
Victor Stinner8c62be82010-05-06 00:08:46 +00006038 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6039 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00006040#else
6041 PyObject *os1;
6042 char *s1;
6043
6044 if (!PyArg_ParseTuple(args, "O&:unsetenv",
6045 PyUnicode_FSConverter, &os1))
6046 return NULL;
6047 s1 = PyBytes_AsString(os1);
6048#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006049
Victor Stinner8c62be82010-05-06 00:08:46 +00006050 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00006051
Victor Stinner8c62be82010-05-06 00:08:46 +00006052 /* Remove the key from posix_putenv_garbage;
6053 * this will cause it to be collected. This has to
6054 * happen after the real unsetenv() call because the
6055 * old value was still accessible until then.
6056 */
6057 if (PyDict_DelItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00006058#ifdef MS_WINDOWS
6059 PyTuple_GET_ITEM(args, 0)
6060#else
6061 os1
6062#endif
6063 )) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006064 /* really not much we can do; just leak */
6065 PyErr_Clear();
6066 }
Guido van Rossumc524d952001-10-19 01:31:59 +00006067
Victor Stinner84ae1182010-05-06 22:05:07 +00006068#ifndef MS_WINDOWS
6069 Py_DECREF(os1);
6070#endif
6071 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00006072}
6073#endif /* unsetenv */
6074
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006075PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006076"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006077Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006078
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006079static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006080posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006081{
Victor Stinner8c62be82010-05-06 00:08:46 +00006082 int code;
6083 char *message;
6084 if (!PyArg_ParseTuple(args, "i:strerror", &code))
6085 return NULL;
6086 message = strerror(code);
6087 if (message == NULL) {
6088 PyErr_SetString(PyExc_ValueError,
6089 "strerror() argument out of range");
6090 return NULL;
6091 }
6092 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006093}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006094
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006095
Guido van Rossumc9641791998-08-04 15:26:23 +00006096#ifdef HAVE_SYS_WAIT_H
6097
Fred Drake106c1a02002-04-23 15:58:02 +00006098#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006099PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006100"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006101Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006102
6103static PyObject *
6104posix_WCOREDUMP(PyObject *self, PyObject *args)
6105{
Victor Stinner8c62be82010-05-06 00:08:46 +00006106 WAIT_TYPE status;
6107 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006108
Victor Stinner8c62be82010-05-06 00:08:46 +00006109 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
6110 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006111
Victor Stinner8c62be82010-05-06 00:08:46 +00006112 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006113}
6114#endif /* WCOREDUMP */
6115
6116#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006117PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006118"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006119Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006120job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006121
6122static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006123posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006124{
Victor Stinner8c62be82010-05-06 00:08:46 +00006125 WAIT_TYPE status;
6126 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006127
Victor Stinner8c62be82010-05-06 00:08:46 +00006128 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
6129 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006130
Victor Stinner8c62be82010-05-06 00:08:46 +00006131 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006132}
6133#endif /* WIFCONTINUED */
6134
Guido van Rossumc9641791998-08-04 15:26:23 +00006135#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006136PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006137"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006138Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006139
6140static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006141posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006142{
Victor Stinner8c62be82010-05-06 00:08:46 +00006143 WAIT_TYPE status;
6144 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006145
Victor Stinner8c62be82010-05-06 00:08:46 +00006146 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
6147 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006148
Victor Stinner8c62be82010-05-06 00:08:46 +00006149 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006150}
6151#endif /* WIFSTOPPED */
6152
6153#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006154PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006155"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006156Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006157
6158static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006159posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006160{
Victor Stinner8c62be82010-05-06 00:08:46 +00006161 WAIT_TYPE status;
6162 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006163
Victor Stinner8c62be82010-05-06 00:08:46 +00006164 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
6165 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006166
Victor Stinner8c62be82010-05-06 00:08:46 +00006167 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006168}
6169#endif /* WIFSIGNALED */
6170
6171#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006172PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006173"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006174Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006175system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006176
6177static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006178posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006179{
Victor Stinner8c62be82010-05-06 00:08:46 +00006180 WAIT_TYPE status;
6181 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006182
Victor Stinner8c62be82010-05-06 00:08:46 +00006183 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
6184 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006185
Victor Stinner8c62be82010-05-06 00:08:46 +00006186 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006187}
6188#endif /* WIFEXITED */
6189
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006190#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006191PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006192"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006193Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006194
6195static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006196posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006197{
Victor Stinner8c62be82010-05-06 00:08:46 +00006198 WAIT_TYPE status;
6199 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006200
Victor Stinner8c62be82010-05-06 00:08:46 +00006201 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
6202 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006203
Victor Stinner8c62be82010-05-06 00:08:46 +00006204 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006205}
6206#endif /* WEXITSTATUS */
6207
6208#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006209PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006210"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006211Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006212value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006213
6214static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006215posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006216{
Victor Stinner8c62be82010-05-06 00:08:46 +00006217 WAIT_TYPE status;
6218 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006219
Victor Stinner8c62be82010-05-06 00:08:46 +00006220 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
6221 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006222
Victor Stinner8c62be82010-05-06 00:08:46 +00006223 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006224}
6225#endif /* WTERMSIG */
6226
6227#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006228PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006229"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006230Return the signal that stopped the process that provided\n\
6231the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006232
6233static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006234posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006235{
Victor Stinner8c62be82010-05-06 00:08:46 +00006236 WAIT_TYPE status;
6237 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006238
Victor Stinner8c62be82010-05-06 00:08:46 +00006239 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
6240 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006241
Victor Stinner8c62be82010-05-06 00:08:46 +00006242 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006243}
6244#endif /* WSTOPSIG */
6245
6246#endif /* HAVE_SYS_WAIT_H */
6247
6248
Thomas Wouters477c8d52006-05-27 19:21:47 +00006249#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006250#ifdef _SCO_DS
6251/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6252 needed definitions in sys/statvfs.h */
6253#define _SVID3
6254#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006255#include <sys/statvfs.h>
6256
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006257static PyObject*
6258_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006259 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6260 if (v == NULL)
6261 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006262
6263#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006264 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6265 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6266 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
6267 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
6268 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
6269 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
6270 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
6271 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
6272 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6273 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006274#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006275 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6276 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6277 PyStructSequence_SET_ITEM(v, 2,
6278 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
6279 PyStructSequence_SET_ITEM(v, 3,
6280 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
6281 PyStructSequence_SET_ITEM(v, 4,
6282 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
6283 PyStructSequence_SET_ITEM(v, 5,
6284 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
6285 PyStructSequence_SET_ITEM(v, 6,
6286 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
6287 PyStructSequence_SET_ITEM(v, 7,
6288 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
6289 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6290 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006291#endif
6292
Victor Stinner8c62be82010-05-06 00:08:46 +00006293 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006294}
6295
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006296PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006297"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006298Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006299
6300static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006301posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006302{
Victor Stinner8c62be82010-05-06 00:08:46 +00006303 int fd, res;
6304 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006305
Victor Stinner8c62be82010-05-06 00:08:46 +00006306 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
6307 return NULL;
6308 Py_BEGIN_ALLOW_THREADS
6309 res = fstatvfs(fd, &st);
6310 Py_END_ALLOW_THREADS
6311 if (res != 0)
6312 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006313
Victor Stinner8c62be82010-05-06 00:08:46 +00006314 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006315}
Thomas Wouters477c8d52006-05-27 19:21:47 +00006316#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006317
6318
Thomas Wouters477c8d52006-05-27 19:21:47 +00006319#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006320#include <sys/statvfs.h>
6321
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006322PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006323"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006324Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006325
6326static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006327posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006328{
Victor Stinner8c62be82010-05-06 00:08:46 +00006329 char *path;
6330 int res;
6331 struct statvfs st;
6332 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
6333 return NULL;
6334 Py_BEGIN_ALLOW_THREADS
6335 res = statvfs(path, &st);
6336 Py_END_ALLOW_THREADS
6337 if (res != 0)
6338 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006339
Victor Stinner8c62be82010-05-06 00:08:46 +00006340 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006341}
6342#endif /* HAVE_STATVFS */
6343
Fred Drakec9680921999-12-13 16:37:25 +00006344/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6345 * It maps strings representing configuration variable names to
6346 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006347 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006348 * rarely-used constants. There are three separate tables that use
6349 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006350 *
6351 * This code is always included, even if none of the interfaces that
6352 * need it are included. The #if hackery needed to avoid it would be
6353 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006354 */
6355struct constdef {
6356 char *name;
6357 long value;
6358};
6359
Fred Drake12c6e2d1999-12-14 21:25:03 +00006360static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006361conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00006362 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006363{
Christian Heimes217cfd12007-12-02 14:31:20 +00006364 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006365 *valuep = PyLong_AS_LONG(arg);
6366 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006367 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00006368 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00006369 /* look up the value in the table using a binary search */
6370 size_t lo = 0;
6371 size_t mid;
6372 size_t hi = tablesize;
6373 int cmp;
6374 const char *confname;
6375 if (!PyUnicode_Check(arg)) {
6376 PyErr_SetString(PyExc_TypeError,
6377 "configuration names must be strings or integers");
6378 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006379 }
Stefan Krah0e803b32010-11-26 16:16:47 +00006380 confname = _PyUnicode_AsString(arg);
6381 if (confname == NULL)
6382 return 0;
6383 while (lo < hi) {
6384 mid = (lo + hi) / 2;
6385 cmp = strcmp(confname, table[mid].name);
6386 if (cmp < 0)
6387 hi = mid;
6388 else if (cmp > 0)
6389 lo = mid + 1;
6390 else {
6391 *valuep = table[mid].value;
6392 return 1;
6393 }
6394 }
6395 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6396 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006397 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00006398}
6399
6400
6401#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6402static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006403#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006404 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006405#endif
6406#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006407 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006408#endif
Fred Drakec9680921999-12-13 16:37:25 +00006409#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006410 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006411#endif
6412#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00006413 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00006414#endif
6415#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00006416 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00006417#endif
6418#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00006419 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00006420#endif
6421#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006422 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006423#endif
6424#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00006425 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00006426#endif
6427#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00006428 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00006429#endif
6430#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006431 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006432#endif
6433#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006434 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00006435#endif
6436#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006437 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006438#endif
6439#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006440 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00006441#endif
6442#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006443 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006444#endif
6445#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006446 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00006447#endif
6448#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006449 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006450#endif
6451#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00006452 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00006453#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00006454#ifdef _PC_ACL_ENABLED
6455 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
6456#endif
6457#ifdef _PC_MIN_HOLE_SIZE
6458 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
6459#endif
6460#ifdef _PC_ALLOC_SIZE_MIN
6461 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
6462#endif
6463#ifdef _PC_REC_INCR_XFER_SIZE
6464 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
6465#endif
6466#ifdef _PC_REC_MAX_XFER_SIZE
6467 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
6468#endif
6469#ifdef _PC_REC_MIN_XFER_SIZE
6470 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
6471#endif
6472#ifdef _PC_REC_XFER_ALIGN
6473 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
6474#endif
6475#ifdef _PC_SYMLINK_MAX
6476 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
6477#endif
6478#ifdef _PC_XATTR_ENABLED
6479 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
6480#endif
6481#ifdef _PC_XATTR_EXISTS
6482 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
6483#endif
6484#ifdef _PC_TIMESTAMP_RESOLUTION
6485 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
6486#endif
Fred Drakec9680921999-12-13 16:37:25 +00006487};
6488
Fred Drakec9680921999-12-13 16:37:25 +00006489static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006490conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006491{
6492 return conv_confname(arg, valuep, posix_constants_pathconf,
6493 sizeof(posix_constants_pathconf)
6494 / sizeof(struct constdef));
6495}
6496#endif
6497
6498#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006499PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006500"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006501Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006502If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006503
6504static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006505posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006506{
6507 PyObject *result = NULL;
6508 int name, fd;
6509
Fred Drake12c6e2d1999-12-14 21:25:03 +00006510 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6511 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006512 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006513
Stefan Krah0e803b32010-11-26 16:16:47 +00006514 errno = 0;
6515 limit = fpathconf(fd, name);
6516 if (limit == -1 && errno != 0)
6517 posix_error();
6518 else
6519 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006520 }
6521 return result;
6522}
6523#endif
6524
6525
6526#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006527PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006528"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006529Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006530If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006531
6532static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006533posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006534{
6535 PyObject *result = NULL;
6536 int name;
6537 char *path;
6538
6539 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6540 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006541 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006542
Victor Stinner8c62be82010-05-06 00:08:46 +00006543 errno = 0;
6544 limit = pathconf(path, name);
6545 if (limit == -1 && errno != 0) {
6546 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00006547 /* could be a path or name problem */
6548 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00006549 else
Stefan Krah99439262010-11-26 12:58:05 +00006550 posix_error_with_filename(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00006551 }
6552 else
6553 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006554 }
6555 return result;
6556}
6557#endif
6558
6559#ifdef HAVE_CONFSTR
6560static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006561#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00006562 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00006563#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00006564#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006565 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006566#endif
6567#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006568 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006569#endif
Fred Draked86ed291999-12-15 15:34:33 +00006570#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006571 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006572#endif
6573#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006574 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006575#endif
6576#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006577 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006578#endif
6579#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006580 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006581#endif
Fred Drakec9680921999-12-13 16:37:25 +00006582#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006583 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006584#endif
6585#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006586 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006587#endif
6588#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006589 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006590#endif
6591#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006592 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006593#endif
6594#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006595 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006596#endif
6597#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006598 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006599#endif
6600#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006601 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006602#endif
6603#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006604 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006605#endif
Fred Draked86ed291999-12-15 15:34:33 +00006606#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00006607 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00006608#endif
Fred Drakec9680921999-12-13 16:37:25 +00006609#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00006610 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00006611#endif
Fred Draked86ed291999-12-15 15:34:33 +00006612#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006613 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00006614#endif
6615#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006616 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00006617#endif
6618#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006619 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006620#endif
6621#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006622 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00006623#endif
Fred Drakec9680921999-12-13 16:37:25 +00006624#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006625 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006626#endif
6627#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006628 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006629#endif
6630#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006631 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006632#endif
6633#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006634 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006635#endif
6636#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006637 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006638#endif
6639#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006640 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006641#endif
6642#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006643 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006644#endif
6645#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006646 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006647#endif
6648#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006649 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006650#endif
6651#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006652 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006653#endif
6654#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006655 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006656#endif
6657#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006658 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006659#endif
6660#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006661 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006662#endif
6663#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006664 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006665#endif
6666#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006667 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006668#endif
6669#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006670 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006671#endif
Fred Draked86ed291999-12-15 15:34:33 +00006672#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006673 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006674#endif
6675#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006676 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00006677#endif
6678#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00006679 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00006680#endif
6681#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006682 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006683#endif
6684#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006685 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006686#endif
6687#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00006688 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00006689#endif
6690#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006691 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00006692#endif
6693#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00006694 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00006695#endif
6696#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006697 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006698#endif
6699#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006700 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006701#endif
6702#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006703 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006704#endif
6705#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006706 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006707#endif
6708#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00006709 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00006710#endif
Fred Drakec9680921999-12-13 16:37:25 +00006711};
6712
6713static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006714conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006715{
6716 return conv_confname(arg, valuep, posix_constants_confstr,
6717 sizeof(posix_constants_confstr)
6718 / sizeof(struct constdef));
6719}
6720
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006721PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006722"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006723Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006724
6725static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006726posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006727{
6728 PyObject *result = NULL;
6729 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00006730 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00006731 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006732
Victor Stinnercb043522010-09-10 23:49:04 +00006733 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
6734 return NULL;
6735
6736 errno = 0;
6737 len = confstr(name, buffer, sizeof(buffer));
6738 if (len == 0) {
6739 if (errno) {
6740 posix_error();
6741 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00006742 }
6743 else {
Victor Stinnercb043522010-09-10 23:49:04 +00006744 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00006745 }
6746 }
Victor Stinnercb043522010-09-10 23:49:04 +00006747
6748 if ((unsigned int)len >= sizeof(buffer)) {
6749 char *buf = PyMem_Malloc(len);
6750 if (buf == NULL)
6751 return PyErr_NoMemory();
6752 confstr(name, buf, len);
6753 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
6754 PyMem_Free(buf);
6755 }
6756 else
6757 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006758 return result;
6759}
6760#endif
6761
6762
6763#ifdef HAVE_SYSCONF
6764static struct constdef posix_constants_sysconf[] = {
6765#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00006766 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00006767#endif
6768#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00006769 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00006770#endif
6771#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006772 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006773#endif
6774#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006775 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006776#endif
6777#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006778 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006779#endif
6780#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00006781 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00006782#endif
6783#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00006784 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00006785#endif
6786#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006787 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006788#endif
6789#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00006790 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00006791#endif
6792#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006793 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006794#endif
Fred Draked86ed291999-12-15 15:34:33 +00006795#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006796 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006797#endif
6798#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00006800#endif
Fred Drakec9680921999-12-13 16:37:25 +00006801#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006803#endif
Fred Drakec9680921999-12-13 16:37:25 +00006804#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006805 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006806#endif
6807#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006808 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006809#endif
6810#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006811 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006812#endif
6813#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006814 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006815#endif
6816#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006818#endif
Fred Draked86ed291999-12-15 15:34:33 +00006819#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006820 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00006821#endif
Fred Drakec9680921999-12-13 16:37:25 +00006822#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00006823 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006824#endif
6825#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006827#endif
6828#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006829 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006830#endif
6831#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006832 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006833#endif
6834#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006835 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006836#endif
Fred Draked86ed291999-12-15 15:34:33 +00006837#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00006838 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00006839#endif
Fred Drakec9680921999-12-13 16:37:25 +00006840#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006841 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006842#endif
6843#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006844 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006845#endif
6846#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006847 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006848#endif
6849#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006850 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006851#endif
6852#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006853 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006854#endif
6855#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006856 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00006857#endif
6858#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006859 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006860#endif
6861#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006862 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006863#endif
6864#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006865 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006866#endif
6867#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006869#endif
6870#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006871 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006872#endif
6873#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006874 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006875#endif
6876#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006877 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006878#endif
6879#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006880 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006881#endif
6882#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006883 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006884#endif
6885#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006886 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006887#endif
6888#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006889 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00006890#endif
6891#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006892 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006893#endif
6894#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006895 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006896#endif
6897#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006898 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006899#endif
6900#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006901 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006902#endif
6903#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006904 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006905#endif
6906#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006907 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006908#endif
Fred Draked86ed291999-12-15 15:34:33 +00006909#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00006910 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00006911#endif
Fred Drakec9680921999-12-13 16:37:25 +00006912#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006913 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006914#endif
6915#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006916 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006917#endif
6918#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006919 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006920#endif
Fred Draked86ed291999-12-15 15:34:33 +00006921#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006922 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00006923#endif
Fred Drakec9680921999-12-13 16:37:25 +00006924#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00006925 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00006926#endif
Fred Draked86ed291999-12-15 15:34:33 +00006927#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00006928 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00006929#endif
6930#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00006931 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00006932#endif
Fred Drakec9680921999-12-13 16:37:25 +00006933#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006934 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006935#endif
6936#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006937 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006938#endif
6939#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006940 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006941#endif
6942#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006943 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006944#endif
Fred Draked86ed291999-12-15 15:34:33 +00006945#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00006946 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00006947#endif
Fred Drakec9680921999-12-13 16:37:25 +00006948#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00006949 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00006950#endif
6951#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00006952 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00006953#endif
6954#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006955 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006956#endif
6957#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006958 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00006959#endif
6960#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00006961 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00006962#endif
6963#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00006964 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00006965#endif
6966#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00006967 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00006968#endif
Fred Draked86ed291999-12-15 15:34:33 +00006969#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00006970 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00006971#endif
Fred Drakec9680921999-12-13 16:37:25 +00006972#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006973 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006974#endif
6975#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006976 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006977#endif
Fred Draked86ed291999-12-15 15:34:33 +00006978#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006979 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006980#endif
Fred Drakec9680921999-12-13 16:37:25 +00006981#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006982 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006983#endif
6984#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006985 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006986#endif
6987#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006988 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006989#endif
6990#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006991 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006992#endif
6993#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006994 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006995#endif
6996#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006997 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006998#endif
6999#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007000 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007001#endif
7002#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007003 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00007004#endif
7005#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00007006 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00007007#endif
Fred Draked86ed291999-12-15 15:34:33 +00007008#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007009 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00007010#endif
7011#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00007012 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00007013#endif
Fred Drakec9680921999-12-13 16:37:25 +00007014#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00007015 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00007016#endif
7017#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007018 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007019#endif
7020#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007021 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007022#endif
7023#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007024 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007025#endif
7026#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007027 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007028#endif
7029#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00007030 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00007031#endif
7032#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00007033 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00007034#endif
7035#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00007036 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00007037#endif
7038#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00007039 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00007040#endif
7041#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00007042 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00007043#endif
7044#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00007045 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00007046#endif
7047#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007048 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00007049#endif
7050#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007051 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00007052#endif
7053#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00007054 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00007055#endif
7056#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00007057 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00007058#endif
7059#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00007060 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00007061#endif
7062#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00007063 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00007064#endif
7065#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007066 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007067#endif
7068#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007069 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007070#endif
7071#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00007072 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00007073#endif
7074#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007075 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007076#endif
7077#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007078 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007079#endif
7080#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00007081 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00007082#endif
7083#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007084 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007085#endif
7086#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007087 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007088#endif
7089#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007090 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00007091#endif
7092#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00007093 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00007094#endif
7095#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007096 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007097#endif
7098#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007099 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007100#endif
7101#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007102 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00007103#endif
7104#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007105 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007106#endif
7107#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007108 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007109#endif
7110#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007111 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007112#endif
7113#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007114 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007115#endif
7116#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007117 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007118#endif
Fred Draked86ed291999-12-15 15:34:33 +00007119#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00007120 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00007121#endif
Fred Drakec9680921999-12-13 16:37:25 +00007122#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00007123 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00007124#endif
7125#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007126 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007127#endif
7128#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00007129 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00007130#endif
7131#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007132 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007133#endif
7134#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007135 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007136#endif
7137#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007138 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007139#endif
7140#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00007141 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00007142#endif
7143#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007144 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007145#endif
7146#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007147 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007148#endif
7149#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007150 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007151#endif
7152#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007153 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007154#endif
7155#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007156 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00007157#endif
7158#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007159 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00007160#endif
7161#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00007162 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00007163#endif
7164#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007165 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007166#endif
7167#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007168 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007169#endif
7170#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007171 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007172#endif
7173#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00007174 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00007175#endif
7176#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007177 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007178#endif
7179#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007180 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007181#endif
7182#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007183 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007184#endif
7185#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007186 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007187#endif
7188#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007189 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007190#endif
7191#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007192 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007193#endif
7194#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00007195 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00007196#endif
7197#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007198 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007199#endif
7200#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007201 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007202#endif
7203#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007204 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007205#endif
7206#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007207 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007208#endif
7209#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00007210 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00007211#endif
7212#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007213 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007214#endif
7215#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00007216 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00007217#endif
7218#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007219 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007220#endif
7221#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00007222 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00007223#endif
7224#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00007225 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00007226#endif
7227#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00007228 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00007229#endif
7230#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00007231 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00007232#endif
7233#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007234 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007235#endif
7236#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00007237 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00007238#endif
7239#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00007240 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00007241#endif
7242#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007243 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007244#endif
7245#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007246 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007247#endif
7248#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00007249 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00007250#endif
7251#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00007252 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00007253#endif
7254#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00007255 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00007256#endif
7257};
7258
7259static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007260conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007261{
7262 return conv_confname(arg, valuep, posix_constants_sysconf,
7263 sizeof(posix_constants_sysconf)
7264 / sizeof(struct constdef));
7265}
7266
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007267PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007268"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007269Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007270
7271static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007272posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007273{
7274 PyObject *result = NULL;
7275 int name;
7276
7277 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7278 int value;
7279
7280 errno = 0;
7281 value = sysconf(name);
7282 if (value == -1 && errno != 0)
7283 posix_error();
7284 else
Christian Heimes217cfd12007-12-02 14:31:20 +00007285 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00007286 }
7287 return result;
7288}
7289#endif
7290
7291
Fred Drakebec628d1999-12-15 18:31:10 +00007292/* This code is used to ensure that the tables of configuration value names
7293 * are in sorted order as required by conv_confname(), and also to build the
7294 * the exported dictionaries that are used to publish information about the
7295 * names available on the host platform.
7296 *
7297 * Sorting the table at runtime ensures that the table is properly ordered
7298 * when used, even for platforms we're not able to test on. It also makes
7299 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007300 */
Fred Drakebec628d1999-12-15 18:31:10 +00007301
7302static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007303cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007304{
7305 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007306 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00007307 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007308 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00007309
7310 return strcmp(c1->name, c2->name);
7311}
7312
7313static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007314setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00007315 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007316{
Fred Drakebec628d1999-12-15 18:31:10 +00007317 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007318 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007319
7320 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7321 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007322 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00007323 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007324
Barry Warsaw3155db32000-04-13 15:20:40 +00007325 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007326 PyObject *o = PyLong_FromLong(table[i].value);
7327 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7328 Py_XDECREF(o);
7329 Py_DECREF(d);
7330 return -1;
7331 }
7332 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007333 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007334 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007335}
7336
Fred Drakebec628d1999-12-15 18:31:10 +00007337/* Return -1 on failure, 0 on success. */
7338static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007339setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007340{
7341#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007342 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007343 sizeof(posix_constants_pathconf)
7344 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007345 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00007346 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007347#endif
7348#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007349 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007350 sizeof(posix_constants_confstr)
7351 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007352 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00007353 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007354#endif
7355#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007356 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007357 sizeof(posix_constants_sysconf)
7358 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007359 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00007360 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007361#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007362 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007363}
Fred Draked86ed291999-12-15 15:34:33 +00007364
7365
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007366PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007367"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007368Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007369in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007370
7371static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007372posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007373{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007374 abort();
7375 /*NOTREACHED*/
7376 Py_FatalError("abort() called from Python code didn't abort!");
7377 return NULL;
7378}
Fred Drakebec628d1999-12-15 18:31:10 +00007379
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007380#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007381PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007382"startfile(filepath [, operation]) - Start a file with its associated\n\
7383application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007384\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007385When \"operation\" is not specified or \"open\", this acts like\n\
7386double-clicking the file in Explorer, or giving the file name as an\n\
7387argument to the DOS \"start\" command: the file is opened with whatever\n\
7388application (if any) its extension is associated.\n\
7389When another \"operation\" is given, it specifies what should be done with\n\
7390the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007391\n\
7392startfile returns as soon as the associated application is launched.\n\
7393There is no option to wait for the application to close, and no way\n\
7394to retrieve the application's exit status.\n\
7395\n\
7396The filepath is relative to the current directory. If you want to use\n\
7397an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007398the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007399
7400static PyObject *
7401win32_startfile(PyObject *self, PyObject *args)
7402{
Victor Stinner8c62be82010-05-06 00:08:46 +00007403 PyObject *ofilepath;
7404 char *filepath;
7405 char *operation = NULL;
7406 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00007407
Victor Stinner8c62be82010-05-06 00:08:46 +00007408 PyObject *unipath, *woperation = NULL;
7409 if (!PyArg_ParseTuple(args, "U|s:startfile",
7410 &unipath, &operation)) {
7411 PyErr_Clear();
7412 goto normal;
7413 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007414
Victor Stinner8c62be82010-05-06 00:08:46 +00007415 if (operation) {
7416 woperation = PyUnicode_DecodeASCII(operation,
7417 strlen(operation), NULL);
7418 if (!woperation) {
7419 PyErr_Clear();
7420 operation = NULL;
7421 goto normal;
7422 }
7423 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007424
Victor Stinner8c62be82010-05-06 00:08:46 +00007425 Py_BEGIN_ALLOW_THREADS
7426 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
7427 PyUnicode_AS_UNICODE(unipath),
7428 NULL, NULL, SW_SHOWNORMAL);
7429 Py_END_ALLOW_THREADS
7430
7431 Py_XDECREF(woperation);
7432 if (rc <= (HINSTANCE)32) {
7433 PyObject *errval = win32_error_unicode("startfile",
7434 PyUnicode_AS_UNICODE(unipath));
7435 return errval;
7436 }
7437 Py_INCREF(Py_None);
7438 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007439
7440normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00007441 if (!PyArg_ParseTuple(args, "O&|s:startfile",
7442 PyUnicode_FSConverter, &ofilepath,
7443 &operation))
7444 return NULL;
7445 filepath = PyBytes_AsString(ofilepath);
7446 Py_BEGIN_ALLOW_THREADS
7447 rc = ShellExecute((HWND)0, operation, filepath,
7448 NULL, NULL, SW_SHOWNORMAL);
7449 Py_END_ALLOW_THREADS
7450 if (rc <= (HINSTANCE)32) {
7451 PyObject *errval = win32_error("startfile", filepath);
7452 Py_DECREF(ofilepath);
7453 return errval;
7454 }
7455 Py_DECREF(ofilepath);
7456 Py_INCREF(Py_None);
7457 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007458}
7459#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007460
Martin v. Löwis438b5342002-12-27 10:16:42 +00007461#ifdef HAVE_GETLOADAVG
7462PyDoc_STRVAR(posix_getloadavg__doc__,
7463"getloadavg() -> (float, float, float)\n\n\
7464Return the number of processes in the system run queue averaged over\n\
7465the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7466was unobtainable");
7467
7468static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007469posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007470{
7471 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007472 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00007473 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7474 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00007475 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00007476 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00007477}
7478#endif
7479
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007480#ifdef MS_WINDOWS
7481
7482PyDoc_STRVAR(win32_urandom__doc__,
7483"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007484Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007485
7486typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7487 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7488 DWORD dwFlags );
7489typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7490 BYTE *pbBuffer );
7491
7492static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00007493/* This handle is never explicitly released. Instead, the operating
7494 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007495static HCRYPTPROV hCryptProv = 0;
7496
Tim Peters4ad82172004-08-30 17:02:04 +00007497static PyObject*
7498win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007499{
Victor Stinner8c62be82010-05-06 00:08:46 +00007500 int howMany;
7501 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007502
Victor Stinner8c62be82010-05-06 00:08:46 +00007503 /* Read arguments */
7504 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7505 return NULL;
7506 if (howMany < 0)
7507 return PyErr_Format(PyExc_ValueError,
7508 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007509
Victor Stinner8c62be82010-05-06 00:08:46 +00007510 if (hCryptProv == 0) {
7511 HINSTANCE hAdvAPI32 = NULL;
7512 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007513
Victor Stinner8c62be82010-05-06 00:08:46 +00007514 /* Obtain handle to the DLL containing CryptoAPI
7515 This should not fail */
7516 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7517 if(hAdvAPI32 == NULL)
7518 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007519
Victor Stinner8c62be82010-05-06 00:08:46 +00007520 /* Obtain pointers to the CryptoAPI functions
7521 This will fail on some early versions of Win95 */
7522 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7523 hAdvAPI32,
7524 "CryptAcquireContextA");
7525 if (pCryptAcquireContext == NULL)
7526 return PyErr_Format(PyExc_NotImplementedError,
7527 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007528
Victor Stinner8c62be82010-05-06 00:08:46 +00007529 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7530 hAdvAPI32, "CryptGenRandom");
7531 if (pCryptGenRandom == NULL)
7532 return PyErr_Format(PyExc_NotImplementedError,
7533 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007534
Victor Stinner8c62be82010-05-06 00:08:46 +00007535 /* Acquire context */
7536 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7537 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7538 return win32_error("CryptAcquireContext", NULL);
7539 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007540
Victor Stinner8c62be82010-05-06 00:08:46 +00007541 /* Allocate bytes */
7542 result = PyBytes_FromStringAndSize(NULL, howMany);
7543 if (result != NULL) {
7544 /* Get random data */
7545 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
7546 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7547 PyBytes_AS_STRING(result))) {
7548 Py_DECREF(result);
7549 return win32_error("CryptGenRandom", NULL);
7550 }
7551 }
7552 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007553}
7554#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007555
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007556PyDoc_STRVAR(device_encoding__doc__,
7557"device_encoding(fd) -> str\n\n\
7558Return a string describing the encoding of the device\n\
7559if the output is a terminal; else return None.");
7560
7561static PyObject *
7562device_encoding(PyObject *self, PyObject *args)
7563{
Victor Stinner8c62be82010-05-06 00:08:46 +00007564 int fd;
7565 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
7566 return NULL;
7567 if (!_PyVerify_fd(fd) || !isatty(fd)) {
7568 Py_INCREF(Py_None);
7569 return Py_None;
7570 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007571#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner8c62be82010-05-06 00:08:46 +00007572 if (fd == 0) {
7573 char buf[100];
7574 sprintf(buf, "cp%d", GetConsoleCP());
7575 return PyUnicode_FromString(buf);
7576 }
7577 if (fd == 1 || fd == 2) {
7578 char buf[100];
7579 sprintf(buf, "cp%d", GetConsoleOutputCP());
7580 return PyUnicode_FromString(buf);
7581 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007582#elif defined(CODESET)
Victor Stinner8c62be82010-05-06 00:08:46 +00007583 {
7584 char *codeset = nl_langinfo(CODESET);
7585 if (codeset != NULL && codeset[0] != 0)
7586 return PyUnicode_FromString(codeset);
7587 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007588#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007589 Py_INCREF(Py_None);
7590 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007591}
7592
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007593#ifdef __VMS
7594/* Use openssl random routine */
7595#include <openssl/rand.h>
7596PyDoc_STRVAR(vms_urandom__doc__,
7597"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007598Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007599
7600static PyObject*
7601vms_urandom(PyObject *self, PyObject *args)
7602{
Victor Stinner8c62be82010-05-06 00:08:46 +00007603 int howMany;
7604 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007605
Victor Stinner8c62be82010-05-06 00:08:46 +00007606 /* Read arguments */
7607 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7608 return NULL;
7609 if (howMany < 0)
7610 return PyErr_Format(PyExc_ValueError,
7611 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007612
Victor Stinner8c62be82010-05-06 00:08:46 +00007613 /* Allocate bytes */
7614 result = PyBytes_FromStringAndSize(NULL, howMany);
7615 if (result != NULL) {
7616 /* Get random data */
7617 if (RAND_pseudo_bytes((unsigned char*)
7618 PyBytes_AS_STRING(result),
7619 howMany) < 0) {
7620 Py_DECREF(result);
7621 return PyErr_Format(PyExc_ValueError,
7622 "RAND_pseudo_bytes");
7623 }
7624 }
7625 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007626}
7627#endif
7628
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007629#ifdef HAVE_SETRESUID
7630PyDoc_STRVAR(posix_setresuid__doc__,
7631"setresuid(ruid, euid, suid)\n\n\
7632Set the current process's real, effective, and saved user ids.");
7633
7634static PyObject*
7635posix_setresuid (PyObject *self, PyObject *args)
7636{
Victor Stinner8c62be82010-05-06 00:08:46 +00007637 /* We assume uid_t is no larger than a long. */
7638 long ruid, euid, suid;
7639 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
7640 return NULL;
7641 if (setresuid(ruid, euid, suid) < 0)
7642 return posix_error();
7643 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007644}
7645#endif
7646
7647#ifdef HAVE_SETRESGID
7648PyDoc_STRVAR(posix_setresgid__doc__,
7649"setresgid(rgid, egid, sgid)\n\n\
7650Set the current process's real, effective, and saved group ids.");
7651
7652static PyObject*
7653posix_setresgid (PyObject *self, PyObject *args)
7654{
Victor Stinner8c62be82010-05-06 00:08:46 +00007655 /* We assume uid_t is no larger than a long. */
7656 long rgid, egid, sgid;
7657 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
7658 return NULL;
7659 if (setresgid(rgid, egid, sgid) < 0)
7660 return posix_error();
7661 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007662}
7663#endif
7664
7665#ifdef HAVE_GETRESUID
7666PyDoc_STRVAR(posix_getresuid__doc__,
7667"getresuid() -> (ruid, euid, suid)\n\n\
7668Get tuple of the current process's real, effective, and saved user ids.");
7669
7670static PyObject*
7671posix_getresuid (PyObject *self, PyObject *noargs)
7672{
Victor Stinner8c62be82010-05-06 00:08:46 +00007673 uid_t ruid, euid, suid;
7674 long l_ruid, l_euid, l_suid;
7675 if (getresuid(&ruid, &euid, &suid) < 0)
7676 return posix_error();
7677 /* Force the values into long's as we don't know the size of uid_t. */
7678 l_ruid = ruid;
7679 l_euid = euid;
7680 l_suid = suid;
7681 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007682}
7683#endif
7684
7685#ifdef HAVE_GETRESGID
7686PyDoc_STRVAR(posix_getresgid__doc__,
7687"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00007688Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007689
7690static PyObject*
7691posix_getresgid (PyObject *self, PyObject *noargs)
7692{
Victor Stinner8c62be82010-05-06 00:08:46 +00007693 uid_t rgid, egid, sgid;
7694 long l_rgid, l_egid, l_sgid;
7695 if (getresgid(&rgid, &egid, &sgid) < 0)
7696 return posix_error();
7697 /* Force the values into long's as we don't know the size of uid_t. */
7698 l_rgid = rgid;
7699 l_egid = egid;
7700 l_sgid = sgid;
7701 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007702}
7703#endif
7704
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007705static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00007706 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007707#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007708 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007709#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007710 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007711#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007712 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007713#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007714 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007715#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007716 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007717#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007718#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007719 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007720#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00007721#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007722 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007723#endif /* HAVE_LCHMOD */
7724#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007725 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007726#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00007727#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007728 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007729#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007730#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007731 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007732#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007733#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +00007734 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00007735#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007736#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +00007737 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007738#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007739#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +00007740 {"getcwd", (PyCFunction)posix_getcwd_unicode,
7741 METH_NOARGS, posix_getcwd__doc__},
7742 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
7743 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007744#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007745#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007746 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007747#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +00007748 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7749 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7750 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007751#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +00007752 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007753#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007754#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007755 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007756#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007757#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007758 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007759#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007760 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7761 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7762 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +00007763 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007764#ifdef HAVE_SYMLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007765 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007766#endif /* HAVE_SYMLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007767#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin74e45612010-07-09 15:58:59 +00007768 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
7769 win_symlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007770#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007771#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +00007772 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007773#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007774 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007775#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007776 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007777#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +00007778 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7779 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7780 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007781#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00007782 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007783#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00007784 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007785#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +00007786 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7787 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007788#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007789#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +00007790 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7791 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007792#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00007793 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7794 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007795#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007796#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007797#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +00007798 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007799#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007800#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +00007801 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007802#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007803#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +00007804 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007805#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007806#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007807 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007808#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007809#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007810 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007811#endif /* HAVE_GETEGID */
7812#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007813 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007814#endif /* HAVE_GETEUID */
7815#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007816 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007817#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007818#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007819 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007820#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007821 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007822#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007823 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007824#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007825#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +00007826 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007827#endif /* HAVE_GETPPID */
7828#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007829 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007830#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007831#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007832 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007833#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007834#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +00007835 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007836#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007837#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +00007838 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007839#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007840#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007841 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007842#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007843#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007844 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7845 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Brian Curtin1b9df392010-11-24 20:24:31 +00007846 {"link", win32_link, METH_VARARGS, win32_link__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +00007847#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007848#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007849 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007850#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007851#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007852 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007853#endif /* HAVE_SETEUID */
7854#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007855 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007856#endif /* HAVE_SETEGID */
7857#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007858 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007859#endif /* HAVE_SETREUID */
7860#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007861 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007862#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007863#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007864 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007865#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007866#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007867 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007868#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +00007869#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007870 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +00007871#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007872#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007873 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00007874#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007875#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007876 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007877#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007878#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007879 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007880#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007881#ifdef HAVE_WAIT3
Victor Stinner8c62be82010-05-06 00:08:46 +00007882 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007883#endif /* HAVE_WAIT3 */
7884#ifdef HAVE_WAIT4
Victor Stinner8c62be82010-05-06 00:08:46 +00007885 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007886#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007887#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007888 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007889#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007890#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007891 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007892#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007893#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007894 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007895#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007896#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007897 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007898#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007899#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007900 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007901#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007902#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007903 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007904#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +00007905 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7906 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7907 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
7908 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
7909 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7910 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7911 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7912 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7913 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7914 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7915 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007916#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +00007917 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007918#endif
7919#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +00007920 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007921#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007922#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +00007923 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007924#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007925#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +00007926 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7927 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7928 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007929#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007930#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +00007931 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007932#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007933#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007934 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007935#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007936#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007937 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00007938#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007939 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007940#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +00007941 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007942#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007943#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007944 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007945#endif
7946#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007947 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007948#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007949#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007950#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +00007951 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00007952#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007953#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00007954 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007955#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007956#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +00007957 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007958#endif /* WIFSTOPPED */
7959#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +00007960 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007961#endif /* WIFSIGNALED */
7962#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +00007963 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007964#endif /* WIFEXITED */
7965#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +00007966 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007967#endif /* WEXITSTATUS */
7968#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007969 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007970#endif /* WTERMSIG */
7971#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007972 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007973#endif /* WSTOPSIG */
7974#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007975#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007976 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007977#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007978#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007979 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007980#endif
Fred Drakec9680921999-12-13 16:37:25 +00007981#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +00007982 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007983#endif
7984#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007985 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007986#endif
7987#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007988 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007989#endif
7990#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007991 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007992#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007993 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007994#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007995 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +00007996 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +00007997 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Mark Hammondef8b6542001-05-13 08:04:26 +00007998#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007999#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +00008000 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008001#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008002 #ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008003 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008004 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008005 #ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008006 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008007 #endif
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008008#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008009 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008010#endif
8011#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008012 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008013#endif
8014#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008015 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008016#endif
8017#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008018 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008019#endif
8020
Victor Stinner8c62be82010-05-06 00:08:46 +00008021 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008022};
8023
8024
Barry Warsaw4a342091996-12-19 23:50:02 +00008025static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008026ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008027{
Victor Stinner8c62be82010-05-06 00:08:46 +00008028 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008029}
8030
Guido van Rossumd48f2521997-12-05 22:19:34 +00008031#if defined(PYOS_OS2)
8032/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008033static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008034{
8035 APIRET rc;
8036 ULONG values[QSV_MAX+1];
8037 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008038 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008039
8040 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008041 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008042 Py_END_ALLOW_THREADS
8043
8044 if (rc != NO_ERROR) {
8045 os2_error(rc);
8046 return -1;
8047 }
8048
Fred Drake4d1e64b2002-04-15 19:40:07 +00008049 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8050 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8051 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8052 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8053 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8054 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8055 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008056
8057 switch (values[QSV_VERSION_MINOR]) {
8058 case 0: ver = "2.00"; break;
8059 case 10: ver = "2.10"; break;
8060 case 11: ver = "2.11"; break;
8061 case 30: ver = "3.00"; break;
8062 case 40: ver = "4.00"; break;
8063 case 50: ver = "5.00"; break;
8064 default:
Tim Peters885d4572001-11-28 20:27:42 +00008065 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +00008066 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00008067 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008068 ver = &tmp[0];
8069 }
8070
8071 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008072 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008073 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008074
8075 /* Add Indicator of Which Drive was Used to Boot the System */
8076 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8077 tmp[1] = ':';
8078 tmp[2] = '\0';
8079
Fred Drake4d1e64b2002-04-15 19:40:07 +00008080 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008081}
8082#endif
8083
Barry Warsaw4a342091996-12-19 23:50:02 +00008084static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008085all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008086{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008087#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008088 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008089#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008090#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008091 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008092#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008093#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008094 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008095#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008096#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008097 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008098#endif
Fred Drakec9680921999-12-13 16:37:25 +00008099#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008100 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00008101#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008102#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008103 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008104#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008105#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00008106 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008107#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008108#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +00008109 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008110#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008111#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +00008112 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008113#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008114#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008115 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008116#endif
8117#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008118 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008119#endif
8120#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +00008121 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008122#endif
8123#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +00008124 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008125#endif
8126#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008127 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008128#endif
8129#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +00008130 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008131#endif
8132#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008133 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008134#endif
8135#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008136 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008137#endif
8138#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008139 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008140#endif
8141#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +00008142 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008143#endif
8144#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008145 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008146#endif
8147#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +00008148 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008149#endif
8150#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008151 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008152#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008153#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008154 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008155#endif
8156#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +00008157 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008158#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008159#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008160 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008161#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008162#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008163 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008164#endif
8165#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008166 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008167#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008168
Tim Peters5aa91602002-01-30 05:46:57 +00008169/* MS Windows */
8170#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008171 /* Don't inherit in child processes. */
8172 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008173#endif
8174#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +00008175 /* Optimize for short life (keep in memory). */
8176 /* MS forgot to define this one with a non-underscore form too. */
8177 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008178#endif
8179#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008180 /* Automatically delete when last handle is closed. */
8181 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008182#endif
8183#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +00008184 /* Optimize for random access. */
8185 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008186#endif
8187#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008188 /* Optimize for sequential access. */
8189 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008190#endif
8191
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008192/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008193#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008194 /* Send a SIGIO signal whenever input or output
8195 becomes available on file descriptor */
8196 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008197#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008198#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008199 /* Direct disk access. */
8200 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008201#endif
8202#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +00008203 /* Must be a directory. */
8204 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008205#endif
8206#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +00008207 /* Do not follow links. */
8208 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008209#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008210#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +00008211 /* Do not update the access time. */
8212 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008213#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008214
Victor Stinner8c62be82010-05-06 00:08:46 +00008215 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008216#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008217 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008218#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008219#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008220 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008221#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008222#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008223 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008224#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008225#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008226 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008227#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008228#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +00008229 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008230#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008231#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +00008232 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008233#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008234#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008235 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008236#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008237#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +00008238 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008239#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008240#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008241 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008242#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008243#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008244 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008245#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008246#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008247 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008248#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008249#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008250 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008251#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008252#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +00008253 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008254#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008255#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +00008256 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008257#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008258#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008259 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008260#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008261#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008262 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008263#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008264#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +00008265 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008266#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008267
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008268 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008269#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008270 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008271#endif /* ST_RDONLY */
8272#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008273 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008274#endif /* ST_NOSUID */
8275
Guido van Rossum246bc171999-02-01 23:54:31 +00008276#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008277#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00008278 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8279 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8280 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8281 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8282 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8283 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8284 if (ins(d, "P_PM", (long)P_PM)) return -1;
8285 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8286 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8287 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8288 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8289 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8290 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8291 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8292 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8293 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8294 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8295 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8296 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8297 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008298#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008299 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8300 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8301 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8302 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8303 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008304#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008305#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008306
Guido van Rossumd48f2521997-12-05 22:19:34 +00008307#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00008308 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008309#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008310 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00008311}
8312
8313
Tim Peters5aa91602002-01-30 05:46:57 +00008314#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008315#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008316#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008317
8318#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008319#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008320#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008321
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008322#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00008323#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008324#define MODNAME "posix"
8325#endif
8326
Martin v. Löwis1a214512008-06-11 05:26:20 +00008327static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +00008328 PyModuleDef_HEAD_INIT,
8329 MODNAME,
8330 posix__doc__,
8331 -1,
8332 posix_methods,
8333 NULL,
8334 NULL,
8335 NULL,
8336 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00008337};
8338
8339
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008340PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008341INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008342{
Victor Stinner8c62be82010-05-06 00:08:46 +00008343 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008344
Victor Stinner8c62be82010-05-06 00:08:46 +00008345 m = PyModule_Create(&posixmodule);
8346 if (m == NULL)
8347 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008348
Victor Stinner8c62be82010-05-06 00:08:46 +00008349 /* Initialize environ dictionary */
8350 v = convertenviron();
8351 Py_XINCREF(v);
8352 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
8353 return NULL;
8354 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008355
Victor Stinner8c62be82010-05-06 00:08:46 +00008356 if (all_ins(m))
8357 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00008358
Victor Stinner8c62be82010-05-06 00:08:46 +00008359 if (setup_confname_tables(m))
8360 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00008361
Victor Stinner8c62be82010-05-06 00:08:46 +00008362 Py_INCREF(PyExc_OSError);
8363 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008364
Guido van Rossumb3d39562000-01-31 18:41:26 +00008365#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00008366 if (posix_putenv_garbage == NULL)
8367 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008368#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008369
Victor Stinner8c62be82010-05-06 00:08:46 +00008370 if (!initialized) {
8371 stat_result_desc.name = MODNAME ".stat_result";
8372 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8373 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8374 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8375 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8376 structseq_new = StatResultType.tp_new;
8377 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008378
Victor Stinner8c62be82010-05-06 00:08:46 +00008379 statvfs_result_desc.name = MODNAME ".statvfs_result";
8380 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008381#ifdef NEED_TICKS_PER_SECOND
8382# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +00008383 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008384# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +00008385 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008386# else
Victor Stinner8c62be82010-05-06 00:08:46 +00008387 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008388# endif
8389#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008390 }
8391 Py_INCREF((PyObject*) &StatResultType);
8392 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
8393 Py_INCREF((PyObject*) &StatVFSResultType);
8394 PyModule_AddObject(m, "statvfs_result",
8395 (PyObject*) &StatVFSResultType);
8396 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008397
8398#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +00008399 /*
8400 * Step 2 of weak-linking support on Mac OS X.
8401 *
8402 * The code below removes functions that are not available on the
8403 * currently active platform.
8404 *
8405 * This block allow one to use a python binary that was build on
8406 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8407 * OSX 10.4.
8408 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008409#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008410 if (fstatvfs == NULL) {
8411 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8412 return NULL;
8413 }
8414 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008415#endif /* HAVE_FSTATVFS */
8416
8417#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008418 if (statvfs == NULL) {
8419 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8420 return NULL;
8421 }
8422 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008423#endif /* HAVE_STATVFS */
8424
8425# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00008426 if (lchown == NULL) {
8427 if (PyObject_DelAttrString(m, "lchown") == -1) {
8428 return NULL;
8429 }
8430 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008431#endif /* HAVE_LCHOWN */
8432
8433
8434#endif /* __APPLE__ */
Victor Stinner8c62be82010-05-06 00:08:46 +00008435 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008436
Guido van Rossumb6775db1994-08-01 11:34:53 +00008437}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008438
8439#ifdef __cplusplus
8440}
8441#endif