blob: 48dbaa515c41937644b952df76a05771f6bd5502 [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
Brian Curtinfc889c42010-11-28 23:59:46 +00002255 PyUnicodeObject *usrc, *udst;
2256 if (PyArg_ParseTuple(args, "UU:link", &usrc, &udst)) {
2257 Py_BEGIN_ALLOW_THREADS
2258 rslt = CreateHardLinkW(PyUnicode_AS_UNICODE(udst),
2259 PyUnicode_AS_UNICODE(usrc), NULL);
2260 Py_END_ALLOW_THREADS
2261
2262 if (rslt == 0)
2263 return win32_error("link", NULL);
2264
2265 Py_RETURN_NONE;
2266 }
2267
2268 /* Narrow strings also valid. */
2269 PyErr_Clear();
2270
Brian Curtin1b9df392010-11-24 20:24:31 +00002271 if (!PyArg_ParseTuple(args, "O&O&:link", PyUnicode_FSConverter, &osrc,
2272 PyUnicode_FSConverter, &odst))
2273 return NULL;
2274
2275 src = PyBytes_AsString(osrc);
2276 dst = PyBytes_AsString(odst);
2277
2278 Py_BEGIN_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00002279 rslt = CreateHardLinkA(dst, src, NULL);
Brian Curtin1b9df392010-11-24 20:24:31 +00002280 Py_END_ALLOW_THREADS
2281
Stefan Krah30b341f2010-11-27 11:44:18 +00002282 Py_DECREF(osrc);
2283 Py_DECREF(odst);
Brian Curtin1b9df392010-11-24 20:24:31 +00002284 if (rslt == 0)
Brian Curtinfc889c42010-11-28 23:59:46 +00002285 return win32_error("link", NULL);
Brian Curtin1b9df392010-11-24 20:24:31 +00002286
2287 Py_RETURN_NONE;
2288}
2289#endif /* MS_WINDOWS */
2290
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002291
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002292PyDoc_STRVAR(posix_listdir__doc__,
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002293"listdir([path]) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002294Return a list containing the names of the entries in the directory.\n\
2295\n\
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002296 path: path of directory to list (default: '.')\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002297\n\
2298The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002299entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002300
Barry Warsaw53699e91996-12-10 23:23:01 +00002301static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002302posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002303{
Victor Stinner8c62be82010-05-06 00:08:46 +00002304 /* XXX Should redo this putting the (now four) versions of opendir
2305 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002306#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002307
Victor Stinner8c62be82010-05-06 00:08:46 +00002308 PyObject *d, *v;
2309 HANDLE hFindFile;
2310 BOOL result;
2311 WIN32_FIND_DATA FileData;
2312 PyObject *opath;
2313 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2314 char *bufptr = namebuf;
2315 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002316
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002317 PyObject *po = NULL;
2318 if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002319 WIN32_FIND_DATAW wFileData;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002320 Py_UNICODE *wnamebuf, *po_wchars;
2321
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002322 if (po == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002323 po_wchars = L".";
2324 len = 1;
2325 } else {
2326 po_wchars = PyUnicode_AS_UNICODE(po);
2327 len = PyUnicode_GET_SIZE(po);
2328 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002329 /* Overallocate for \\*.*\0 */
Victor Stinner8c62be82010-05-06 00:08:46 +00002330 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2331 if (!wnamebuf) {
2332 PyErr_NoMemory();
2333 return NULL;
2334 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002335 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00002336 if (len > 0) {
2337 Py_UNICODE wch = wnamebuf[len-1];
2338 if (wch != L'/' && wch != L'\\' && wch != L':')
2339 wnamebuf[len++] = L'\\';
2340 wcscpy(wnamebuf + len, L"*.*");
2341 }
2342 if ((d = PyList_New(0)) == NULL) {
2343 free(wnamebuf);
2344 return NULL;
2345 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00002346 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002347 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002348 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002349 if (hFindFile == INVALID_HANDLE_VALUE) {
2350 int error = GetLastError();
2351 if (error == ERROR_FILE_NOT_FOUND) {
2352 free(wnamebuf);
2353 return d;
2354 }
2355 Py_DECREF(d);
2356 win32_error_unicode("FindFirstFileW", wnamebuf);
2357 free(wnamebuf);
2358 return NULL;
2359 }
2360 do {
2361 /* Skip over . and .. */
2362 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2363 wcscmp(wFileData.cFileName, L"..") != 0) {
2364 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2365 if (v == NULL) {
2366 Py_DECREF(d);
2367 d = NULL;
2368 break;
2369 }
2370 if (PyList_Append(d, v) != 0) {
2371 Py_DECREF(v);
2372 Py_DECREF(d);
2373 d = NULL;
2374 break;
2375 }
2376 Py_DECREF(v);
2377 }
2378 Py_BEGIN_ALLOW_THREADS
2379 result = FindNextFileW(hFindFile, &wFileData);
2380 Py_END_ALLOW_THREADS
2381 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2382 it got to the end of the directory. */
2383 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2384 Py_DECREF(d);
2385 win32_error_unicode("FindNextFileW", wnamebuf);
2386 FindClose(hFindFile);
2387 free(wnamebuf);
2388 return NULL;
2389 }
2390 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002391
Victor Stinner8c62be82010-05-06 00:08:46 +00002392 if (FindClose(hFindFile) == FALSE) {
2393 Py_DECREF(d);
2394 win32_error_unicode("FindClose", wnamebuf);
2395 free(wnamebuf);
2396 return NULL;
2397 }
2398 free(wnamebuf);
2399 return d;
2400 }
2401 /* Drop the argument parsing error as narrow strings
2402 are also valid. */
2403 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002404
Victor Stinner8c62be82010-05-06 00:08:46 +00002405 if (!PyArg_ParseTuple(args, "O&:listdir",
2406 PyUnicode_FSConverter, &opath))
2407 return NULL;
2408 if (PyBytes_GET_SIZE(opath)+1 > MAX_PATH) {
2409 PyErr_SetString(PyExc_ValueError, "path too long");
2410 Py_DECREF(opath);
2411 return NULL;
2412 }
2413 strcpy(namebuf, PyBytes_AsString(opath));
2414 len = PyObject_Size(opath);
Stefan Krah2a7feee2010-11-27 22:06:49 +00002415 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00002416 if (len > 0) {
2417 char ch = namebuf[len-1];
2418 if (ch != SEP && ch != ALTSEP && ch != ':')
2419 namebuf[len++] = '/';
2420 strcpy(namebuf + len, "*.*");
2421 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002422
Victor Stinner8c62be82010-05-06 00:08:46 +00002423 if ((d = PyList_New(0)) == NULL)
2424 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002425
Antoine Pitroub73caab2010-08-09 23:39:31 +00002426 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002427 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002428 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002429 if (hFindFile == INVALID_HANDLE_VALUE) {
2430 int error = GetLastError();
2431 if (error == ERROR_FILE_NOT_FOUND)
2432 return d;
2433 Py_DECREF(d);
2434 return win32_error("FindFirstFile", namebuf);
2435 }
2436 do {
2437 /* Skip over . and .. */
2438 if (strcmp(FileData.cFileName, ".") != 0 &&
2439 strcmp(FileData.cFileName, "..") != 0) {
2440 v = PyBytes_FromString(FileData.cFileName);
2441 if (v == NULL) {
2442 Py_DECREF(d);
2443 d = NULL;
2444 break;
2445 }
2446 if (PyList_Append(d, v) != 0) {
2447 Py_DECREF(v);
2448 Py_DECREF(d);
2449 d = NULL;
2450 break;
2451 }
2452 Py_DECREF(v);
2453 }
2454 Py_BEGIN_ALLOW_THREADS
2455 result = FindNextFile(hFindFile, &FileData);
2456 Py_END_ALLOW_THREADS
2457 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2458 it got to the end of the directory. */
2459 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2460 Py_DECREF(d);
2461 win32_error("FindNextFile", namebuf);
2462 FindClose(hFindFile);
2463 return NULL;
2464 }
2465 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002466
Victor Stinner8c62be82010-05-06 00:08:46 +00002467 if (FindClose(hFindFile) == FALSE) {
2468 Py_DECREF(d);
2469 return win32_error("FindClose", namebuf);
2470 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002471
Victor Stinner8c62be82010-05-06 00:08:46 +00002472 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002473
Tim Peters0bb44a42000-09-15 07:44:49 +00002474#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002475
2476#ifndef MAX_PATH
2477#define MAX_PATH CCHMAXPATH
2478#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002479 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002480 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002481 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002482 PyObject *d, *v;
2483 char namebuf[MAX_PATH+5];
2484 HDIR hdir = 1;
2485 ULONG srchcnt = 1;
2486 FILEFINDBUF3 ep;
2487 APIRET rc;
2488
Victor Stinner8c62be82010-05-06 00:08:46 +00002489 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002490 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002491 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002492 name = PyBytes_AsString(oname);
2493 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002494 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002495 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002496 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002497 return NULL;
2498 }
2499 strcpy(namebuf, name);
2500 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002501 if (*pt == ALTSEP)
2502 *pt = SEP;
2503 if (namebuf[len-1] != SEP)
2504 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002505 strcpy(namebuf + len, "*.*");
2506
Neal Norwitz6c913782007-10-14 03:23:09 +00002507 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002508 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002509 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002510 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002511
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002512 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2513 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002514 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002515 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2516 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2517 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002518
2519 if (rc != NO_ERROR) {
2520 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002521 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002522 }
2523
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002524 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002525 do {
2526 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002527 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002528 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002529
2530 strcpy(namebuf, ep.achName);
2531
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002532 /* Leave Case of Name Alone -- In Native Form */
2533 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002534
Christian Heimes72b710a2008-05-26 13:28:38 +00002535 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002536 if (v == NULL) {
2537 Py_DECREF(d);
2538 d = NULL;
2539 break;
2540 }
2541 if (PyList_Append(d, v) != 0) {
2542 Py_DECREF(v);
2543 Py_DECREF(d);
2544 d = NULL;
2545 break;
2546 }
2547 Py_DECREF(v);
2548 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2549 }
2550
Victor Stinnerdcb24032010-04-22 12:08:36 +00002551 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002552 return d;
2553#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002554 PyObject *oname;
2555 char *name;
2556 PyObject *d, *v;
2557 DIR *dirp;
2558 struct dirent *ep;
2559 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002560
Victor Stinner8c62be82010-05-06 00:08:46 +00002561 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002562 /* v is never read, so it does not need to be initialized yet. */
2563 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002564 arg_is_unicode = 0;
2565 PyErr_Clear();
2566 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002567 oname = NULL;
2568 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
Victor Stinner8c62be82010-05-06 00:08:46 +00002569 return NULL;
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002570 if (oname == NULL) { /* Default arg: "." */
Stefan Krah0e803b32010-11-26 16:16:47 +00002571 oname = PyBytes_FromString(".");
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002572 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002573 name = PyBytes_AsString(oname);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002574 Py_BEGIN_ALLOW_THREADS
2575 dirp = opendir(name);
2576 Py_END_ALLOW_THREADS
2577 if (dirp == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002578 return posix_error_with_allocated_filename(oname);
2579 }
2580 if ((d = PyList_New(0)) == NULL) {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002581 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002582 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002583 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002584 Py_DECREF(oname);
2585 return NULL;
2586 }
2587 for (;;) {
2588 errno = 0;
2589 Py_BEGIN_ALLOW_THREADS
2590 ep = readdir(dirp);
2591 Py_END_ALLOW_THREADS
2592 if (ep == NULL) {
2593 if (errno == 0) {
2594 break;
2595 } else {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002596 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002597 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002598 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002599 Py_DECREF(d);
2600 return posix_error_with_allocated_filename(oname);
2601 }
2602 }
2603 if (ep->d_name[0] == '.' &&
2604 (NAMLEN(ep) == 1 ||
2605 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2606 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002607 if (arg_is_unicode)
2608 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2609 else
2610 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002611 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002612 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002613 break;
2614 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002615 if (PyList_Append(d, v) != 0) {
2616 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002617 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002618 break;
2619 }
2620 Py_DECREF(v);
2621 }
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002622 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002623 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002624 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002625 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002626
Victor Stinner8c62be82010-05-06 00:08:46 +00002627 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002628
Tim Peters0bb44a42000-09-15 07:44:49 +00002629#endif /* which OS */
2630} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002631
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002632#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002633/* A helper function for abspath on win32 */
2634static PyObject *
2635posix__getfullpathname(PyObject *self, PyObject *args)
2636{
Victor Stinner8c62be82010-05-06 00:08:46 +00002637 PyObject *opath;
2638 char *path;
2639 char outbuf[MAX_PATH*2];
2640 char *temp;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002641#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002642 PyUnicodeObject *po;
2643 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2644 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2645 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2646 Py_UNICODE *wtemp;
2647 DWORD result;
2648 PyObject *v;
2649 result = GetFullPathNameW(wpath,
2650 sizeof(woutbuf)/sizeof(woutbuf[0]),
2651 woutbuf, &wtemp);
2652 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2653 woutbufp = malloc(result * sizeof(Py_UNICODE));
2654 if (!woutbufp)
2655 return PyErr_NoMemory();
2656 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2657 }
2658 if (result)
2659 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2660 else
2661 v = win32_error_unicode("GetFullPathNameW", wpath);
2662 if (woutbufp != woutbuf)
2663 free(woutbufp);
2664 return v;
2665 }
2666 /* Drop the argument parsing error as narrow strings
2667 are also valid. */
2668 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002669
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002670#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002671 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2672 PyUnicode_FSConverter, &opath))
2673 return NULL;
2674 path = PyBytes_AsString(opath);
2675 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2676 outbuf, &temp)) {
2677 win32_error("GetFullPathName", path);
2678 Py_DECREF(opath);
2679 return NULL;
2680 }
2681 Py_DECREF(opath);
2682 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2683 return PyUnicode_Decode(outbuf, strlen(outbuf),
2684 Py_FileSystemDefaultEncoding, NULL);
2685 }
2686 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002687} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00002688
Brian Curtinf5e76d02010-11-24 13:14:05 +00002689/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
2690static int has_GetFinalPathNameByHandle = 0;
2691static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
2692 DWORD);
2693static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
2694 DWORD);
2695static int
2696check_GetFinalPathNameByHandle()
2697{
2698 HINSTANCE hKernel32;
2699 /* only recheck */
2700 if (!has_GetFinalPathNameByHandle)
2701 {
2702 hKernel32 = GetModuleHandle("KERNEL32");
2703 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
2704 "GetFinalPathNameByHandleA");
2705 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
2706 "GetFinalPathNameByHandleW");
2707 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
2708 Py_GetFinalPathNameByHandleW;
2709 }
2710 return has_GetFinalPathNameByHandle;
2711}
2712
Brian Curtind40e6f72010-07-08 21:39:08 +00002713/* A helper function for samepath on windows */
2714static PyObject *
2715posix__getfinalpathname(PyObject *self, PyObject *args)
2716{
2717 HANDLE hFile;
2718 int buf_size;
2719 wchar_t *target_path;
2720 int result_length;
2721 PyObject *result;
2722 wchar_t *path;
2723
Brian Curtin94622b02010-09-24 00:03:39 +00002724 if (!PyArg_ParseTuple(args, "u|:_getfinalpathname", &path)) {
Brian Curtind40e6f72010-07-08 21:39:08 +00002725 return NULL;
2726 }
2727
2728 if(!check_GetFinalPathNameByHandle()) {
2729 /* If the OS doesn't have GetFinalPathNameByHandle, return a
2730 NotImplementedError. */
2731 return PyErr_Format(PyExc_NotImplementedError,
2732 "GetFinalPathNameByHandle not available on this platform");
2733 }
2734
2735 hFile = CreateFileW(
2736 path,
2737 0, /* desired access */
2738 0, /* share mode */
2739 NULL, /* security attributes */
2740 OPEN_EXISTING,
2741 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
2742 FILE_FLAG_BACKUP_SEMANTICS,
2743 NULL);
2744
2745 if(hFile == INVALID_HANDLE_VALUE) {
2746 return win32_error_unicode("GetFinalPathNamyByHandle", path);
Brian Curtin74e45612010-07-09 15:58:59 +00002747 return PyErr_Format(PyExc_RuntimeError,
2748 "Could not get a handle to file.");
Brian Curtind40e6f72010-07-08 21:39:08 +00002749 }
2750
2751 /* We have a good handle to the target, use it to determine the
2752 target path name. */
2753 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
2754
2755 if(!buf_size)
2756 return win32_error_unicode("GetFinalPathNameByHandle", path);
2757
2758 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
2759 if(!target_path)
2760 return PyErr_NoMemory();
2761
2762 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
2763 buf_size, VOLUME_NAME_DOS);
2764 if(!result_length)
2765 return win32_error_unicode("GetFinalPathNamyByHandle", path);
2766
2767 if(!CloseHandle(hFile))
2768 return win32_error_unicode("GetFinalPathNameByHandle", path);
2769
2770 target_path[result_length] = 0;
2771 result = PyUnicode_FromUnicode(target_path, result_length);
2772 free(target_path);
2773 return result;
2774
2775} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00002776
2777static PyObject *
2778posix__getfileinformation(PyObject *self, PyObject *args)
2779{
2780 HANDLE hFile;
2781 BY_HANDLE_FILE_INFORMATION info;
2782 int fd;
2783
2784 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
2785 return NULL;
2786
2787 if (!_PyVerify_fd(fd)) {
2788 PyErr_SetString(PyExc_ValueError, "received invalid file descriptor");
2789 return NULL;
2790 }
2791
2792 hFile = (HANDLE)_get_osfhandle(fd);
2793 if (hFile == INVALID_HANDLE_VALUE)
2794 return win32_error("_getfileinformation", NULL);
2795
2796 if (!GetFileInformationByHandle(hFile, &info))
2797 return win32_error("_getfileinformation", NULL);
2798
2799 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
2800 info.nFileIndexHigh,
2801 info.nFileIndexLow);
2802}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002803#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002804
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002805PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002806"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002807Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002808
Barry Warsaw53699e91996-12-10 23:23:01 +00002809static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002810posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002811{
Victor Stinner8c62be82010-05-06 00:08:46 +00002812 int res;
2813 PyObject *opath;
2814 char *path;
2815 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002816
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002817#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002818 PyUnicodeObject *po;
2819 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2820 Py_BEGIN_ALLOW_THREADS
2821 /* PyUnicode_AS_UNICODE OK without thread lock as
2822 it is a simple dereference. */
2823 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2824 Py_END_ALLOW_THREADS
2825 if (!res)
2826 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2827 Py_INCREF(Py_None);
2828 return Py_None;
2829 }
2830 /* Drop the argument parsing error as narrow strings
2831 are also valid. */
2832 PyErr_Clear();
2833 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
2838 /* PyUnicode_AS_UNICODE OK without thread lock as
2839 it is a simple dereference. */
2840 res = CreateDirectoryA(path, NULL);
2841 Py_END_ALLOW_THREADS
2842 if (!res) {
2843 win32_error("mkdir", path);
2844 Py_DECREF(opath);
2845 return NULL;
2846 }
2847 Py_DECREF(opath);
2848 Py_INCREF(Py_None);
2849 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002850#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002851
Victor Stinner8c62be82010-05-06 00:08:46 +00002852 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2853 PyUnicode_FSConverter, &opath, &mode))
2854 return NULL;
2855 path = PyBytes_AsString(opath);
2856 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002857#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00002858 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002859#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002860 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002861#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002862 Py_END_ALLOW_THREADS
2863 if (res < 0)
2864 return posix_error_with_allocated_filename(opath);
2865 Py_DECREF(opath);
2866 Py_INCREF(Py_None);
2867 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002868#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002869}
2870
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002871
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002872/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2873#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002874#include <sys/resource.h>
2875#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002876
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002877
2878#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002879PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002880"nice(inc) -> new_priority\n\n\
2881Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002882
Barry Warsaw53699e91996-12-10 23:23:01 +00002883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002884posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002885{
Victor Stinner8c62be82010-05-06 00:08:46 +00002886 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002887
Victor Stinner8c62be82010-05-06 00:08:46 +00002888 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2889 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002890
Victor Stinner8c62be82010-05-06 00:08:46 +00002891 /* There are two flavours of 'nice': one that returns the new
2892 priority (as required by almost all standards out there) and the
2893 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2894 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002895
Victor Stinner8c62be82010-05-06 00:08:46 +00002896 If we are of the nice family that returns the new priority, we
2897 need to clear errno before the call, and check if errno is filled
2898 before calling posix_error() on a returnvalue of -1, because the
2899 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002900
Victor Stinner8c62be82010-05-06 00:08:46 +00002901 errno = 0;
2902 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002903#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00002904 if (value == 0)
2905 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002906#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002907 if (value == -1 && errno != 0)
2908 /* either nice() or getpriority() returned an error */
2909 return posix_error();
2910 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002911}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002912#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002913
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002914PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002915"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002916Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002917
Barry Warsaw53699e91996-12-10 23:23:01 +00002918static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002919posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002920{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002921#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002922 PyObject *o1, *o2;
2923 char *p1, *p2;
2924 BOOL result;
2925 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2926 goto error;
2927 if (!convert_to_unicode(&o1))
2928 goto error;
2929 if (!convert_to_unicode(&o2)) {
2930 Py_DECREF(o1);
2931 goto error;
2932 }
2933 Py_BEGIN_ALLOW_THREADS
2934 result = MoveFileW(PyUnicode_AsUnicode(o1),
2935 PyUnicode_AsUnicode(o2));
2936 Py_END_ALLOW_THREADS
2937 Py_DECREF(o1);
2938 Py_DECREF(o2);
2939 if (!result)
2940 return win32_error("rename", NULL);
2941 Py_INCREF(Py_None);
2942 return Py_None;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002943error:
Victor Stinner8c62be82010-05-06 00:08:46 +00002944 PyErr_Clear();
2945 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2946 return NULL;
2947 Py_BEGIN_ALLOW_THREADS
2948 result = MoveFileA(p1, p2);
2949 Py_END_ALLOW_THREADS
2950 if (!result)
2951 return win32_error("rename", NULL);
2952 Py_INCREF(Py_None);
2953 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002954#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002955 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002956#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002957}
2958
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002959
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002960PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002961"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002962Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002963
Barry Warsaw53699e91996-12-10 23:23:01 +00002964static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002965posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002966{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002967#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002968 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002969#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002970 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002971#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002972}
2973
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002974
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002975PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002976"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002977Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002978
Barry Warsaw53699e91996-12-10 23:23:01 +00002979static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002980posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002981{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002982#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00002983 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002984#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002985 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002986#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002987}
2988
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002989
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002990#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002991PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002992"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002993Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002994
Barry Warsaw53699e91996-12-10 23:23:01 +00002995static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002996posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002997{
Victor Stinner8c62be82010-05-06 00:08:46 +00002998 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002999#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003000 wchar_t *command;
3001 if (!PyArg_ParseTuple(args, "u:system", &command))
3002 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003003
Victor Stinner8c62be82010-05-06 00:08:46 +00003004 Py_BEGIN_ALLOW_THREADS
3005 sts = _wsystem(command);
3006 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00003007#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003008 PyObject *command_obj;
3009 char *command;
3010 if (!PyArg_ParseTuple(args, "O&:system",
3011 PyUnicode_FSConverter, &command_obj))
3012 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003013
Victor Stinner8c62be82010-05-06 00:08:46 +00003014 command = PyBytes_AsString(command_obj);
3015 Py_BEGIN_ALLOW_THREADS
3016 sts = system(command);
3017 Py_END_ALLOW_THREADS
3018 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00003019#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003020 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003021}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003022#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003023
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003024
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003025PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003026"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003027Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003028
Barry Warsaw53699e91996-12-10 23:23:01 +00003029static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003030posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003031{
Victor Stinner8c62be82010-05-06 00:08:46 +00003032 int i;
3033 if (!PyArg_ParseTuple(args, "i:umask", &i))
3034 return NULL;
3035 i = (int)umask(i);
3036 if (i < 0)
3037 return posix_error();
3038 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003039}
3040
Brian Curtind40e6f72010-07-08 21:39:08 +00003041#ifdef MS_WINDOWS
3042
3043/* override the default DeleteFileW behavior so that directory
3044symlinks can be removed with this function, the same as with
3045Unix symlinks */
3046BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
3047{
3048 WIN32_FILE_ATTRIBUTE_DATA info;
3049 WIN32_FIND_DATAW find_data;
3050 HANDLE find_data_handle;
3051 int is_directory = 0;
3052 int is_link = 0;
3053
3054 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3055 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
3056
3057 /* Get WIN32_FIND_DATA structure for the path to determine if
3058 it is a symlink */
3059 if(is_directory &&
3060 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3061 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3062
3063 if(find_data_handle != INVALID_HANDLE_VALUE) {
3064 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3065 FindClose(find_data_handle);
3066 }
3067 }
3068 }
3069
3070 if (is_directory && is_link)
3071 return RemoveDirectoryW(lpFileName);
3072
3073 return DeleteFileW(lpFileName);
3074}
3075#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003076
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003077PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003078"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003079Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003080
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003081PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003082"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003083Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003084
Barry Warsaw53699e91996-12-10 23:23:01 +00003085static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003086posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003087{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003088#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003089 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3090 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003091#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003092 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003093#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003094}
3095
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003096
Guido van Rossumb6775db1994-08-01 11:34:53 +00003097#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003098PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003099"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003100Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003101
Barry Warsaw53699e91996-12-10 23:23:01 +00003102static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003103posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003104{
Victor Stinner8c62be82010-05-06 00:08:46 +00003105 struct utsname u;
3106 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003107
Victor Stinner8c62be82010-05-06 00:08:46 +00003108 Py_BEGIN_ALLOW_THREADS
3109 res = uname(&u);
3110 Py_END_ALLOW_THREADS
3111 if (res < 0)
3112 return posix_error();
3113 return Py_BuildValue("(sssss)",
3114 u.sysname,
3115 u.nodename,
3116 u.release,
3117 u.version,
3118 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003119}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003120#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003121
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003122static int
3123extract_time(PyObject *t, long* sec, long* usec)
3124{
Victor Stinner8c62be82010-05-06 00:08:46 +00003125 long intval;
3126 if (PyFloat_Check(t)) {
3127 double tval = PyFloat_AsDouble(t);
3128 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
3129 if (!intobj)
3130 return -1;
3131 intval = PyLong_AsLong(intobj);
3132 Py_DECREF(intobj);
3133 if (intval == -1 && PyErr_Occurred())
3134 return -1;
3135 *sec = intval;
3136 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
3137 if (*usec < 0)
3138 /* If rounding gave us a negative number,
3139 truncate. */
3140 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00003141 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003142 }
3143 intval = PyLong_AsLong(t);
3144 if (intval == -1 && PyErr_Occurred())
3145 return -1;
3146 *sec = intval;
3147 *usec = 0;
3148 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003149}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003150
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003151PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00003152"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00003153utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00003154Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003155second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003156
Barry Warsaw53699e91996-12-10 23:23:01 +00003157static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003158posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003159{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003160#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003161 PyObject *arg;
3162 PyUnicodeObject *obwpath;
3163 wchar_t *wpath = NULL;
3164 PyObject *oapath;
3165 char *apath;
3166 HANDLE hFile;
3167 long atimesec, mtimesec, ausec, musec;
3168 FILETIME atime, mtime;
3169 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003170
Victor Stinner8c62be82010-05-06 00:08:46 +00003171 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
3172 wpath = PyUnicode_AS_UNICODE(obwpath);
3173 Py_BEGIN_ALLOW_THREADS
3174 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3175 NULL, OPEN_EXISTING,
3176 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3177 Py_END_ALLOW_THREADS
3178 if (hFile == INVALID_HANDLE_VALUE)
3179 return win32_error_unicode("utime", wpath);
3180 } else
3181 /* Drop the argument parsing error as narrow strings
3182 are also valid. */
3183 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003184
Victor Stinner8c62be82010-05-06 00:08:46 +00003185 if (!wpath) {
3186 if (!PyArg_ParseTuple(args, "O&O:utime",
3187 PyUnicode_FSConverter, &oapath, &arg))
3188 return NULL;
3189 apath = PyBytes_AsString(oapath);
3190 Py_BEGIN_ALLOW_THREADS
3191 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3192 NULL, OPEN_EXISTING,
3193 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3194 Py_END_ALLOW_THREADS
3195 if (hFile == INVALID_HANDLE_VALUE) {
3196 win32_error("utime", apath);
3197 Py_DECREF(oapath);
3198 return NULL;
3199 }
3200 Py_DECREF(oapath);
3201 }
3202
3203 if (arg == Py_None) {
3204 SYSTEMTIME now;
3205 GetSystemTime(&now);
3206 if (!SystemTimeToFileTime(&now, &mtime) ||
3207 !SystemTimeToFileTime(&now, &atime)) {
3208 win32_error("utime", NULL);
3209 goto done;
Stefan Krah0e803b32010-11-26 16:16:47 +00003210 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003211 }
3212 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3213 PyErr_SetString(PyExc_TypeError,
3214 "utime() arg 2 must be a tuple (atime, mtime)");
3215 goto done;
3216 }
3217 else {
3218 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3219 &atimesec, &ausec) == -1)
3220 goto done;
3221 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3222 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3223 &mtimesec, &musec) == -1)
3224 goto done;
3225 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3226 }
3227 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3228 /* Avoid putting the file name into the error here,
3229 as that may confuse the user into believing that
3230 something is wrong with the file, when it also
3231 could be the time stamp that gives a problem. */
3232 win32_error("utime", NULL);
3233 }
3234 Py_INCREF(Py_None);
3235 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003236done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003237 CloseHandle(hFile);
3238 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003239#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003240
Victor Stinner8c62be82010-05-06 00:08:46 +00003241 PyObject *opath;
3242 char *path;
3243 long atime, mtime, ausec, musec;
3244 int res;
3245 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003246
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003247#if defined(HAVE_UTIMES)
Victor Stinner8c62be82010-05-06 00:08:46 +00003248 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003249#define ATIME buf[0].tv_sec
3250#define MTIME buf[1].tv_sec
3251#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003252/* XXX should define struct utimbuf instead, above */
Victor Stinner8c62be82010-05-06 00:08:46 +00003253 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003254#define ATIME buf.actime
3255#define MTIME buf.modtime
3256#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003257#else /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003258 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003259#define ATIME buf[0]
3260#define MTIME buf[1]
3261#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003262#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003263
Mark Hammond817c9292003-12-03 01:22:38 +00003264
Victor Stinner8c62be82010-05-06 00:08:46 +00003265 if (!PyArg_ParseTuple(args, "O&O:utime",
3266 PyUnicode_FSConverter, &opath, &arg))
3267 return NULL;
3268 path = PyBytes_AsString(opath);
3269 if (arg == Py_None) {
3270 /* optional time values not given */
3271 Py_BEGIN_ALLOW_THREADS
3272 res = utime(path, NULL);
3273 Py_END_ALLOW_THREADS
3274 }
3275 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3276 PyErr_SetString(PyExc_TypeError,
3277 "utime() arg 2 must be a tuple (atime, mtime)");
3278 Py_DECREF(opath);
3279 return NULL;
3280 }
3281 else {
3282 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3283 &atime, &ausec) == -1) {
3284 Py_DECREF(opath);
3285 return NULL;
3286 }
3287 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3288 &mtime, &musec) == -1) {
3289 Py_DECREF(opath);
3290 return NULL;
3291 }
3292 ATIME = atime;
3293 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003294#ifdef HAVE_UTIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00003295 buf[0].tv_usec = ausec;
3296 buf[1].tv_usec = musec;
3297 Py_BEGIN_ALLOW_THREADS
3298 res = utimes(path, buf);
3299 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003300#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003301 Py_BEGIN_ALLOW_THREADS
3302 res = utime(path, UTIME_ARG);
3303 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003304#endif /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003305 }
3306 if (res < 0) {
3307 return posix_error_with_allocated_filename(opath);
3308 }
3309 Py_DECREF(opath);
3310 Py_INCREF(Py_None);
3311 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003312#undef UTIME_ARG
3313#undef ATIME
3314#undef MTIME
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003315#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003316}
3317
Guido van Rossum85e3b011991-06-03 12:42:10 +00003318
Guido van Rossum3b066191991-06-04 19:40:25 +00003319/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003320
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003321PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003322"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003323Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003324
Barry Warsaw53699e91996-12-10 23:23:01 +00003325static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003326posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003327{
Victor Stinner8c62be82010-05-06 00:08:46 +00003328 int sts;
3329 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3330 return NULL;
3331 _exit(sts);
3332 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003333}
3334
Martin v. Löwis114619e2002-10-07 06:44:21 +00003335#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3336static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003337free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003338{
Victor Stinner8c62be82010-05-06 00:08:46 +00003339 Py_ssize_t i;
3340 for (i = 0; i < count; i++)
3341 PyMem_Free(array[i]);
3342 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003343}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003344
Antoine Pitrou69f71142009-05-24 21:25:49 +00003345static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003346int fsconvert_strdup(PyObject *o, char**out)
3347{
Victor Stinner8c62be82010-05-06 00:08:46 +00003348 PyObject *bytes;
3349 Py_ssize_t size;
3350 if (!PyUnicode_FSConverter(o, &bytes))
3351 return 0;
3352 size = PyBytes_GET_SIZE(bytes);
3353 *out = PyMem_Malloc(size+1);
3354 if (!*out)
3355 return 0;
3356 memcpy(*out, PyBytes_AsString(bytes), size+1);
3357 Py_DECREF(bytes);
3358 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003359}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003360#endif
3361
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003362
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003363#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003364PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003365"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003366Execute an executable path with arguments, replacing current process.\n\
3367\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003368 path: path of executable file\n\
3369 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003370
Barry Warsaw53699e91996-12-10 23:23:01 +00003371static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003372posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003373{
Victor Stinner8c62be82010-05-06 00:08:46 +00003374 PyObject *opath;
3375 char *path;
3376 PyObject *argv;
3377 char **argvlist;
3378 Py_ssize_t i, argc;
3379 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003380
Victor Stinner8c62be82010-05-06 00:08:46 +00003381 /* execv has two arguments: (path, argv), where
3382 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003383
Victor Stinner8c62be82010-05-06 00:08:46 +00003384 if (!PyArg_ParseTuple(args, "O&O:execv",
3385 PyUnicode_FSConverter,
3386 &opath, &argv))
3387 return NULL;
3388 path = PyBytes_AsString(opath);
3389 if (PyList_Check(argv)) {
3390 argc = PyList_Size(argv);
3391 getitem = PyList_GetItem;
3392 }
3393 else if (PyTuple_Check(argv)) {
3394 argc = PyTuple_Size(argv);
3395 getitem = PyTuple_GetItem;
3396 }
3397 else {
3398 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3399 Py_DECREF(opath);
3400 return NULL;
3401 }
3402 if (argc < 1) {
3403 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3404 Py_DECREF(opath);
3405 return NULL;
3406 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003407
Victor Stinner8c62be82010-05-06 00:08:46 +00003408 argvlist = PyMem_NEW(char *, argc+1);
3409 if (argvlist == NULL) {
3410 Py_DECREF(opath);
3411 return PyErr_NoMemory();
3412 }
3413 for (i = 0; i < argc; i++) {
3414 if (!fsconvert_strdup((*getitem)(argv, i),
3415 &argvlist[i])) {
3416 free_string_array(argvlist, i);
3417 PyErr_SetString(PyExc_TypeError,
3418 "execv() arg 2 must contain only strings");
3419 Py_DECREF(opath);
3420 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003421
Victor Stinner8c62be82010-05-06 00:08:46 +00003422 }
3423 }
3424 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003425
Victor Stinner8c62be82010-05-06 00:08:46 +00003426 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003427
Victor Stinner8c62be82010-05-06 00:08:46 +00003428 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003429
Victor Stinner8c62be82010-05-06 00:08:46 +00003430 free_string_array(argvlist, argc);
3431 Py_DECREF(opath);
3432 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003433}
3434
Victor Stinner13bb71c2010-04-23 21:41:56 +00003435static char**
3436parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3437{
Victor Stinner8c62be82010-05-06 00:08:46 +00003438 char **envlist;
3439 Py_ssize_t i, pos, envc;
3440 PyObject *keys=NULL, *vals=NULL;
3441 PyObject *key, *val, *key2, *val2;
3442 char *p, *k, *v;
3443 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003444
Victor Stinner8c62be82010-05-06 00:08:46 +00003445 i = PyMapping_Size(env);
3446 if (i < 0)
3447 return NULL;
3448 envlist = PyMem_NEW(char *, i + 1);
3449 if (envlist == NULL) {
3450 PyErr_NoMemory();
3451 return NULL;
3452 }
3453 envc = 0;
3454 keys = PyMapping_Keys(env);
3455 vals = PyMapping_Values(env);
3456 if (!keys || !vals)
3457 goto error;
3458 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3459 PyErr_Format(PyExc_TypeError,
3460 "env.keys() or env.values() is not a list");
3461 goto error;
3462 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003463
Victor Stinner8c62be82010-05-06 00:08:46 +00003464 for (pos = 0; pos < i; pos++) {
3465 key = PyList_GetItem(keys, pos);
3466 val = PyList_GetItem(vals, pos);
3467 if (!key || !val)
3468 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003469
Victor Stinner8c62be82010-05-06 00:08:46 +00003470 if (PyUnicode_FSConverter(key, &key2) == 0)
3471 goto error;
3472 if (PyUnicode_FSConverter(val, &val2) == 0) {
3473 Py_DECREF(key2);
3474 goto error;
3475 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003476
3477#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003478 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3479 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00003480#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003481 k = PyBytes_AsString(key2);
3482 v = PyBytes_AsString(val2);
3483 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003484
Victor Stinner8c62be82010-05-06 00:08:46 +00003485 p = PyMem_NEW(char, len);
3486 if (p == NULL) {
3487 PyErr_NoMemory();
3488 Py_DECREF(key2);
3489 Py_DECREF(val2);
3490 goto error;
3491 }
3492 PyOS_snprintf(p, len, "%s=%s", k, v);
3493 envlist[envc++] = p;
3494 Py_DECREF(key2);
3495 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003496#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003497 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003498#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003499 }
3500 Py_DECREF(vals);
3501 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003502
Victor Stinner8c62be82010-05-06 00:08:46 +00003503 envlist[envc] = 0;
3504 *envc_ptr = envc;
3505 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003506
3507error:
Victor Stinner8c62be82010-05-06 00:08:46 +00003508 Py_XDECREF(keys);
3509 Py_XDECREF(vals);
3510 while (--envc >= 0)
3511 PyMem_DEL(envlist[envc]);
3512 PyMem_DEL(envlist);
3513 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003514}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003515
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003516PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003517"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003518Execute a path with arguments and environment, replacing current process.\n\
3519\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003520 path: path of executable file\n\
3521 args: tuple or list of arguments\n\
3522 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003523
Barry Warsaw53699e91996-12-10 23:23:01 +00003524static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003525posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003526{
Victor Stinner8c62be82010-05-06 00:08:46 +00003527 PyObject *opath;
3528 char *path;
3529 PyObject *argv, *env;
3530 char **argvlist;
3531 char **envlist;
3532 Py_ssize_t i, argc, envc;
3533 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3534 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003535
Victor Stinner8c62be82010-05-06 00:08:46 +00003536 /* execve has three arguments: (path, argv, env), where
3537 argv is a list or tuple of strings and env is a dictionary
3538 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003539
Victor Stinner8c62be82010-05-06 00:08:46 +00003540 if (!PyArg_ParseTuple(args, "O&OO:execve",
3541 PyUnicode_FSConverter,
3542 &opath, &argv, &env))
3543 return NULL;
3544 path = PyBytes_AsString(opath);
3545 if (PyList_Check(argv)) {
3546 argc = PyList_Size(argv);
3547 getitem = PyList_GetItem;
3548 }
3549 else if (PyTuple_Check(argv)) {
3550 argc = PyTuple_Size(argv);
3551 getitem = PyTuple_GetItem;
3552 }
3553 else {
3554 PyErr_SetString(PyExc_TypeError,
3555 "execve() arg 2 must be a tuple or list");
3556 goto fail_0;
3557 }
3558 if (!PyMapping_Check(env)) {
3559 PyErr_SetString(PyExc_TypeError,
3560 "execve() arg 3 must be a mapping object");
3561 goto fail_0;
3562 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003563
Victor Stinner8c62be82010-05-06 00:08:46 +00003564 argvlist = PyMem_NEW(char *, argc+1);
3565 if (argvlist == NULL) {
3566 PyErr_NoMemory();
3567 goto fail_0;
3568 }
3569 for (i = 0; i < argc; i++) {
3570 if (!fsconvert_strdup((*getitem)(argv, i),
3571 &argvlist[i]))
3572 {
3573 lastarg = i;
3574 goto fail_1;
3575 }
3576 }
3577 lastarg = argc;
3578 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003579
Victor Stinner8c62be82010-05-06 00:08:46 +00003580 envlist = parse_envlist(env, &envc);
3581 if (envlist == NULL)
3582 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003583
Victor Stinner8c62be82010-05-06 00:08:46 +00003584 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003585
Victor Stinner8c62be82010-05-06 00:08:46 +00003586 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003587
Victor Stinner8c62be82010-05-06 00:08:46 +00003588 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003589
Victor Stinner8c62be82010-05-06 00:08:46 +00003590 while (--envc >= 0)
3591 PyMem_DEL(envlist[envc]);
3592 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003593 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003594 free_string_array(argvlist, lastarg);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003595 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003596 Py_DECREF(opath);
3597 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003598}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003599#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003600
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003601
Guido van Rossuma1065681999-01-25 23:20:23 +00003602#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003603PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003604"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003605Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003606\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003607 mode: mode of process creation\n\
3608 path: path of executable file\n\
3609 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003610
3611static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003612posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003613{
Victor Stinner8c62be82010-05-06 00:08:46 +00003614 PyObject *opath;
3615 char *path;
3616 PyObject *argv;
3617 char **argvlist;
3618 int mode, i;
3619 Py_ssize_t argc;
3620 Py_intptr_t spawnval;
3621 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003622
Victor Stinner8c62be82010-05-06 00:08:46 +00003623 /* spawnv has three arguments: (mode, path, argv), where
3624 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003625
Victor Stinner8c62be82010-05-06 00:08:46 +00003626 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3627 PyUnicode_FSConverter,
3628 &opath, &argv))
3629 return NULL;
3630 path = PyBytes_AsString(opath);
3631 if (PyList_Check(argv)) {
3632 argc = PyList_Size(argv);
3633 getitem = PyList_GetItem;
3634 }
3635 else if (PyTuple_Check(argv)) {
3636 argc = PyTuple_Size(argv);
3637 getitem = PyTuple_GetItem;
3638 }
3639 else {
3640 PyErr_SetString(PyExc_TypeError,
3641 "spawnv() arg 2 must be a tuple or list");
3642 Py_DECREF(opath);
3643 return NULL;
3644 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003645
Victor Stinner8c62be82010-05-06 00:08:46 +00003646 argvlist = PyMem_NEW(char *, argc+1);
3647 if (argvlist == NULL) {
3648 Py_DECREF(opath);
3649 return PyErr_NoMemory();
3650 }
3651 for (i = 0; i < argc; i++) {
3652 if (!fsconvert_strdup((*getitem)(argv, i),
3653 &argvlist[i])) {
3654 free_string_array(argvlist, i);
3655 PyErr_SetString(
3656 PyExc_TypeError,
3657 "spawnv() arg 2 must contain only strings");
3658 Py_DECREF(opath);
3659 return NULL;
3660 }
3661 }
3662 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003663
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003664#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003665 Py_BEGIN_ALLOW_THREADS
3666 spawnval = spawnv(mode, path, argvlist);
3667 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003668#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003669 if (mode == _OLD_P_OVERLAY)
3670 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003671
Victor Stinner8c62be82010-05-06 00:08:46 +00003672 Py_BEGIN_ALLOW_THREADS
3673 spawnval = _spawnv(mode, path, argvlist);
3674 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003675#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003676
Victor Stinner8c62be82010-05-06 00:08:46 +00003677 free_string_array(argvlist, argc);
3678 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003679
Victor Stinner8c62be82010-05-06 00:08:46 +00003680 if (spawnval == -1)
3681 return posix_error();
3682 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003683#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003684 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003685#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003686 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003687#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003688}
3689
3690
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003691PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003692"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003693Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003694\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003695 mode: mode of process creation\n\
3696 path: path of executable file\n\
3697 args: tuple or list of arguments\n\
3698 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003699
3700static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003701posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003702{
Victor Stinner8c62be82010-05-06 00:08:46 +00003703 PyObject *opath;
3704 char *path;
3705 PyObject *argv, *env;
3706 char **argvlist;
3707 char **envlist;
3708 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003709 int mode;
3710 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003711 Py_intptr_t spawnval;
3712 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3713 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003714
Victor Stinner8c62be82010-05-06 00:08:46 +00003715 /* spawnve has four arguments: (mode, path, argv, env), where
3716 argv is a list or tuple of strings and env is a dictionary
3717 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003718
Victor Stinner8c62be82010-05-06 00:08:46 +00003719 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3720 PyUnicode_FSConverter,
3721 &opath, &argv, &env))
3722 return NULL;
3723 path = PyBytes_AsString(opath);
3724 if (PyList_Check(argv)) {
3725 argc = PyList_Size(argv);
3726 getitem = PyList_GetItem;
3727 }
3728 else if (PyTuple_Check(argv)) {
3729 argc = PyTuple_Size(argv);
3730 getitem = PyTuple_GetItem;
3731 }
3732 else {
3733 PyErr_SetString(PyExc_TypeError,
3734 "spawnve() arg 2 must be a tuple or list");
3735 goto fail_0;
3736 }
3737 if (!PyMapping_Check(env)) {
3738 PyErr_SetString(PyExc_TypeError,
3739 "spawnve() arg 3 must be a mapping object");
3740 goto fail_0;
3741 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003742
Victor Stinner8c62be82010-05-06 00:08:46 +00003743 argvlist = PyMem_NEW(char *, argc+1);
3744 if (argvlist == NULL) {
3745 PyErr_NoMemory();
3746 goto fail_0;
3747 }
3748 for (i = 0; i < argc; i++) {
3749 if (!fsconvert_strdup((*getitem)(argv, i),
3750 &argvlist[i]))
3751 {
3752 lastarg = i;
3753 goto fail_1;
3754 }
3755 }
3756 lastarg = argc;
3757 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003758
Victor Stinner8c62be82010-05-06 00:08:46 +00003759 envlist = parse_envlist(env, &envc);
3760 if (envlist == NULL)
3761 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003762
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003763#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003764 Py_BEGIN_ALLOW_THREADS
3765 spawnval = spawnve(mode, path, argvlist, envlist);
3766 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003767#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003768 if (mode == _OLD_P_OVERLAY)
3769 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003770
Victor Stinner8c62be82010-05-06 00:08:46 +00003771 Py_BEGIN_ALLOW_THREADS
3772 spawnval = _spawnve(mode, path, argvlist, envlist);
3773 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003774#endif
Tim Peters25059d32001-12-07 20:35:43 +00003775
Victor Stinner8c62be82010-05-06 00:08:46 +00003776 if (spawnval == -1)
3777 (void) posix_error();
3778 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003779#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003780 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003781#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003782 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003783#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003784
Victor Stinner8c62be82010-05-06 00:08:46 +00003785 while (--envc >= 0)
3786 PyMem_DEL(envlist[envc]);
3787 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003788 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003789 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003790 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003791 Py_DECREF(opath);
3792 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003793}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003794
3795/* OS/2 supports spawnvp & spawnvpe natively */
3796#if defined(PYOS_OS2)
3797PyDoc_STRVAR(posix_spawnvp__doc__,
3798"spawnvp(mode, file, args)\n\n\
3799Execute the program 'file' in a new process, using the environment\n\
3800search path to find the file.\n\
3801\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003802 mode: mode of process creation\n\
3803 file: executable file name\n\
3804 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003805
3806static PyObject *
3807posix_spawnvp(PyObject *self, PyObject *args)
3808{
Victor Stinner8c62be82010-05-06 00:08:46 +00003809 PyObject *opath;
3810 char *path;
3811 PyObject *argv;
3812 char **argvlist;
3813 int mode, i, argc;
3814 Py_intptr_t spawnval;
3815 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003816
Victor Stinner8c62be82010-05-06 00:08:46 +00003817 /* spawnvp has three arguments: (mode, path, argv), where
3818 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003819
Victor Stinner8c62be82010-05-06 00:08:46 +00003820 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3821 PyUnicode_FSConverter,
3822 &opath, &argv))
3823 return NULL;
3824 path = PyBytes_AsString(opath);
3825 if (PyList_Check(argv)) {
3826 argc = PyList_Size(argv);
3827 getitem = PyList_GetItem;
3828 }
3829 else if (PyTuple_Check(argv)) {
3830 argc = PyTuple_Size(argv);
3831 getitem = PyTuple_GetItem;
3832 }
3833 else {
3834 PyErr_SetString(PyExc_TypeError,
3835 "spawnvp() arg 2 must be a tuple or list");
3836 Py_DECREF(opath);
3837 return NULL;
3838 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003839
Victor Stinner8c62be82010-05-06 00:08:46 +00003840 argvlist = PyMem_NEW(char *, argc+1);
3841 if (argvlist == NULL) {
3842 Py_DECREF(opath);
3843 return PyErr_NoMemory();
3844 }
3845 for (i = 0; i < argc; i++) {
3846 if (!fsconvert_strdup((*getitem)(argv, i),
3847 &argvlist[i])) {
3848 free_string_array(argvlist, i);
3849 PyErr_SetString(
3850 PyExc_TypeError,
3851 "spawnvp() arg 2 must contain only strings");
3852 Py_DECREF(opath);
3853 return NULL;
3854 }
3855 }
3856 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003857
Victor Stinner8c62be82010-05-06 00:08:46 +00003858 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003859#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003860 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003861#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003862 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003863#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003864 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003865
Victor Stinner8c62be82010-05-06 00:08:46 +00003866 free_string_array(argvlist, argc);
3867 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003868
Victor Stinner8c62be82010-05-06 00:08:46 +00003869 if (spawnval == -1)
3870 return posix_error();
3871 else
3872 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003873}
3874
3875
3876PyDoc_STRVAR(posix_spawnvpe__doc__,
3877"spawnvpe(mode, file, args, env)\n\n\
3878Execute the program 'file' in a new process, using the environment\n\
3879search path to find the file.\n\
3880\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003881 mode: mode of process creation\n\
3882 file: executable file name\n\
3883 args: tuple or list of arguments\n\
3884 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003885
3886static PyObject *
3887posix_spawnvpe(PyObject *self, PyObject *args)
3888{
Victor Stinner8c62be82010-05-06 00:08:46 +00003889 PyObject *opath
3890 char *path;
3891 PyObject *argv, *env;
3892 char **argvlist;
3893 char **envlist;
3894 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003895 int mode;
3896 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003897 Py_intptr_t spawnval;
3898 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3899 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003900
Victor Stinner8c62be82010-05-06 00:08:46 +00003901 /* spawnvpe has four arguments: (mode, path, argv, env), where
3902 argv is a list or tuple of strings and env is a dictionary
3903 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003904
Victor Stinner8c62be82010-05-06 00:08:46 +00003905 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3906 PyUnicode_FSConverter,
3907 &opath, &argv, &env))
3908 return NULL;
3909 path = PyBytes_AsString(opath);
3910 if (PyList_Check(argv)) {
3911 argc = PyList_Size(argv);
3912 getitem = PyList_GetItem;
3913 }
3914 else if (PyTuple_Check(argv)) {
3915 argc = PyTuple_Size(argv);
3916 getitem = PyTuple_GetItem;
3917 }
3918 else {
3919 PyErr_SetString(PyExc_TypeError,
3920 "spawnvpe() arg 2 must be a tuple or list");
3921 goto fail_0;
3922 }
3923 if (!PyMapping_Check(env)) {
3924 PyErr_SetString(PyExc_TypeError,
3925 "spawnvpe() arg 3 must be a mapping object");
3926 goto fail_0;
3927 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003928
Victor Stinner8c62be82010-05-06 00:08:46 +00003929 argvlist = PyMem_NEW(char *, argc+1);
3930 if (argvlist == NULL) {
3931 PyErr_NoMemory();
3932 goto fail_0;
3933 }
3934 for (i = 0; i < argc; i++) {
3935 if (!fsconvert_strdup((*getitem)(argv, i),
3936 &argvlist[i]))
3937 {
3938 lastarg = i;
3939 goto fail_1;
3940 }
3941 }
3942 lastarg = argc;
3943 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003944
Victor Stinner8c62be82010-05-06 00:08:46 +00003945 envlist = parse_envlist(env, &envc);
3946 if (envlist == NULL)
3947 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003948
Victor Stinner8c62be82010-05-06 00:08:46 +00003949 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003950#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003951 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003952#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003953 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003954#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003955 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003956
Victor Stinner8c62be82010-05-06 00:08:46 +00003957 if (spawnval == -1)
3958 (void) posix_error();
3959 else
3960 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003961
Victor Stinner8c62be82010-05-06 00:08:46 +00003962 while (--envc >= 0)
3963 PyMem_DEL(envlist[envc]);
3964 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003965 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003966 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003967 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003968 Py_DECREF(opath);
3969 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003970}
3971#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003972#endif /* HAVE_SPAWNV */
3973
3974
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003975#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003976PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003977"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003978Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3979\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003980Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003981
3982static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003983posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003984{
Victor Stinner8c62be82010-05-06 00:08:46 +00003985 pid_t pid;
3986 int result = 0;
3987 _PyImport_AcquireLock();
3988 pid = fork1();
3989 if (pid == 0) {
3990 /* child: this clobbers and resets the import lock. */
3991 PyOS_AfterFork();
3992 } else {
3993 /* parent: release the import lock. */
3994 result = _PyImport_ReleaseLock();
3995 }
3996 if (pid == -1)
3997 return posix_error();
3998 if (result < 0) {
3999 /* Don't clobber the OSError if the fork failed. */
4000 PyErr_SetString(PyExc_RuntimeError,
4001 "not holding the import lock");
4002 return NULL;
4003 }
4004 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004005}
4006#endif
4007
4008
Guido van Rossumad0ee831995-03-01 10:34:45 +00004009#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004010PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004011"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004012Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004013Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004014
Barry Warsaw53699e91996-12-10 23:23:01 +00004015static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004016posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004017{
Victor Stinner8c62be82010-05-06 00:08:46 +00004018 pid_t pid;
4019 int result = 0;
4020 _PyImport_AcquireLock();
4021 pid = fork();
4022 if (pid == 0) {
4023 /* child: this clobbers and resets the import lock. */
4024 PyOS_AfterFork();
4025 } else {
4026 /* parent: release the import lock. */
4027 result = _PyImport_ReleaseLock();
4028 }
4029 if (pid == -1)
4030 return posix_error();
4031 if (result < 0) {
4032 /* Don't clobber the OSError if the fork failed. */
4033 PyErr_SetString(PyExc_RuntimeError,
4034 "not holding the import lock");
4035 return NULL;
4036 }
4037 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00004038}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004039#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004040
Neal Norwitzb59798b2003-03-21 01:43:31 +00004041/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00004042/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
4043#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00004044#define DEV_PTY_FILE "/dev/ptc"
4045#define HAVE_DEV_PTMX
4046#else
4047#define DEV_PTY_FILE "/dev/ptmx"
4048#endif
4049
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004050#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004051#ifdef HAVE_PTY_H
4052#include <pty.h>
4053#else
4054#ifdef HAVE_LIBUTIL_H
4055#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00004056#else
4057#ifdef HAVE_UTIL_H
4058#include <util.h>
4059#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004060#endif /* HAVE_LIBUTIL_H */
4061#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00004062#ifdef HAVE_STROPTS_H
4063#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004064#endif
4065#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004066
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004067#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004068PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004069"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004070Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004071
4072static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004073posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004074{
Victor Stinner8c62be82010-05-06 00:08:46 +00004075 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004076#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004077 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004078#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004079#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004080 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004081#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00004082 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004083#endif
4084#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00004085
Thomas Wouters70c21a12000-07-14 14:28:33 +00004086#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004087 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
4088 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004089#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004090 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
4091 if (slave_name == NULL)
4092 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00004093
Victor Stinner8c62be82010-05-06 00:08:46 +00004094 slave_fd = open(slave_name, O_RDWR);
4095 if (slave_fd < 0)
4096 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004097#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004098 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
4099 if (master_fd < 0)
4100 return posix_error();
4101 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
4102 /* change permission of slave */
4103 if (grantpt(master_fd) < 0) {
4104 PyOS_setsig(SIGCHLD, sig_saved);
4105 return posix_error();
4106 }
4107 /* unlock slave */
4108 if (unlockpt(master_fd) < 0) {
4109 PyOS_setsig(SIGCHLD, sig_saved);
4110 return posix_error();
4111 }
4112 PyOS_setsig(SIGCHLD, sig_saved);
4113 slave_name = ptsname(master_fd); /* get name of slave */
4114 if (slave_name == NULL)
4115 return posix_error();
4116 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
4117 if (slave_fd < 0)
4118 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004119#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004120 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
4121 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00004122#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00004123 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00004124#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004125#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00004126#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00004127
Victor Stinner8c62be82010-05-06 00:08:46 +00004128 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00004129
Fred Drake8cef4cf2000-06-28 16:40:38 +00004130}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004131#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004132
4133#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004134PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004135"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00004136Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
4137Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004138To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004139
4140static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004141posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004142{
Victor Stinner8c62be82010-05-06 00:08:46 +00004143 int master_fd = -1, result = 0;
4144 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00004145
Victor Stinner8c62be82010-05-06 00:08:46 +00004146 _PyImport_AcquireLock();
4147 pid = forkpty(&master_fd, NULL, NULL, NULL);
4148 if (pid == 0) {
4149 /* child: this clobbers and resets the import lock. */
4150 PyOS_AfterFork();
4151 } else {
4152 /* parent: release the import lock. */
4153 result = _PyImport_ReleaseLock();
4154 }
4155 if (pid == -1)
4156 return posix_error();
4157 if (result < 0) {
4158 /* Don't clobber the OSError if the fork failed. */
4159 PyErr_SetString(PyExc_RuntimeError,
4160 "not holding the import lock");
4161 return NULL;
4162 }
4163 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004164}
4165#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004166
Guido van Rossumad0ee831995-03-01 10:34:45 +00004167#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004168PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004169"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004170Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004171
Barry Warsaw53699e91996-12-10 23:23:01 +00004172static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004173posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004174{
Victor Stinner8c62be82010-05-06 00:08:46 +00004175 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004176}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004177#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004178
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004179
Guido van Rossumad0ee831995-03-01 10:34:45 +00004180#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004181PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004182"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004183Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004184
Barry Warsaw53699e91996-12-10 23:23:01 +00004185static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004186posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004187{
Victor Stinner8c62be82010-05-06 00:08:46 +00004188 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004189}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004190#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004191
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004192
Guido van Rossumad0ee831995-03-01 10:34:45 +00004193#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004194PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004195"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004196Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004197
Barry Warsaw53699e91996-12-10 23:23:01 +00004198static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004199posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004200{
Victor Stinner8c62be82010-05-06 00:08:46 +00004201 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004202}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004203#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004204
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004205
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004206PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004207"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004208Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004209
Barry Warsaw53699e91996-12-10 23:23:01 +00004210static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004211posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004212{
Victor Stinner8c62be82010-05-06 00:08:46 +00004213 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004214}
4215
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004216
Fred Drakec9680921999-12-13 16:37:25 +00004217#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004218PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004219"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004220Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004221
4222static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004223posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004224{
4225 PyObject *result = NULL;
4226
Fred Drakec9680921999-12-13 16:37:25 +00004227#ifdef NGROUPS_MAX
4228#define MAX_GROUPS NGROUPS_MAX
4229#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004230 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004231#define MAX_GROUPS 64
4232#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004233 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004234
4235 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
4236 * This is a helper variable to store the intermediate result when
4237 * that happens.
4238 *
4239 * To keep the code readable the OSX behaviour is unconditional,
4240 * according to the POSIX spec this should be safe on all unix-y
4241 * systems.
4242 */
4243 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00004244 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004245
Victor Stinner8c62be82010-05-06 00:08:46 +00004246 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004247 if (n < 0) {
4248 if (errno == EINVAL) {
4249 n = getgroups(0, NULL);
4250 if (n == -1) {
4251 return posix_error();
4252 }
4253 if (n == 0) {
4254 /* Avoid malloc(0) */
4255 alt_grouplist = grouplist;
4256 } else {
4257 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4258 if (alt_grouplist == NULL) {
4259 errno = EINVAL;
4260 return posix_error();
4261 }
4262 n = getgroups(n, alt_grouplist);
4263 if (n == -1) {
4264 PyMem_Free(alt_grouplist);
4265 return posix_error();
4266 }
4267 }
4268 } else {
4269 return posix_error();
4270 }
4271 }
4272 result = PyList_New(n);
4273 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004274 int i;
4275 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004276 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00004277 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00004278 Py_DECREF(result);
4279 result = NULL;
4280 break;
Fred Drakec9680921999-12-13 16:37:25 +00004281 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004282 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004283 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004284 }
4285
4286 if (alt_grouplist != grouplist) {
4287 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00004288 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004289
Fred Drakec9680921999-12-13 16:37:25 +00004290 return result;
4291}
4292#endif
4293
Antoine Pitroub7572f02009-12-02 20:46:48 +00004294#ifdef HAVE_INITGROUPS
4295PyDoc_STRVAR(posix_initgroups__doc__,
4296"initgroups(username, gid) -> None\n\n\
4297Call the system initgroups() to initialize the group access list with all of\n\
4298the groups of which the specified username is a member, plus the specified\n\
4299group id.");
4300
4301static PyObject *
4302posix_initgroups(PyObject *self, PyObject *args)
4303{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004304 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00004305 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004306 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00004307 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004308
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004309 if (!PyArg_ParseTuple(args, "O&l:initgroups",
4310 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00004311 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004312 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004313
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004314 res = initgroups(username, (gid_t) gid);
4315 Py_DECREF(oname);
4316 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00004317 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004318
Victor Stinner8c62be82010-05-06 00:08:46 +00004319 Py_INCREF(Py_None);
4320 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004321}
4322#endif
4323
Martin v. Löwis606edc12002-06-13 21:09:11 +00004324#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004325PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004326"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004327Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004328
4329static PyObject *
4330posix_getpgid(PyObject *self, PyObject *args)
4331{
Victor Stinner8c62be82010-05-06 00:08:46 +00004332 pid_t pid, pgid;
4333 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
4334 return NULL;
4335 pgid = getpgid(pid);
4336 if (pgid < 0)
4337 return posix_error();
4338 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004339}
4340#endif /* HAVE_GETPGID */
4341
4342
Guido van Rossumb6775db1994-08-01 11:34:53 +00004343#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004344PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004345"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004346Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004347
Barry Warsaw53699e91996-12-10 23:23:01 +00004348static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004349posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004350{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004351#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004352 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004353#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004354 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004355#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004356}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004357#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004358
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004359
Guido van Rossumb6775db1994-08-01 11:34:53 +00004360#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004361PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004362"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00004363Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004364
Barry Warsaw53699e91996-12-10 23:23:01 +00004365static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004366posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004367{
Guido van Rossum64933891994-10-20 21:56:42 +00004368#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004369 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004370#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004371 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004372#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004373 return posix_error();
4374 Py_INCREF(Py_None);
4375 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004376}
4377
Guido van Rossumb6775db1994-08-01 11:34:53 +00004378#endif /* HAVE_SETPGRP */
4379
Guido van Rossumad0ee831995-03-01 10:34:45 +00004380#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004381
4382#ifdef MS_WINDOWS
4383#include <tlhelp32.h>
4384
4385static PyObject*
4386win32_getppid()
4387{
4388 HANDLE snapshot;
4389 pid_t mypid;
4390 PyObject* result = NULL;
4391 BOOL have_record;
4392 PROCESSENTRY32 pe;
4393
4394 mypid = getpid(); /* This function never fails */
4395
4396 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
4397 if (snapshot == INVALID_HANDLE_VALUE)
4398 return PyErr_SetFromWindowsErr(GetLastError());
4399
4400 pe.dwSize = sizeof(pe);
4401 have_record = Process32First(snapshot, &pe);
4402 while (have_record) {
4403 if (mypid == (pid_t)pe.th32ProcessID) {
4404 /* We could cache the ulong value in a static variable. */
4405 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
4406 break;
4407 }
4408
4409 have_record = Process32Next(snapshot, &pe);
4410 }
4411
4412 /* If our loop exits and our pid was not found (result will be NULL)
4413 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
4414 * error anyway, so let's raise it. */
4415 if (!result)
4416 result = PyErr_SetFromWindowsErr(GetLastError());
4417
4418 CloseHandle(snapshot);
4419
4420 return result;
4421}
4422#endif /*MS_WINDOWS*/
4423
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004424PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004425"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004426Return the parent's process id. If the parent process has already exited,\n\
4427Windows machines will still return its id; others systems will return the id\n\
4428of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004429
Barry Warsaw53699e91996-12-10 23:23:01 +00004430static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004431posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004432{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004433#ifdef MS_WINDOWS
4434 return win32_getppid();
4435#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004436 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00004437#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004438}
4439#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004440
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004441
Fred Drake12c6e2d1999-12-14 21:25:03 +00004442#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004443PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004444"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004445Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004446
4447static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004448posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004449{
Victor Stinner8c62be82010-05-06 00:08:46 +00004450 PyObject *result = NULL;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004451#ifdef MS_WINDOWS
4452 wchar_t user_name[UNLEN + 1];
4453 DWORD num_chars = sizeof(user_name)/sizeof(user_name[0]);
4454
4455 if (GetUserNameW(user_name, &num_chars)) {
4456 /* num_chars is the number of unicode chars plus null terminator */
4457 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
4458 }
4459 else
4460 result = PyErr_SetFromWindowsErr(GetLastError());
4461#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004462 char *name;
4463 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004464
Victor Stinner8c62be82010-05-06 00:08:46 +00004465 errno = 0;
4466 name = getlogin();
4467 if (name == NULL) {
4468 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00004469 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004470 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004471 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00004472 }
4473 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004474 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00004475 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004476#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00004477 return result;
4478}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004479#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00004480
Guido van Rossumad0ee831995-03-01 10:34:45 +00004481#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004482PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004483"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004484Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004485
Barry Warsaw53699e91996-12-10 23:23:01 +00004486static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004487posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004488{
Victor Stinner8c62be82010-05-06 00:08:46 +00004489 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004490}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004491#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004492
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004493
Guido van Rossumad0ee831995-03-01 10:34:45 +00004494#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004495PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004496"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004497Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004498
Barry Warsaw53699e91996-12-10 23:23:01 +00004499static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004500posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004501{
Victor Stinner8c62be82010-05-06 00:08:46 +00004502 pid_t pid;
4503 int sig;
4504 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
4505 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004506#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004507 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4508 APIRET rc;
4509 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004510 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004511
4512 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4513 APIRET rc;
4514 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004515 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004516
4517 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004518 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004519#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004520 if (kill(pid, sig) == -1)
4521 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004522#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004523 Py_INCREF(Py_None);
4524 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004525}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004526#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004527
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004528#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004529PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004530"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004531Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004532
4533static PyObject *
4534posix_killpg(PyObject *self, PyObject *args)
4535{
Victor Stinner8c62be82010-05-06 00:08:46 +00004536 int sig;
4537 pid_t pgid;
4538 /* XXX some man pages make the `pgid` parameter an int, others
4539 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4540 take the same type. Moreover, pid_t is always at least as wide as
4541 int (else compilation of this module fails), which is safe. */
4542 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
4543 return NULL;
4544 if (killpg(pgid, sig) == -1)
4545 return posix_error();
4546 Py_INCREF(Py_None);
4547 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004548}
4549#endif
4550
Brian Curtineb24d742010-04-12 17:16:38 +00004551#ifdef MS_WINDOWS
4552PyDoc_STRVAR(win32_kill__doc__,
4553"kill(pid, sig)\n\n\
4554Kill a process with a signal.");
4555
4556static PyObject *
4557win32_kill(PyObject *self, PyObject *args)
4558{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00004559 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004560 DWORD pid, sig, err;
4561 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00004562
Victor Stinner8c62be82010-05-06 00:08:46 +00004563 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4564 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00004565
Victor Stinner8c62be82010-05-06 00:08:46 +00004566 /* Console processes which share a common console can be sent CTRL+C or
4567 CTRL+BREAK events, provided they handle said events. */
4568 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4569 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4570 err = GetLastError();
4571 PyErr_SetFromWindowsErr(err);
4572 }
4573 else
4574 Py_RETURN_NONE;
4575 }
Brian Curtineb24d742010-04-12 17:16:38 +00004576
Victor Stinner8c62be82010-05-06 00:08:46 +00004577 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4578 attempt to open and terminate the process. */
4579 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4580 if (handle == NULL) {
4581 err = GetLastError();
4582 return PyErr_SetFromWindowsErr(err);
4583 }
Brian Curtineb24d742010-04-12 17:16:38 +00004584
Victor Stinner8c62be82010-05-06 00:08:46 +00004585 if (TerminateProcess(handle, sig) == 0) {
4586 err = GetLastError();
4587 result = PyErr_SetFromWindowsErr(err);
4588 } else {
4589 Py_INCREF(Py_None);
4590 result = Py_None;
4591 }
Brian Curtineb24d742010-04-12 17:16:38 +00004592
Victor Stinner8c62be82010-05-06 00:08:46 +00004593 CloseHandle(handle);
4594 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00004595}
4596#endif /* MS_WINDOWS */
4597
Guido van Rossumc0125471996-06-28 18:55:32 +00004598#ifdef HAVE_PLOCK
4599
4600#ifdef HAVE_SYS_LOCK_H
4601#include <sys/lock.h>
4602#endif
4603
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004604PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004605"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004606Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004607
Barry Warsaw53699e91996-12-10 23:23:01 +00004608static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004609posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004610{
Victor Stinner8c62be82010-05-06 00:08:46 +00004611 int op;
4612 if (!PyArg_ParseTuple(args, "i:plock", &op))
4613 return NULL;
4614 if (plock(op) == -1)
4615 return posix_error();
4616 Py_INCREF(Py_None);
4617 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004618}
4619#endif
4620
Guido van Rossumb6775db1994-08-01 11:34:53 +00004621#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004622PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004623"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004624Set the current process's user id.");
4625
Barry Warsaw53699e91996-12-10 23:23:01 +00004626static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004627posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004628{
Victor Stinner8c62be82010-05-06 00:08:46 +00004629 long uid_arg;
4630 uid_t uid;
4631 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
4632 return NULL;
4633 uid = uid_arg;
4634 if (uid != uid_arg) {
4635 PyErr_SetString(PyExc_OverflowError, "user id too big");
4636 return NULL;
4637 }
4638 if (setuid(uid) < 0)
4639 return posix_error();
4640 Py_INCREF(Py_None);
4641 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004642}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004643#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004644
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004645
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004646#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004647PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004648"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004649Set the current process's effective user id.");
4650
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004651static PyObject *
4652posix_seteuid (PyObject *self, PyObject *args)
4653{
Victor Stinner8c62be82010-05-06 00:08:46 +00004654 long euid_arg;
4655 uid_t euid;
4656 if (!PyArg_ParseTuple(args, "l", &euid_arg))
4657 return NULL;
4658 euid = euid_arg;
4659 if (euid != euid_arg) {
4660 PyErr_SetString(PyExc_OverflowError, "user id too big");
4661 return NULL;
4662 }
4663 if (seteuid(euid) < 0) {
4664 return posix_error();
4665 } else {
4666 Py_INCREF(Py_None);
4667 return Py_None;
4668 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004669}
4670#endif /* HAVE_SETEUID */
4671
4672#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004673PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004674"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004675Set the current process's effective group id.");
4676
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004677static PyObject *
4678posix_setegid (PyObject *self, PyObject *args)
4679{
Victor Stinner8c62be82010-05-06 00:08:46 +00004680 long egid_arg;
4681 gid_t egid;
4682 if (!PyArg_ParseTuple(args, "l", &egid_arg))
4683 return NULL;
4684 egid = egid_arg;
4685 if (egid != egid_arg) {
4686 PyErr_SetString(PyExc_OverflowError, "group id too big");
4687 return NULL;
4688 }
4689 if (setegid(egid) < 0) {
4690 return posix_error();
4691 } else {
4692 Py_INCREF(Py_None);
4693 return Py_None;
4694 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004695}
4696#endif /* HAVE_SETEGID */
4697
4698#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004699PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004700"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004701Set the current process's real and effective user ids.");
4702
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004703static PyObject *
4704posix_setreuid (PyObject *self, PyObject *args)
4705{
Victor Stinner8c62be82010-05-06 00:08:46 +00004706 long ruid_arg, euid_arg;
4707 uid_t ruid, euid;
4708 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
4709 return NULL;
4710 if (ruid_arg == -1)
4711 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
4712 else
4713 ruid = ruid_arg; /* otherwise, assign from our long */
4714 if (euid_arg == -1)
4715 euid = (uid_t)-1;
4716 else
4717 euid = euid_arg;
4718 if ((euid_arg != -1 && euid != euid_arg) ||
4719 (ruid_arg != -1 && ruid != ruid_arg)) {
4720 PyErr_SetString(PyExc_OverflowError, "user id too big");
4721 return NULL;
4722 }
4723 if (setreuid(ruid, euid) < 0) {
4724 return posix_error();
4725 } else {
4726 Py_INCREF(Py_None);
4727 return Py_None;
4728 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004729}
4730#endif /* HAVE_SETREUID */
4731
4732#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004733PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004734"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004735Set the current process's real and effective group ids.");
4736
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004737static PyObject *
4738posix_setregid (PyObject *self, PyObject *args)
4739{
Victor Stinner8c62be82010-05-06 00:08:46 +00004740 long rgid_arg, egid_arg;
4741 gid_t rgid, egid;
4742 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
4743 return NULL;
4744 if (rgid_arg == -1)
4745 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
4746 else
4747 rgid = rgid_arg; /* otherwise, assign from our long */
4748 if (egid_arg == -1)
4749 egid = (gid_t)-1;
4750 else
4751 egid = egid_arg;
4752 if ((egid_arg != -1 && egid != egid_arg) ||
4753 (rgid_arg != -1 && rgid != rgid_arg)) {
4754 PyErr_SetString(PyExc_OverflowError, "group id too big");
4755 return NULL;
4756 }
4757 if (setregid(rgid, egid) < 0) {
4758 return posix_error();
4759 } else {
4760 Py_INCREF(Py_None);
4761 return Py_None;
4762 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004763}
4764#endif /* HAVE_SETREGID */
4765
Guido van Rossumb6775db1994-08-01 11:34:53 +00004766#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004767PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004768"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004769Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004770
Barry Warsaw53699e91996-12-10 23:23:01 +00004771static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004772posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004773{
Victor Stinner8c62be82010-05-06 00:08:46 +00004774 long gid_arg;
4775 gid_t gid;
4776 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
4777 return NULL;
4778 gid = gid_arg;
4779 if (gid != gid_arg) {
4780 PyErr_SetString(PyExc_OverflowError, "group id too big");
4781 return NULL;
4782 }
4783 if (setgid(gid) < 0)
4784 return posix_error();
4785 Py_INCREF(Py_None);
4786 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004787}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004788#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004789
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004790#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004791PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004792"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004793Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004794
4795static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004796posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004797{
Victor Stinner8c62be82010-05-06 00:08:46 +00004798 int i, len;
4799 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004800
Victor Stinner8c62be82010-05-06 00:08:46 +00004801 if (!PySequence_Check(groups)) {
4802 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4803 return NULL;
4804 }
4805 len = PySequence_Size(groups);
4806 if (len > MAX_GROUPS) {
4807 PyErr_SetString(PyExc_ValueError, "too many groups");
4808 return NULL;
4809 }
4810 for(i = 0; i < len; i++) {
4811 PyObject *elem;
4812 elem = PySequence_GetItem(groups, i);
4813 if (!elem)
4814 return NULL;
4815 if (!PyLong_Check(elem)) {
4816 PyErr_SetString(PyExc_TypeError,
4817 "groups must be integers");
4818 Py_DECREF(elem);
4819 return NULL;
4820 } else {
4821 unsigned long x = PyLong_AsUnsignedLong(elem);
4822 if (PyErr_Occurred()) {
4823 PyErr_SetString(PyExc_TypeError,
4824 "group id too big");
4825 Py_DECREF(elem);
4826 return NULL;
4827 }
4828 grouplist[i] = x;
4829 /* read back the value to see if it fitted in gid_t */
4830 if (grouplist[i] != x) {
4831 PyErr_SetString(PyExc_TypeError,
4832 "group id too big");
4833 Py_DECREF(elem);
4834 return NULL;
4835 }
4836 }
4837 Py_DECREF(elem);
4838 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004839
Victor Stinner8c62be82010-05-06 00:08:46 +00004840 if (setgroups(len, grouplist) < 0)
4841 return posix_error();
4842 Py_INCREF(Py_None);
4843 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004844}
4845#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004846
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004847#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4848static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004849wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004850{
Victor Stinner8c62be82010-05-06 00:08:46 +00004851 PyObject *result;
4852 static PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004853
Victor Stinner8c62be82010-05-06 00:08:46 +00004854 if (pid == -1)
4855 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004856
Victor Stinner8c62be82010-05-06 00:08:46 +00004857 if (struct_rusage == NULL) {
4858 PyObject *m = PyImport_ImportModuleNoBlock("resource");
4859 if (m == NULL)
4860 return NULL;
4861 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4862 Py_DECREF(m);
4863 if (struct_rusage == NULL)
4864 return NULL;
4865 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004866
Victor Stinner8c62be82010-05-06 00:08:46 +00004867 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4868 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4869 if (!result)
4870 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004871
4872#ifndef doubletime
4873#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4874#endif
4875
Victor Stinner8c62be82010-05-06 00:08:46 +00004876 PyStructSequence_SET_ITEM(result, 0,
4877 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4878 PyStructSequence_SET_ITEM(result, 1,
4879 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004880#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00004881 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
4882 SET_INT(result, 2, ru->ru_maxrss);
4883 SET_INT(result, 3, ru->ru_ixrss);
4884 SET_INT(result, 4, ru->ru_idrss);
4885 SET_INT(result, 5, ru->ru_isrss);
4886 SET_INT(result, 6, ru->ru_minflt);
4887 SET_INT(result, 7, ru->ru_majflt);
4888 SET_INT(result, 8, ru->ru_nswap);
4889 SET_INT(result, 9, ru->ru_inblock);
4890 SET_INT(result, 10, ru->ru_oublock);
4891 SET_INT(result, 11, ru->ru_msgsnd);
4892 SET_INT(result, 12, ru->ru_msgrcv);
4893 SET_INT(result, 13, ru->ru_nsignals);
4894 SET_INT(result, 14, ru->ru_nvcsw);
4895 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004896#undef SET_INT
4897
Victor Stinner8c62be82010-05-06 00:08:46 +00004898 if (PyErr_Occurred()) {
4899 Py_DECREF(result);
4900 return NULL;
4901 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004902
Victor Stinner8c62be82010-05-06 00:08:46 +00004903 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004904}
4905#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4906
4907#ifdef HAVE_WAIT3
4908PyDoc_STRVAR(posix_wait3__doc__,
4909"wait3(options) -> (pid, status, rusage)\n\n\
4910Wait for completion of a child process.");
4911
4912static PyObject *
4913posix_wait3(PyObject *self, PyObject *args)
4914{
Victor Stinner8c62be82010-05-06 00:08:46 +00004915 pid_t pid;
4916 int options;
4917 struct rusage ru;
4918 WAIT_TYPE status;
4919 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004920
Victor Stinner8c62be82010-05-06 00:08:46 +00004921 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4922 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004923
Victor Stinner8c62be82010-05-06 00:08:46 +00004924 Py_BEGIN_ALLOW_THREADS
4925 pid = wait3(&status, options, &ru);
4926 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004927
Victor Stinner8c62be82010-05-06 00:08:46 +00004928 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004929}
4930#endif /* HAVE_WAIT3 */
4931
4932#ifdef HAVE_WAIT4
4933PyDoc_STRVAR(posix_wait4__doc__,
4934"wait4(pid, options) -> (pid, status, rusage)\n\n\
4935Wait for completion of a given child process.");
4936
4937static PyObject *
4938posix_wait4(PyObject *self, PyObject *args)
4939{
Victor Stinner8c62be82010-05-06 00:08:46 +00004940 pid_t pid;
4941 int options;
4942 struct rusage ru;
4943 WAIT_TYPE status;
4944 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004945
Victor Stinner8c62be82010-05-06 00:08:46 +00004946 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
4947 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004948
Victor Stinner8c62be82010-05-06 00:08:46 +00004949 Py_BEGIN_ALLOW_THREADS
4950 pid = wait4(pid, &status, options, &ru);
4951 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004952
Victor Stinner8c62be82010-05-06 00:08:46 +00004953 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004954}
4955#endif /* HAVE_WAIT4 */
4956
Guido van Rossumb6775db1994-08-01 11:34:53 +00004957#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004958PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004959"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004960Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004961
Barry Warsaw53699e91996-12-10 23:23:01 +00004962static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004963posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004964{
Victor Stinner8c62be82010-05-06 00:08:46 +00004965 pid_t pid;
4966 int options;
4967 WAIT_TYPE status;
4968 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004969
Victor Stinner8c62be82010-05-06 00:08:46 +00004970 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4971 return NULL;
4972 Py_BEGIN_ALLOW_THREADS
4973 pid = waitpid(pid, &status, options);
4974 Py_END_ALLOW_THREADS
4975 if (pid == -1)
4976 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004977
Victor Stinner8c62be82010-05-06 00:08:46 +00004978 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004979}
4980
Tim Petersab034fa2002-02-01 11:27:43 +00004981#elif defined(HAVE_CWAIT)
4982
4983/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004984PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004985"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004986"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004987
4988static PyObject *
4989posix_waitpid(PyObject *self, PyObject *args)
4990{
Victor Stinner8c62be82010-05-06 00:08:46 +00004991 Py_intptr_t pid;
4992 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004993
Victor Stinner8c62be82010-05-06 00:08:46 +00004994 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4995 return NULL;
4996 Py_BEGIN_ALLOW_THREADS
4997 pid = _cwait(&status, pid, options);
4998 Py_END_ALLOW_THREADS
4999 if (pid == -1)
5000 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005001
Victor Stinner8c62be82010-05-06 00:08:46 +00005002 /* shift the status left a byte so this is more like the POSIX waitpid */
5003 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005004}
5005#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005006
Guido van Rossumad0ee831995-03-01 10:34:45 +00005007#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005008PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005009"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005010Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005011
Barry Warsaw53699e91996-12-10 23:23:01 +00005012static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005013posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005014{
Victor Stinner8c62be82010-05-06 00:08:46 +00005015 pid_t pid;
5016 WAIT_TYPE status;
5017 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005018
Victor Stinner8c62be82010-05-06 00:08:46 +00005019 Py_BEGIN_ALLOW_THREADS
5020 pid = wait(&status);
5021 Py_END_ALLOW_THREADS
5022 if (pid == -1)
5023 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005024
Victor Stinner8c62be82010-05-06 00:08:46 +00005025 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005026}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005027#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005028
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005029
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005030PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005031"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005032Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005033
Barry Warsaw53699e91996-12-10 23:23:01 +00005034static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005035posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005036{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005037#ifdef HAVE_LSTAT
Victor Stinner8c62be82010-05-06 00:08:46 +00005038 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005039#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005040#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00005041 return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat",
5042 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005043#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005044 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005045#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005046#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005047}
5048
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005049
Guido van Rossumb6775db1994-08-01 11:34:53 +00005050#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005051PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005052"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005053Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005054
Barry Warsaw53699e91996-12-10 23:23:01 +00005055static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005056posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005057{
Victor Stinner8c62be82010-05-06 00:08:46 +00005058 PyObject* v;
5059 char buf[MAXPATHLEN];
5060 PyObject *opath;
5061 char *path;
5062 int n;
5063 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00005064
Victor Stinner8c62be82010-05-06 00:08:46 +00005065 if (!PyArg_ParseTuple(args, "O&:readlink",
5066 PyUnicode_FSConverter, &opath))
5067 return NULL;
5068 path = PyBytes_AsString(opath);
5069 v = PySequence_GetItem(args, 0);
5070 if (v == NULL) {
5071 Py_DECREF(opath);
5072 return NULL;
5073 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00005074
Victor Stinner8c62be82010-05-06 00:08:46 +00005075 if (PyUnicode_Check(v)) {
5076 arg_is_unicode = 1;
5077 }
5078 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005079
Victor Stinner8c62be82010-05-06 00:08:46 +00005080 Py_BEGIN_ALLOW_THREADS
5081 n = readlink(path, buf, (int) sizeof buf);
5082 Py_END_ALLOW_THREADS
5083 if (n < 0)
5084 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005085
Victor Stinner8c62be82010-05-06 00:08:46 +00005086 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00005087 if (arg_is_unicode)
5088 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
5089 else
5090 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005091}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005092#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005093
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005094
Guido van Rossumb6775db1994-08-01 11:34:53 +00005095#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005096PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005097"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005098Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005099
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005100static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005101posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005102{
Victor Stinner8c62be82010-05-06 00:08:46 +00005103 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005104}
5105#endif /* HAVE_SYMLINK */
5106
Brian Curtind40e6f72010-07-08 21:39:08 +00005107#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
5108
5109PyDoc_STRVAR(win_readlink__doc__,
5110"readlink(path) -> path\n\n\
5111Return a string representing the path to which the symbolic link points.");
5112
Brian Curtind40e6f72010-07-08 21:39:08 +00005113/* Windows readlink implementation */
5114static PyObject *
5115win_readlink(PyObject *self, PyObject *args)
5116{
5117 wchar_t *path;
5118 DWORD n_bytes_returned;
5119 DWORD io_result;
5120 PyObject *result;
5121 HANDLE reparse_point_handle;
5122
5123 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
5124 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
5125 wchar_t *print_name;
5126
5127 if (!PyArg_ParseTuple(args,
5128 "u:readlink",
5129 &path))
5130 return NULL;
5131
5132 /* First get a handle to the reparse point */
5133 Py_BEGIN_ALLOW_THREADS
5134 reparse_point_handle = CreateFileW(
5135 path,
5136 0,
5137 0,
5138 0,
5139 OPEN_EXISTING,
5140 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
5141 0);
5142 Py_END_ALLOW_THREADS
5143
5144 if (reparse_point_handle==INVALID_HANDLE_VALUE)
5145 {
5146 return win32_error_unicode("readlink", path);
5147 }
5148
5149 Py_BEGIN_ALLOW_THREADS
5150 /* New call DeviceIoControl to read the reparse point */
5151 io_result = DeviceIoControl(
5152 reparse_point_handle,
5153 FSCTL_GET_REPARSE_POINT,
5154 0, 0, /* in buffer */
5155 target_buffer, sizeof(target_buffer),
5156 &n_bytes_returned,
5157 0 /* we're not using OVERLAPPED_IO */
5158 );
5159 CloseHandle(reparse_point_handle);
5160 Py_END_ALLOW_THREADS
5161
5162 if (io_result==0)
5163 {
5164 return win32_error_unicode("readlink", path);
5165 }
5166
5167 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
5168 {
5169 PyErr_SetString(PyExc_ValueError,
5170 "not a symbolic link");
5171 return NULL;
5172 }
Brian Curtin74e45612010-07-09 15:58:59 +00005173 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
5174 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
5175
5176 result = PyUnicode_FromWideChar(print_name,
5177 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00005178 return result;
5179}
5180
5181#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
5182
5183#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
5184
5185/* Grab CreateSymbolicLinkW dynamically from kernel32 */
5186static int has_CreateSymbolicLinkW = 0;
5187static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
5188static int
5189check_CreateSymbolicLinkW()
5190{
5191 HINSTANCE hKernel32;
5192 /* only recheck */
5193 if (has_CreateSymbolicLinkW)
5194 return has_CreateSymbolicLinkW;
5195 hKernel32 = GetModuleHandle("KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00005196 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
5197 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00005198 if (Py_CreateSymbolicLinkW)
5199 has_CreateSymbolicLinkW = 1;
5200 return has_CreateSymbolicLinkW;
5201}
5202
5203PyDoc_STRVAR(win_symlink__doc__,
5204"symlink(src, dst, target_is_directory=False)\n\n\
5205Create a symbolic link pointing to src named dst.\n\
5206target_is_directory is required if the target is to be interpreted as\n\
5207a directory.\n\
5208This function requires Windows 6.0 or greater, and raises a\n\
5209NotImplementedError otherwise.");
5210
5211static PyObject *
5212win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
5213{
5214 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
5215 PyObject *src, *dest;
5216 int target_is_directory = 0;
5217 DWORD res;
5218 WIN32_FILE_ATTRIBUTE_DATA src_info;
5219
5220 if (!check_CreateSymbolicLinkW())
5221 {
5222 /* raise NotImplementedError */
5223 return PyErr_Format(PyExc_NotImplementedError,
5224 "CreateSymbolicLinkW not found");
5225 }
5226 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:symlink",
5227 kwlist, &src, &dest, &target_is_directory))
5228 return NULL;
5229 if (!convert_to_unicode(&src)) { return NULL; }
5230 if (!convert_to_unicode(&dest)) {
5231 Py_DECREF(src);
5232 return NULL;
5233 }
5234
5235 /* if src is a directory, ensure target_is_directory==1 */
5236 if(
5237 GetFileAttributesExW(
5238 PyUnicode_AsUnicode(src), GetFileExInfoStandard, &src_info
5239 ))
5240 {
5241 target_is_directory = target_is_directory ||
5242 (src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
5243 }
5244
5245 Py_BEGIN_ALLOW_THREADS
5246 res = Py_CreateSymbolicLinkW(
5247 PyUnicode_AsUnicode(dest),
5248 PyUnicode_AsUnicode(src),
5249 target_is_directory);
5250 Py_END_ALLOW_THREADS
5251 Py_DECREF(src);
5252 Py_DECREF(dest);
5253 if (!res)
5254 {
5255 return win32_error_unicode("symlink", PyUnicode_AsUnicode(src));
5256 }
5257
5258 Py_INCREF(Py_None);
5259 return Py_None;
5260}
5261#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005262
5263#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00005264#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5265static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005266system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005267{
5268 ULONG value = 0;
5269
5270 Py_BEGIN_ALLOW_THREADS
5271 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5272 Py_END_ALLOW_THREADS
5273
5274 return value;
5275}
5276
5277static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005278posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005279{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005280 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00005281 return Py_BuildValue("ddddd",
5282 (double)0 /* t.tms_utime / HZ */,
5283 (double)0 /* t.tms_stime / HZ */,
5284 (double)0 /* t.tms_cutime / HZ */,
5285 (double)0 /* t.tms_cstime / HZ */,
5286 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005287}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005288#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00005289#define NEED_TICKS_PER_SECOND
5290static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00005291static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005292posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005293{
Victor Stinner8c62be82010-05-06 00:08:46 +00005294 struct tms t;
5295 clock_t c;
5296 errno = 0;
5297 c = times(&t);
5298 if (c == (clock_t) -1)
5299 return posix_error();
5300 return Py_BuildValue("ddddd",
5301 (double)t.tms_utime / ticks_per_second,
5302 (double)t.tms_stime / ticks_per_second,
5303 (double)t.tms_cutime / ticks_per_second,
5304 (double)t.tms_cstime / ticks_per_second,
5305 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005306}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005307#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005308#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005309
5310
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005311#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005312#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005313static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005314posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005315{
Victor Stinner8c62be82010-05-06 00:08:46 +00005316 FILETIME create, exit, kernel, user;
5317 HANDLE hProc;
5318 hProc = GetCurrentProcess();
5319 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5320 /* The fields of a FILETIME structure are the hi and lo part
5321 of a 64-bit value expressed in 100 nanosecond units.
5322 1e7 is one second in such units; 1e-7 the inverse.
5323 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5324 */
5325 return Py_BuildValue(
5326 "ddddd",
5327 (double)(user.dwHighDateTime*429.4967296 +
5328 user.dwLowDateTime*1e-7),
5329 (double)(kernel.dwHighDateTime*429.4967296 +
5330 kernel.dwLowDateTime*1e-7),
5331 (double)0,
5332 (double)0,
5333 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005334}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005335#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005336
5337#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005338PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005339"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005340Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005341#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005342
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005343
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005344#ifdef HAVE_GETSID
5345PyDoc_STRVAR(posix_getsid__doc__,
5346"getsid(pid) -> sid\n\n\
5347Call the system call getsid().");
5348
5349static PyObject *
5350posix_getsid(PyObject *self, PyObject *args)
5351{
Victor Stinner8c62be82010-05-06 00:08:46 +00005352 pid_t pid;
5353 int sid;
5354 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
5355 return NULL;
5356 sid = getsid(pid);
5357 if (sid < 0)
5358 return posix_error();
5359 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005360}
5361#endif /* HAVE_GETSID */
5362
5363
Guido van Rossumb6775db1994-08-01 11:34:53 +00005364#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005365PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005366"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005367Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005368
Barry Warsaw53699e91996-12-10 23:23:01 +00005369static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005370posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005371{
Victor Stinner8c62be82010-05-06 00:08:46 +00005372 if (setsid() < 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_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005378
Guido van Rossumb6775db1994-08-01 11:34:53 +00005379#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005380PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005381"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005382Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005383
Barry Warsaw53699e91996-12-10 23:23:01 +00005384static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005385posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005386{
Victor Stinner8c62be82010-05-06 00:08:46 +00005387 pid_t pid;
5388 int pgrp;
5389 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
5390 return NULL;
5391 if (setpgid(pid, pgrp) < 0)
5392 return posix_error();
5393 Py_INCREF(Py_None);
5394 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005395}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005396#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005397
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005398
Guido van Rossumb6775db1994-08-01 11:34:53 +00005399#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005400PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005401"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005402Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005403
Barry Warsaw53699e91996-12-10 23:23:01 +00005404static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005405posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005406{
Victor Stinner8c62be82010-05-06 00:08:46 +00005407 int fd;
5408 pid_t pgid;
5409 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
5410 return NULL;
5411 pgid = tcgetpgrp(fd);
5412 if (pgid < 0)
5413 return posix_error();
5414 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005415}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005416#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005417
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005418
Guido van Rossumb6775db1994-08-01 11:34:53 +00005419#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005420PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005421"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005422Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005423
Barry Warsaw53699e91996-12-10 23:23:01 +00005424static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005425posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005426{
Victor Stinner8c62be82010-05-06 00:08:46 +00005427 int fd;
5428 pid_t pgid;
5429 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
5430 return NULL;
5431 if (tcsetpgrp(fd, pgid) < 0)
5432 return posix_error();
5433 Py_INCREF(Py_None);
5434 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005435}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005436#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005437
Guido van Rossum687dd131993-05-17 08:34:16 +00005438/* Functions acting on file descriptors */
5439
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005440PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005441"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005442Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005443
Barry Warsaw53699e91996-12-10 23:23:01 +00005444static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005445posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005446{
Victor Stinner8c62be82010-05-06 00:08:46 +00005447 PyObject *ofile;
5448 char *file;
5449 int flag;
5450 int mode = 0777;
5451 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005452
5453#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005454 PyUnicodeObject *po;
5455 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5456 Py_BEGIN_ALLOW_THREADS
5457 /* PyUnicode_AS_UNICODE OK without thread
5458 lock as it is a simple dereference. */
5459 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5460 Py_END_ALLOW_THREADS
5461 if (fd < 0)
5462 return posix_error();
5463 return PyLong_FromLong((long)fd);
5464 }
5465 /* Drop the argument parsing error as narrow strings
5466 are also valid. */
5467 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005468#endif
5469
Victor Stinner8c62be82010-05-06 00:08:46 +00005470 if (!PyArg_ParseTuple(args, "O&i|i",
5471 PyUnicode_FSConverter, &ofile,
5472 &flag, &mode))
5473 return NULL;
5474 file = PyBytes_AsString(ofile);
5475 Py_BEGIN_ALLOW_THREADS
5476 fd = open(file, flag, mode);
5477 Py_END_ALLOW_THREADS
5478 if (fd < 0)
5479 return posix_error_with_allocated_filename(ofile);
5480 Py_DECREF(ofile);
5481 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005482}
5483
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005484
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005485PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005486"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005487Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005488
Barry Warsaw53699e91996-12-10 23:23:01 +00005489static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005490posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005491{
Victor Stinner8c62be82010-05-06 00:08:46 +00005492 int fd, res;
5493 if (!PyArg_ParseTuple(args, "i:close", &fd))
5494 return NULL;
5495 if (!_PyVerify_fd(fd))
5496 return posix_error();
5497 Py_BEGIN_ALLOW_THREADS
5498 res = close(fd);
5499 Py_END_ALLOW_THREADS
5500 if (res < 0)
5501 return posix_error();
5502 Py_INCREF(Py_None);
5503 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005504}
5505
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005506
Victor Stinner8c62be82010-05-06 00:08:46 +00005507PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00005508"closerange(fd_low, fd_high)\n\n\
5509Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
5510
5511static PyObject *
5512posix_closerange(PyObject *self, PyObject *args)
5513{
Victor Stinner8c62be82010-05-06 00:08:46 +00005514 int fd_from, fd_to, i;
5515 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
5516 return NULL;
5517 Py_BEGIN_ALLOW_THREADS
5518 for (i = fd_from; i < fd_to; i++)
5519 if (_PyVerify_fd(i))
5520 close(i);
5521 Py_END_ALLOW_THREADS
5522 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00005523}
5524
5525
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005526PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005527"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005528Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005529
Barry Warsaw53699e91996-12-10 23:23:01 +00005530static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005531posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005532{
Victor Stinner8c62be82010-05-06 00:08:46 +00005533 int fd;
5534 if (!PyArg_ParseTuple(args, "i:dup", &fd))
5535 return NULL;
5536 if (!_PyVerify_fd(fd))
5537 return posix_error();
5538 Py_BEGIN_ALLOW_THREADS
5539 fd = dup(fd);
5540 Py_END_ALLOW_THREADS
5541 if (fd < 0)
5542 return posix_error();
5543 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005544}
5545
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005546
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005547PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005548"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005549Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005550
Barry Warsaw53699e91996-12-10 23:23:01 +00005551static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005552posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005553{
Victor Stinner8c62be82010-05-06 00:08:46 +00005554 int fd, fd2, res;
5555 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5556 return NULL;
5557 if (!_PyVerify_fd_dup2(fd, fd2))
5558 return posix_error();
5559 Py_BEGIN_ALLOW_THREADS
5560 res = dup2(fd, fd2);
5561 Py_END_ALLOW_THREADS
5562 if (res < 0)
5563 return posix_error();
5564 Py_INCREF(Py_None);
5565 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005566}
5567
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005568
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005569PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005570"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005571Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005572
Barry Warsaw53699e91996-12-10 23:23:01 +00005573static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005574posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005575{
Victor Stinner8c62be82010-05-06 00:08:46 +00005576 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005577#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005578 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005579#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005580 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005581#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005582 PyObject *posobj;
5583 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5584 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005585#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00005586 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5587 switch (how) {
5588 case 0: how = SEEK_SET; break;
5589 case 1: how = SEEK_CUR; break;
5590 case 2: how = SEEK_END; break;
5591 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005592#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005593
5594#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005595 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005596#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005597 pos = PyLong_Check(posobj) ?
5598 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005599#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005600 if (PyErr_Occurred())
5601 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005602
Victor Stinner8c62be82010-05-06 00:08:46 +00005603 if (!_PyVerify_fd(fd))
5604 return posix_error();
5605 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005606#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005607 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005608#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005609 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005610#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005611 Py_END_ALLOW_THREADS
5612 if (res < 0)
5613 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005614
5615#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005616 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005617#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005618 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005619#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005620}
5621
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005622
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005623PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005624"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005625Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005626
Barry Warsaw53699e91996-12-10 23:23:01 +00005627static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005628posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005629{
Victor Stinner8c62be82010-05-06 00:08:46 +00005630 int fd, size;
5631 Py_ssize_t n;
5632 PyObject *buffer;
5633 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5634 return NULL;
5635 if (size < 0) {
5636 errno = EINVAL;
5637 return posix_error();
5638 }
5639 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
5640 if (buffer == NULL)
5641 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00005642 if (!_PyVerify_fd(fd)) {
5643 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00005644 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00005645 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005646 Py_BEGIN_ALLOW_THREADS
5647 n = read(fd, PyBytes_AS_STRING(buffer), size);
5648 Py_END_ALLOW_THREADS
5649 if (n < 0) {
5650 Py_DECREF(buffer);
5651 return posix_error();
5652 }
5653 if (n != size)
5654 _PyBytes_Resize(&buffer, n);
5655 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00005656}
5657
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005658
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005659PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005660"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005661Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005662
Barry Warsaw53699e91996-12-10 23:23:01 +00005663static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005664posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005665{
Victor Stinner8c62be82010-05-06 00:08:46 +00005666 Py_buffer pbuf;
5667 int fd;
5668 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005669
Victor Stinner8c62be82010-05-06 00:08:46 +00005670 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
5671 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00005672 if (!_PyVerify_fd(fd)) {
5673 PyBuffer_Release(&pbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00005674 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00005675 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005676 Py_BEGIN_ALLOW_THREADS
5677 size = write(fd, pbuf.buf, (size_t)pbuf.len);
5678 Py_END_ALLOW_THREADS
Stefan Krah99439262010-11-26 12:58:05 +00005679 PyBuffer_Release(&pbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00005680 if (size < 0)
5681 return posix_error();
5682 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005683}
5684
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005685
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005686PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005687"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005688Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005689
Barry Warsaw53699e91996-12-10 23:23:01 +00005690static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005691posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005692{
Victor Stinner8c62be82010-05-06 00:08:46 +00005693 int fd;
5694 STRUCT_STAT st;
5695 int res;
5696 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5697 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005698#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00005699 /* on OpenVMS we must ensure that all bytes are written to the file */
5700 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005701#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005702 if (!_PyVerify_fd(fd))
5703 return posix_error();
5704 Py_BEGIN_ALLOW_THREADS
5705 res = FSTAT(fd, &st);
5706 Py_END_ALLOW_THREADS
5707 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00005708#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005709 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00005710#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005711 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005712#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005713 }
Tim Peters5aa91602002-01-30 05:46:57 +00005714
Victor Stinner8c62be82010-05-06 00:08:46 +00005715 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005716}
5717
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005718PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005719"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005720Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005721connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005722
5723static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005724posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005725{
Victor Stinner8c62be82010-05-06 00:08:46 +00005726 int fd;
5727 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5728 return NULL;
5729 if (!_PyVerify_fd(fd))
5730 return PyBool_FromLong(0);
5731 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005732}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005733
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005734#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005735PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005736"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005737Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005738
Barry Warsaw53699e91996-12-10 23:23:01 +00005739static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005740posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005741{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005742#if defined(PYOS_OS2)
5743 HFILE read, write;
5744 APIRET rc;
5745
Victor Stinner8c62be82010-05-06 00:08:46 +00005746 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005747 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinner8c62be82010-05-06 00:08:46 +00005748 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005749 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005750 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005751
5752 return Py_BuildValue("(ii)", read, write);
5753#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005754#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005755 int fds[2];
5756 int res;
5757 Py_BEGIN_ALLOW_THREADS
5758 res = pipe(fds);
5759 Py_END_ALLOW_THREADS
5760 if (res != 0)
5761 return posix_error();
5762 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005763#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00005764 HANDLE read, write;
5765 int read_fd, write_fd;
5766 BOOL ok;
5767 Py_BEGIN_ALLOW_THREADS
5768 ok = CreatePipe(&read, &write, NULL, 0);
5769 Py_END_ALLOW_THREADS
5770 if (!ok)
5771 return win32_error("CreatePipe", NULL);
5772 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5773 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5774 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005775#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005776#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005777}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005778#endif /* HAVE_PIPE */
5779
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005780
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005781#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005782PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005783"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005784Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005785
Barry Warsaw53699e91996-12-10 23:23:01 +00005786static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005787posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005788{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005789 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005790 char *filename;
5791 int mode = 0666;
5792 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005793 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
5794 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00005795 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005796 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005797 Py_BEGIN_ALLOW_THREADS
5798 res = mkfifo(filename, mode);
5799 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005800 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005801 if (res < 0)
5802 return posix_error();
5803 Py_INCREF(Py_None);
5804 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005805}
5806#endif
5807
5808
Neal Norwitz11690112002-07-30 01:08:28 +00005809#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005810PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005811"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005812Create a filesystem node (file, device special file or named pipe)\n\
5813named filename. mode specifies both the permissions to use and the\n\
5814type of node to be created, being combined (bitwise OR) with one of\n\
5815S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005816device defines the newly created device special file (probably using\n\
5817os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005818
5819
5820static PyObject *
5821posix_mknod(PyObject *self, PyObject *args)
5822{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005823 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005824 char *filename;
5825 int mode = 0600;
5826 int device = 0;
5827 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005828 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
5829 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00005830 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005831 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005832 Py_BEGIN_ALLOW_THREADS
5833 res = mknod(filename, mode, device);
5834 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005835 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005836 if (res < 0)
5837 return posix_error();
5838 Py_INCREF(Py_None);
5839 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005840}
5841#endif
5842
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005843#ifdef HAVE_DEVICE_MACROS
5844PyDoc_STRVAR(posix_major__doc__,
5845"major(device) -> major number\n\
5846Extracts a device major number from a raw device number.");
5847
5848static PyObject *
5849posix_major(PyObject *self, PyObject *args)
5850{
Victor Stinner8c62be82010-05-06 00:08:46 +00005851 int device;
5852 if (!PyArg_ParseTuple(args, "i:major", &device))
5853 return NULL;
5854 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005855}
5856
5857PyDoc_STRVAR(posix_minor__doc__,
5858"minor(device) -> minor number\n\
5859Extracts a device minor number from a raw device number.");
5860
5861static PyObject *
5862posix_minor(PyObject *self, PyObject *args)
5863{
Victor Stinner8c62be82010-05-06 00:08:46 +00005864 int device;
5865 if (!PyArg_ParseTuple(args, "i:minor", &device))
5866 return NULL;
5867 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005868}
5869
5870PyDoc_STRVAR(posix_makedev__doc__,
5871"makedev(major, minor) -> device number\n\
5872Composes a raw device number from the major and minor device numbers.");
5873
5874static PyObject *
5875posix_makedev(PyObject *self, PyObject *args)
5876{
Victor Stinner8c62be82010-05-06 00:08:46 +00005877 int major, minor;
5878 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5879 return NULL;
5880 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005881}
5882#endif /* device macros */
5883
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005884
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005885#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005886PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005887"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005888Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005889
Barry Warsaw53699e91996-12-10 23:23:01 +00005890static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005891posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005892{
Victor Stinner8c62be82010-05-06 00:08:46 +00005893 int fd;
5894 off_t length;
5895 int res;
5896 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005897
Victor Stinner8c62be82010-05-06 00:08:46 +00005898 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
5899 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005900
5901#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005902 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005903#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005904 length = PyLong_Check(lenobj) ?
5905 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005906#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005907 if (PyErr_Occurred())
5908 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005909
Victor Stinner8c62be82010-05-06 00:08:46 +00005910 Py_BEGIN_ALLOW_THREADS
5911 res = ftruncate(fd, length);
5912 Py_END_ALLOW_THREADS
5913 if (res < 0)
5914 return posix_error();
5915 Py_INCREF(Py_None);
5916 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005917}
5918#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005919
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005920#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005921PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005922"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005923Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005924
Fred Drake762e2061999-08-26 17:23:54 +00005925/* Save putenv() parameters as values here, so we can collect them when they
5926 * get re-set with another call for the same key. */
5927static PyObject *posix_putenv_garbage;
5928
Tim Peters5aa91602002-01-30 05:46:57 +00005929static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005930posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005931{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005932#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005933 wchar_t *s1, *s2;
5934 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005935#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005936 PyObject *os1, *os2;
5937 char *s1, *s2;
5938 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005939#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005940 PyObject *newstr = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005941 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005942
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005943#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005944 if (!PyArg_ParseTuple(args,
5945 "uu:putenv",
5946 &s1, &s2))
5947 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005948#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005949 if (!PyArg_ParseTuple(args,
5950 "O&O&:putenv",
5951 PyUnicode_FSConverter, &os1,
5952 PyUnicode_FSConverter, &os2))
5953 return NULL;
5954 s1 = PyBytes_AsString(os1);
5955 s2 = PyBytes_AsString(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005956#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005957
5958#if defined(PYOS_OS2)
5959 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5960 APIRET rc;
5961
Guido van Rossumd48f2521997-12-05 22:19:34 +00005962 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005963 if (rc != NO_ERROR) {
5964 os2_error(rc);
5965 goto error;
5966 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005967
5968 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5969 APIRET rc;
5970
Guido van Rossumd48f2521997-12-05 22:19:34 +00005971 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005972 if (rc != NO_ERROR) {
5973 os2_error(rc);
5974 goto error;
5975 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005976 } else {
5977#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005978 /* XXX This can leak memory -- not easy to fix :-( */
5979 /* len includes space for a trailing \0; the size arg to
5980 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005981#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005982 len = wcslen(s1) + wcslen(s2) + 2;
5983 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005984#else
Victor Stinner84ae1182010-05-06 22:05:07 +00005985 len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2;
Victor Stinner8c62be82010-05-06 00:08:46 +00005986 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005987#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005988 if (newstr == NULL) {
5989 PyErr_NoMemory();
5990 goto error;
5991 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005992#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005993 newenv = PyUnicode_AsUnicode(newstr);
5994 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5995 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005996 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00005997 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005998 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005999#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006000 newenv = PyBytes_AS_STRING(newstr);
6001 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6002 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006003 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00006004 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006005 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006006#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006007
Victor Stinner8c62be82010-05-06 00:08:46 +00006008 /* Install the first arg and newstr in posix_putenv_garbage;
6009 * this will cause previous value to be collected. This has to
6010 * happen after the real putenv() call because the old value
6011 * was still accessible until then. */
6012 if (PyDict_SetItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00006013#ifdef MS_WINDOWS
6014 PyTuple_GET_ITEM(args, 0),
6015#else
6016 os1,
6017#endif
6018 newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006019 /* really not much we can do; just leak */
6020 PyErr_Clear();
6021 }
6022 else {
6023 Py_DECREF(newstr);
6024 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006025
6026#if defined(PYOS_OS2)
6027 }
6028#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006029
Martin v. Löwis011e8422009-05-05 04:43:17 +00006030#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006031 Py_DECREF(os1);
6032 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00006033#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006034 Py_RETURN_NONE;
6035
6036error:
6037#ifndef MS_WINDOWS
6038 Py_DECREF(os1);
6039 Py_DECREF(os2);
6040#endif
6041 Py_XDECREF(newstr);
6042 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006043}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006044#endif /* putenv */
6045
Guido van Rossumc524d952001-10-19 01:31:59 +00006046#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006047PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006048"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006049Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006050
6051static PyObject *
6052posix_unsetenv(PyObject *self, PyObject *args)
6053{
Victor Stinner84ae1182010-05-06 22:05:07 +00006054#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006055 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00006056
Victor Stinner8c62be82010-05-06 00:08:46 +00006057 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6058 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00006059#else
6060 PyObject *os1;
6061 char *s1;
6062
6063 if (!PyArg_ParseTuple(args, "O&:unsetenv",
6064 PyUnicode_FSConverter, &os1))
6065 return NULL;
6066 s1 = PyBytes_AsString(os1);
6067#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006068
Victor Stinner8c62be82010-05-06 00:08:46 +00006069 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00006070
Victor Stinner8c62be82010-05-06 00:08:46 +00006071 /* Remove the key from posix_putenv_garbage;
6072 * this will cause it to be collected. This has to
6073 * happen after the real unsetenv() call because the
6074 * old value was still accessible until then.
6075 */
6076 if (PyDict_DelItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00006077#ifdef MS_WINDOWS
6078 PyTuple_GET_ITEM(args, 0)
6079#else
6080 os1
6081#endif
6082 )) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006083 /* really not much we can do; just leak */
6084 PyErr_Clear();
6085 }
Guido van Rossumc524d952001-10-19 01:31:59 +00006086
Victor Stinner84ae1182010-05-06 22:05:07 +00006087#ifndef MS_WINDOWS
6088 Py_DECREF(os1);
6089#endif
6090 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00006091}
6092#endif /* unsetenv */
6093
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006094PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006095"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006096Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006097
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006098static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006099posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006100{
Victor Stinner8c62be82010-05-06 00:08:46 +00006101 int code;
6102 char *message;
6103 if (!PyArg_ParseTuple(args, "i:strerror", &code))
6104 return NULL;
6105 message = strerror(code);
6106 if (message == NULL) {
6107 PyErr_SetString(PyExc_ValueError,
6108 "strerror() argument out of range");
6109 return NULL;
6110 }
6111 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006112}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006113
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006114
Guido van Rossumc9641791998-08-04 15:26:23 +00006115#ifdef HAVE_SYS_WAIT_H
6116
Fred Drake106c1a02002-04-23 15:58:02 +00006117#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006118PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006119"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006120Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006121
6122static PyObject *
6123posix_WCOREDUMP(PyObject *self, PyObject *args)
6124{
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:WCOREDUMP", &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(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006132}
6133#endif /* WCOREDUMP */
6134
6135#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006136PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006137"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006138Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006139job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006140
6141static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006142posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006143{
Victor Stinner8c62be82010-05-06 00:08:46 +00006144 WAIT_TYPE status;
6145 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006146
Victor Stinner8c62be82010-05-06 00:08:46 +00006147 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
6148 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006149
Victor Stinner8c62be82010-05-06 00:08:46 +00006150 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006151}
6152#endif /* WIFCONTINUED */
6153
Guido van Rossumc9641791998-08-04 15:26:23 +00006154#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006155PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006156"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006157Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006158
6159static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006160posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006161{
Victor Stinner8c62be82010-05-06 00:08:46 +00006162 WAIT_TYPE status;
6163 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006164
Victor Stinner8c62be82010-05-06 00:08:46 +00006165 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
6166 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006167
Victor Stinner8c62be82010-05-06 00:08:46 +00006168 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006169}
6170#endif /* WIFSTOPPED */
6171
6172#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006173PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006174"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006175Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006176
6177static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006178posix_WIFSIGNALED(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:WIFSIGNALED", &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(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006187}
6188#endif /* WIFSIGNALED */
6189
6190#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006191PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006192"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006193Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006194system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006195
6196static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006197posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006198{
Victor Stinner8c62be82010-05-06 00:08:46 +00006199 WAIT_TYPE status;
6200 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006201
Victor Stinner8c62be82010-05-06 00:08:46 +00006202 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
6203 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006204
Victor Stinner8c62be82010-05-06 00:08:46 +00006205 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006206}
6207#endif /* WIFEXITED */
6208
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006209#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006210PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006211"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006212Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006213
6214static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006215posix_WEXITSTATUS(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:WEXITSTATUS", &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", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006224}
6225#endif /* WEXITSTATUS */
6226
6227#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006228PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006229"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006230Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006231value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006232
6233static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006234posix_WTERMSIG(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:WTERMSIG", &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", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006243}
6244#endif /* WTERMSIG */
6245
6246#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006247PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006248"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006249Return the signal that stopped the process that provided\n\
6250the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006251
6252static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006253posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006254{
Victor Stinner8c62be82010-05-06 00:08:46 +00006255 WAIT_TYPE status;
6256 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006257
Victor Stinner8c62be82010-05-06 00:08:46 +00006258 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
6259 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006260
Victor Stinner8c62be82010-05-06 00:08:46 +00006261 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006262}
6263#endif /* WSTOPSIG */
6264
6265#endif /* HAVE_SYS_WAIT_H */
6266
6267
Thomas Wouters477c8d52006-05-27 19:21:47 +00006268#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006269#ifdef _SCO_DS
6270/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6271 needed definitions in sys/statvfs.h */
6272#define _SVID3
6273#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006274#include <sys/statvfs.h>
6275
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006276static PyObject*
6277_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006278 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6279 if (v == NULL)
6280 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006281
6282#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006283 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6284 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6285 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
6286 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
6287 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
6288 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
6289 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
6290 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
6291 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6292 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006293#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006294 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6295 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6296 PyStructSequence_SET_ITEM(v, 2,
6297 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
6298 PyStructSequence_SET_ITEM(v, 3,
6299 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
6300 PyStructSequence_SET_ITEM(v, 4,
6301 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
6302 PyStructSequence_SET_ITEM(v, 5,
6303 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
6304 PyStructSequence_SET_ITEM(v, 6,
6305 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
6306 PyStructSequence_SET_ITEM(v, 7,
6307 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
6308 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6309 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006310#endif
6311
Victor Stinner8c62be82010-05-06 00:08:46 +00006312 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006313}
6314
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006315PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006316"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006317Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006318
6319static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006320posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006321{
Victor Stinner8c62be82010-05-06 00:08:46 +00006322 int fd, res;
6323 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006324
Victor Stinner8c62be82010-05-06 00:08:46 +00006325 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
6326 return NULL;
6327 Py_BEGIN_ALLOW_THREADS
6328 res = fstatvfs(fd, &st);
6329 Py_END_ALLOW_THREADS
6330 if (res != 0)
6331 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006332
Victor Stinner8c62be82010-05-06 00:08:46 +00006333 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006334}
Thomas Wouters477c8d52006-05-27 19:21:47 +00006335#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006336
6337
Thomas Wouters477c8d52006-05-27 19:21:47 +00006338#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006339#include <sys/statvfs.h>
6340
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006341PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006342"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006343Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006344
6345static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006346posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006347{
Victor Stinner8c62be82010-05-06 00:08:46 +00006348 char *path;
6349 int res;
6350 struct statvfs st;
6351 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
6352 return NULL;
6353 Py_BEGIN_ALLOW_THREADS
6354 res = statvfs(path, &st);
6355 Py_END_ALLOW_THREADS
6356 if (res != 0)
6357 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006358
Victor Stinner8c62be82010-05-06 00:08:46 +00006359 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006360}
6361#endif /* HAVE_STATVFS */
6362
Fred Drakec9680921999-12-13 16:37:25 +00006363/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6364 * It maps strings representing configuration variable names to
6365 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006366 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006367 * rarely-used constants. There are three separate tables that use
6368 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006369 *
6370 * This code is always included, even if none of the interfaces that
6371 * need it are included. The #if hackery needed to avoid it would be
6372 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006373 */
6374struct constdef {
6375 char *name;
6376 long value;
6377};
6378
Fred Drake12c6e2d1999-12-14 21:25:03 +00006379static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006380conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00006381 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006382{
Christian Heimes217cfd12007-12-02 14:31:20 +00006383 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006384 *valuep = PyLong_AS_LONG(arg);
6385 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006386 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00006387 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00006388 /* look up the value in the table using a binary search */
6389 size_t lo = 0;
6390 size_t mid;
6391 size_t hi = tablesize;
6392 int cmp;
6393 const char *confname;
6394 if (!PyUnicode_Check(arg)) {
6395 PyErr_SetString(PyExc_TypeError,
6396 "configuration names must be strings or integers");
6397 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006398 }
Stefan Krah0e803b32010-11-26 16:16:47 +00006399 confname = _PyUnicode_AsString(arg);
6400 if (confname == NULL)
6401 return 0;
6402 while (lo < hi) {
6403 mid = (lo + hi) / 2;
6404 cmp = strcmp(confname, table[mid].name);
6405 if (cmp < 0)
6406 hi = mid;
6407 else if (cmp > 0)
6408 lo = mid + 1;
6409 else {
6410 *valuep = table[mid].value;
6411 return 1;
6412 }
6413 }
6414 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6415 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006416 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00006417}
6418
6419
6420#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6421static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006422#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006423 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006424#endif
6425#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006426 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006427#endif
Fred Drakec9680921999-12-13 16:37:25 +00006428#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006429 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006430#endif
6431#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00006432 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00006433#endif
6434#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00006435 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00006436#endif
6437#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00006438 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00006439#endif
6440#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006441 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006442#endif
6443#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00006444 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00006445#endif
6446#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00006447 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00006448#endif
6449#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006450 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006451#endif
6452#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006453 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00006454#endif
6455#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006456 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006457#endif
6458#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006459 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00006460#endif
6461#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006462 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006463#endif
6464#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006465 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00006466#endif
6467#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006468 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006469#endif
6470#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00006471 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00006472#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00006473#ifdef _PC_ACL_ENABLED
6474 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
6475#endif
6476#ifdef _PC_MIN_HOLE_SIZE
6477 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
6478#endif
6479#ifdef _PC_ALLOC_SIZE_MIN
6480 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
6481#endif
6482#ifdef _PC_REC_INCR_XFER_SIZE
6483 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
6484#endif
6485#ifdef _PC_REC_MAX_XFER_SIZE
6486 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
6487#endif
6488#ifdef _PC_REC_MIN_XFER_SIZE
6489 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
6490#endif
6491#ifdef _PC_REC_XFER_ALIGN
6492 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
6493#endif
6494#ifdef _PC_SYMLINK_MAX
6495 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
6496#endif
6497#ifdef _PC_XATTR_ENABLED
6498 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
6499#endif
6500#ifdef _PC_XATTR_EXISTS
6501 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
6502#endif
6503#ifdef _PC_TIMESTAMP_RESOLUTION
6504 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
6505#endif
Fred Drakec9680921999-12-13 16:37:25 +00006506};
6507
Fred Drakec9680921999-12-13 16:37:25 +00006508static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006509conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006510{
6511 return conv_confname(arg, valuep, posix_constants_pathconf,
6512 sizeof(posix_constants_pathconf)
6513 / sizeof(struct constdef));
6514}
6515#endif
6516
6517#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006518PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006519"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006520Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006521If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006522
6523static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006524posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006525{
6526 PyObject *result = NULL;
6527 int name, fd;
6528
Fred Drake12c6e2d1999-12-14 21:25:03 +00006529 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6530 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006531 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006532
Stefan Krah0e803b32010-11-26 16:16:47 +00006533 errno = 0;
6534 limit = fpathconf(fd, name);
6535 if (limit == -1 && errno != 0)
6536 posix_error();
6537 else
6538 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006539 }
6540 return result;
6541}
6542#endif
6543
6544
6545#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006546PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006547"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006548Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006549If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006550
6551static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006552posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006553{
6554 PyObject *result = NULL;
6555 int name;
6556 char *path;
6557
6558 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6559 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006560 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006561
Victor Stinner8c62be82010-05-06 00:08:46 +00006562 errno = 0;
6563 limit = pathconf(path, name);
6564 if (limit == -1 && errno != 0) {
6565 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00006566 /* could be a path or name problem */
6567 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00006568 else
Stefan Krah99439262010-11-26 12:58:05 +00006569 posix_error_with_filename(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00006570 }
6571 else
6572 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006573 }
6574 return result;
6575}
6576#endif
6577
6578#ifdef HAVE_CONFSTR
6579static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006580#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00006581 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00006582#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00006583#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006584 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006585#endif
6586#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006587 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006588#endif
Fred Draked86ed291999-12-15 15:34:33 +00006589#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006590 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006591#endif
6592#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006593 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006594#endif
6595#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006596 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006597#endif
6598#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006599 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006600#endif
Fred Drakec9680921999-12-13 16:37:25 +00006601#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006602 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006603#endif
6604#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006605 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006606#endif
6607#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006608 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006609#endif
6610#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006611 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006612#endif
6613#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006614 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006615#endif
6616#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006617 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006618#endif
6619#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006620 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006621#endif
6622#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006623 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006624#endif
Fred Draked86ed291999-12-15 15:34:33 +00006625#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00006626 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00006627#endif
Fred Drakec9680921999-12-13 16:37:25 +00006628#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00006629 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00006630#endif
Fred Draked86ed291999-12-15 15:34:33 +00006631#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006632 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00006633#endif
6634#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006635 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00006636#endif
6637#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006638 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006639#endif
6640#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006641 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00006642#endif
Fred Drakec9680921999-12-13 16:37:25 +00006643#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006644 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006645#endif
6646#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006647 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006648#endif
6649#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006650 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006651#endif
6652#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006653 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006654#endif
6655#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006656 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006657#endif
6658#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006659 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006660#endif
6661#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006662 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006663#endif
6664#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006665 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006666#endif
6667#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006668 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006669#endif
6670#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006671 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006672#endif
6673#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006674 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006675#endif
6676#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006677 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006678#endif
6679#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006680 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006681#endif
6682#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006683 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006684#endif
6685#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006686 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006687#endif
6688#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006689 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006690#endif
Fred Draked86ed291999-12-15 15:34:33 +00006691#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006692 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006693#endif
6694#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006695 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00006696#endif
6697#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00006698 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00006699#endif
6700#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006701 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006702#endif
6703#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006704 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006705#endif
6706#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00006707 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00006708#endif
6709#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006710 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00006711#endif
6712#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00006713 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00006714#endif
6715#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006716 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006717#endif
6718#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006719 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006720#endif
6721#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006722 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006723#endif
6724#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006725 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006726#endif
6727#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00006728 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00006729#endif
Fred Drakec9680921999-12-13 16:37:25 +00006730};
6731
6732static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006733conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006734{
6735 return conv_confname(arg, valuep, posix_constants_confstr,
6736 sizeof(posix_constants_confstr)
6737 / sizeof(struct constdef));
6738}
6739
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006740PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006741"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006742Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006743
6744static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006745posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006746{
6747 PyObject *result = NULL;
6748 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00006749 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00006750 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006751
Victor Stinnercb043522010-09-10 23:49:04 +00006752 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
6753 return NULL;
6754
6755 errno = 0;
6756 len = confstr(name, buffer, sizeof(buffer));
6757 if (len == 0) {
6758 if (errno) {
6759 posix_error();
6760 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00006761 }
6762 else {
Victor Stinnercb043522010-09-10 23:49:04 +00006763 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00006764 }
6765 }
Victor Stinnercb043522010-09-10 23:49:04 +00006766
6767 if ((unsigned int)len >= sizeof(buffer)) {
6768 char *buf = PyMem_Malloc(len);
6769 if (buf == NULL)
6770 return PyErr_NoMemory();
6771 confstr(name, buf, len);
6772 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
6773 PyMem_Free(buf);
6774 }
6775 else
6776 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006777 return result;
6778}
6779#endif
6780
6781
6782#ifdef HAVE_SYSCONF
6783static struct constdef posix_constants_sysconf[] = {
6784#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00006785 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00006786#endif
6787#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00006788 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00006789#endif
6790#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006791 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006792#endif
6793#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006794 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006795#endif
6796#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006797 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006798#endif
6799#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00006801#endif
6802#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00006803 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00006804#endif
6805#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006806 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006807#endif
6808#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00006809 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00006810#endif
6811#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006812 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006813#endif
Fred Draked86ed291999-12-15 15:34:33 +00006814#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006815 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006816#endif
6817#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00006818 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00006819#endif
Fred Drakec9680921999-12-13 16:37:25 +00006820#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006821 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006822#endif
Fred Drakec9680921999-12-13 16:37:25 +00006823#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006824 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006825#endif
6826#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006827 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006828#endif
6829#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006830 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006831#endif
6832#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006833 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006834#endif
6835#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006836 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006837#endif
Fred Draked86ed291999-12-15 15:34:33 +00006838#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006839 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00006840#endif
Fred Drakec9680921999-12-13 16:37:25 +00006841#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00006842 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006843#endif
6844#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006845 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006846#endif
6847#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006848 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006849#endif
6850#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006851 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006852#endif
6853#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006854 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006855#endif
Fred Draked86ed291999-12-15 15:34:33 +00006856#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00006857 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00006858#endif
Fred Drakec9680921999-12-13 16:37:25 +00006859#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006860 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006861#endif
6862#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006863 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006864#endif
6865#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006866 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006867#endif
6868#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006869 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006870#endif
6871#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006872 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006873#endif
6874#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006875 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00006876#endif
6877#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006878 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006879#endif
6880#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006881 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006882#endif
6883#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006884 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006885#endif
6886#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006887 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006888#endif
6889#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006890 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006891#endif
6892#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006893 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006894#endif
6895#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006896 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006897#endif
6898#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006899 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006900#endif
6901#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006902 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006903#endif
6904#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006905 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006906#endif
6907#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006908 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00006909#endif
6910#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006911 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006912#endif
6913#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006914 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006915#endif
6916#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006917 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006918#endif
6919#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006920 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006921#endif
6922#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006923 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006924#endif
6925#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006926 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006927#endif
Fred Draked86ed291999-12-15 15:34:33 +00006928#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00006929 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00006930#endif
Fred Drakec9680921999-12-13 16:37:25 +00006931#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006932 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006933#endif
6934#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006935 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006936#endif
6937#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006938 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006939#endif
Fred Draked86ed291999-12-15 15:34:33 +00006940#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006941 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00006942#endif
Fred Drakec9680921999-12-13 16:37:25 +00006943#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00006944 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00006945#endif
Fred Draked86ed291999-12-15 15:34:33 +00006946#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00006947 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00006948#endif
6949#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00006950 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00006951#endif
Fred Drakec9680921999-12-13 16:37:25 +00006952#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006953 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006954#endif
6955#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006956 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006957#endif
6958#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006959 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006960#endif
6961#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006962 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006963#endif
Fred Draked86ed291999-12-15 15:34:33 +00006964#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00006965 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00006966#endif
Fred Drakec9680921999-12-13 16:37:25 +00006967#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00006968 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00006969#endif
6970#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00006971 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00006972#endif
6973#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006974 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006975#endif
6976#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006977 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00006978#endif
6979#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00006980 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00006981#endif
6982#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00006983 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00006984#endif
6985#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00006986 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00006987#endif
Fred Draked86ed291999-12-15 15:34:33 +00006988#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00006989 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00006990#endif
Fred Drakec9680921999-12-13 16:37:25 +00006991#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006992 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006993#endif
6994#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006995 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006996#endif
Fred Draked86ed291999-12-15 15:34:33 +00006997#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006998 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006999#endif
Fred Drakec9680921999-12-13 16:37:25 +00007000#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007001 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007002#endif
7003#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007004 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007005#endif
7006#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007007 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007008#endif
7009#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007010 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007011#endif
7012#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007013 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007014#endif
7015#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007016 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007017#endif
7018#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007019 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007020#endif
7021#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007022 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00007023#endif
7024#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00007025 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00007026#endif
Fred Draked86ed291999-12-15 15:34:33 +00007027#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007028 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00007029#endif
7030#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00007031 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00007032#endif
Fred Drakec9680921999-12-13 16:37:25 +00007033#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00007034 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00007035#endif
7036#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007037 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007038#endif
7039#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007040 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007041#endif
7042#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007043 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007044#endif
7045#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007046 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007047#endif
7048#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00007049 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00007050#endif
7051#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00007052 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00007053#endif
7054#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00007055 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00007056#endif
7057#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00007058 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00007059#endif
7060#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00007061 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00007062#endif
7063#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00007064 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00007065#endif
7066#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007067 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00007068#endif
7069#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007070 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00007071#endif
7072#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00007073 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00007074#endif
7075#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00007076 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00007077#endif
7078#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00007079 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00007080#endif
7081#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00007082 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00007083#endif
7084#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007085 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007086#endif
7087#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007088 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007089#endif
7090#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00007091 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00007092#endif
7093#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007094 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007095#endif
7096#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007097 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007098#endif
7099#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00007100 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00007101#endif
7102#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007103 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007104#endif
7105#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007106 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007107#endif
7108#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007109 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00007110#endif
7111#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00007112 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00007113#endif
7114#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007115 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007116#endif
7117#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007118 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007119#endif
7120#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007121 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00007122#endif
7123#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007124 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007125#endif
7126#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007127 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007128#endif
7129#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007130 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007131#endif
7132#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007133 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007134#endif
7135#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007136 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007137#endif
Fred Draked86ed291999-12-15 15:34:33 +00007138#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00007139 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00007140#endif
Fred Drakec9680921999-12-13 16:37:25 +00007141#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00007142 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00007143#endif
7144#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007145 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007146#endif
7147#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00007148 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00007149#endif
7150#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007151 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007152#endif
7153#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007154 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007155#endif
7156#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007157 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007158#endif
7159#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00007160 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00007161#endif
7162#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007163 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007164#endif
7165#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007166 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007167#endif
7168#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007169 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007170#endif
7171#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007172 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007173#endif
7174#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007175 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00007176#endif
7177#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007178 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00007179#endif
7180#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00007181 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00007182#endif
7183#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007184 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007185#endif
7186#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007187 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007188#endif
7189#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007190 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007191#endif
7192#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00007193 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00007194#endif
7195#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007196 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007197#endif
7198#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007199 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007200#endif
7201#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007202 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007203#endif
7204#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007205 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007206#endif
7207#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007208 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007209#endif
7210#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007211 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007212#endif
7213#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00007214 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00007215#endif
7216#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007217 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007218#endif
7219#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007220 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007221#endif
7222#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007223 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007224#endif
7225#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007226 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007227#endif
7228#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00007229 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00007230#endif
7231#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007232 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007233#endif
7234#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00007235 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00007236#endif
7237#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007238 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007239#endif
7240#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00007241 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00007242#endif
7243#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00007244 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00007245#endif
7246#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00007247 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00007248#endif
7249#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00007250 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00007251#endif
7252#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007253 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007254#endif
7255#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00007256 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00007257#endif
7258#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00007259 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00007260#endif
7261#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007262 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007263#endif
7264#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007265 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007266#endif
7267#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00007268 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00007269#endif
7270#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00007271 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00007272#endif
7273#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00007274 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00007275#endif
7276};
7277
7278static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007279conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007280{
7281 return conv_confname(arg, valuep, posix_constants_sysconf,
7282 sizeof(posix_constants_sysconf)
7283 / sizeof(struct constdef));
7284}
7285
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007286PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007287"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007288Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007289
7290static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007291posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007292{
7293 PyObject *result = NULL;
7294 int name;
7295
7296 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7297 int value;
7298
7299 errno = 0;
7300 value = sysconf(name);
7301 if (value == -1 && errno != 0)
7302 posix_error();
7303 else
Christian Heimes217cfd12007-12-02 14:31:20 +00007304 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00007305 }
7306 return result;
7307}
7308#endif
7309
7310
Fred Drakebec628d1999-12-15 18:31:10 +00007311/* This code is used to ensure that the tables of configuration value names
7312 * are in sorted order as required by conv_confname(), and also to build the
7313 * the exported dictionaries that are used to publish information about the
7314 * names available on the host platform.
7315 *
7316 * Sorting the table at runtime ensures that the table is properly ordered
7317 * when used, even for platforms we're not able to test on. It also makes
7318 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007319 */
Fred Drakebec628d1999-12-15 18:31:10 +00007320
7321static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007322cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007323{
7324 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007325 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00007326 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007327 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00007328
7329 return strcmp(c1->name, c2->name);
7330}
7331
7332static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007333setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00007334 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007335{
Fred Drakebec628d1999-12-15 18:31:10 +00007336 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007337 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007338
7339 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7340 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007341 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00007342 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007343
Barry Warsaw3155db32000-04-13 15:20:40 +00007344 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007345 PyObject *o = PyLong_FromLong(table[i].value);
7346 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7347 Py_XDECREF(o);
7348 Py_DECREF(d);
7349 return -1;
7350 }
7351 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007352 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007353 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007354}
7355
Fred Drakebec628d1999-12-15 18:31:10 +00007356/* Return -1 on failure, 0 on success. */
7357static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007358setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007359{
7360#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007361 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007362 sizeof(posix_constants_pathconf)
7363 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007364 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00007365 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007366#endif
7367#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007368 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007369 sizeof(posix_constants_confstr)
7370 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007371 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00007372 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007373#endif
7374#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007375 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007376 sizeof(posix_constants_sysconf)
7377 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007378 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00007379 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007380#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007381 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007382}
Fred Draked86ed291999-12-15 15:34:33 +00007383
7384
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007385PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007386"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007387Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007388in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007389
7390static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007391posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007392{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007393 abort();
7394 /*NOTREACHED*/
7395 Py_FatalError("abort() called from Python code didn't abort!");
7396 return NULL;
7397}
Fred Drakebec628d1999-12-15 18:31:10 +00007398
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007399#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007400PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007401"startfile(filepath [, operation]) - Start a file with its associated\n\
7402application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007403\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007404When \"operation\" is not specified or \"open\", this acts like\n\
7405double-clicking the file in Explorer, or giving the file name as an\n\
7406argument to the DOS \"start\" command: the file is opened with whatever\n\
7407application (if any) its extension is associated.\n\
7408When another \"operation\" is given, it specifies what should be done with\n\
7409the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007410\n\
7411startfile returns as soon as the associated application is launched.\n\
7412There is no option to wait for the application to close, and no way\n\
7413to retrieve the application's exit status.\n\
7414\n\
7415The filepath is relative to the current directory. If you want to use\n\
7416an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007417the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007418
7419static PyObject *
7420win32_startfile(PyObject *self, PyObject *args)
7421{
Victor Stinner8c62be82010-05-06 00:08:46 +00007422 PyObject *ofilepath;
7423 char *filepath;
7424 char *operation = NULL;
7425 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00007426
Victor Stinner8c62be82010-05-06 00:08:46 +00007427 PyObject *unipath, *woperation = NULL;
7428 if (!PyArg_ParseTuple(args, "U|s:startfile",
7429 &unipath, &operation)) {
7430 PyErr_Clear();
7431 goto normal;
7432 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007433
Victor Stinner8c62be82010-05-06 00:08:46 +00007434 if (operation) {
7435 woperation = PyUnicode_DecodeASCII(operation,
7436 strlen(operation), NULL);
7437 if (!woperation) {
7438 PyErr_Clear();
7439 operation = NULL;
7440 goto normal;
7441 }
7442 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007443
Victor Stinner8c62be82010-05-06 00:08:46 +00007444 Py_BEGIN_ALLOW_THREADS
7445 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
7446 PyUnicode_AS_UNICODE(unipath),
7447 NULL, NULL, SW_SHOWNORMAL);
7448 Py_END_ALLOW_THREADS
7449
7450 Py_XDECREF(woperation);
7451 if (rc <= (HINSTANCE)32) {
7452 PyObject *errval = win32_error_unicode("startfile",
7453 PyUnicode_AS_UNICODE(unipath));
7454 return errval;
7455 }
7456 Py_INCREF(Py_None);
7457 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007458
7459normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00007460 if (!PyArg_ParseTuple(args, "O&|s:startfile",
7461 PyUnicode_FSConverter, &ofilepath,
7462 &operation))
7463 return NULL;
7464 filepath = PyBytes_AsString(ofilepath);
7465 Py_BEGIN_ALLOW_THREADS
7466 rc = ShellExecute((HWND)0, operation, filepath,
7467 NULL, NULL, SW_SHOWNORMAL);
7468 Py_END_ALLOW_THREADS
7469 if (rc <= (HINSTANCE)32) {
7470 PyObject *errval = win32_error("startfile", filepath);
7471 Py_DECREF(ofilepath);
7472 return errval;
7473 }
7474 Py_DECREF(ofilepath);
7475 Py_INCREF(Py_None);
7476 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007477}
7478#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007479
Martin v. Löwis438b5342002-12-27 10:16:42 +00007480#ifdef HAVE_GETLOADAVG
7481PyDoc_STRVAR(posix_getloadavg__doc__,
7482"getloadavg() -> (float, float, float)\n\n\
7483Return the number of processes in the system run queue averaged over\n\
7484the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7485was unobtainable");
7486
7487static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007488posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007489{
7490 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007491 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00007492 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7493 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00007494 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00007495 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00007496}
7497#endif
7498
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007499#ifdef MS_WINDOWS
7500
7501PyDoc_STRVAR(win32_urandom__doc__,
7502"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007503Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007504
7505typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7506 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7507 DWORD dwFlags );
7508typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7509 BYTE *pbBuffer );
7510
7511static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00007512/* This handle is never explicitly released. Instead, the operating
7513 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007514static HCRYPTPROV hCryptProv = 0;
7515
Tim Peters4ad82172004-08-30 17:02:04 +00007516static PyObject*
7517win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007518{
Victor Stinner8c62be82010-05-06 00:08:46 +00007519 int howMany;
7520 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007521
Victor Stinner8c62be82010-05-06 00:08:46 +00007522 /* Read arguments */
7523 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7524 return NULL;
7525 if (howMany < 0)
7526 return PyErr_Format(PyExc_ValueError,
7527 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007528
Victor Stinner8c62be82010-05-06 00:08:46 +00007529 if (hCryptProv == 0) {
7530 HINSTANCE hAdvAPI32 = NULL;
7531 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007532
Victor Stinner8c62be82010-05-06 00:08:46 +00007533 /* Obtain handle to the DLL containing CryptoAPI
7534 This should not fail */
7535 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7536 if(hAdvAPI32 == NULL)
7537 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007538
Victor Stinner8c62be82010-05-06 00:08:46 +00007539 /* Obtain pointers to the CryptoAPI functions
7540 This will fail on some early versions of Win95 */
7541 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7542 hAdvAPI32,
7543 "CryptAcquireContextA");
7544 if (pCryptAcquireContext == NULL)
7545 return PyErr_Format(PyExc_NotImplementedError,
7546 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007547
Victor Stinner8c62be82010-05-06 00:08:46 +00007548 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7549 hAdvAPI32, "CryptGenRandom");
7550 if (pCryptGenRandom == NULL)
7551 return PyErr_Format(PyExc_NotImplementedError,
7552 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007553
Victor Stinner8c62be82010-05-06 00:08:46 +00007554 /* Acquire context */
7555 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7556 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7557 return win32_error("CryptAcquireContext", NULL);
7558 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007559
Victor Stinner8c62be82010-05-06 00:08:46 +00007560 /* Allocate bytes */
7561 result = PyBytes_FromStringAndSize(NULL, howMany);
7562 if (result != NULL) {
7563 /* Get random data */
7564 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
7565 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7566 PyBytes_AS_STRING(result))) {
7567 Py_DECREF(result);
7568 return win32_error("CryptGenRandom", NULL);
7569 }
7570 }
7571 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007572}
7573#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007574
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007575PyDoc_STRVAR(device_encoding__doc__,
7576"device_encoding(fd) -> str\n\n\
7577Return a string describing the encoding of the device\n\
7578if the output is a terminal; else return None.");
7579
7580static PyObject *
7581device_encoding(PyObject *self, PyObject *args)
7582{
Victor Stinner8c62be82010-05-06 00:08:46 +00007583 int fd;
7584 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
7585 return NULL;
7586 if (!_PyVerify_fd(fd) || !isatty(fd)) {
7587 Py_INCREF(Py_None);
7588 return Py_None;
7589 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007590#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner8c62be82010-05-06 00:08:46 +00007591 if (fd == 0) {
7592 char buf[100];
7593 sprintf(buf, "cp%d", GetConsoleCP());
7594 return PyUnicode_FromString(buf);
7595 }
7596 if (fd == 1 || fd == 2) {
7597 char buf[100];
7598 sprintf(buf, "cp%d", GetConsoleOutputCP());
7599 return PyUnicode_FromString(buf);
7600 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007601#elif defined(CODESET)
Victor Stinner8c62be82010-05-06 00:08:46 +00007602 {
7603 char *codeset = nl_langinfo(CODESET);
7604 if (codeset != NULL && codeset[0] != 0)
7605 return PyUnicode_FromString(codeset);
7606 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007607#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007608 Py_INCREF(Py_None);
7609 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007610}
7611
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007612#ifdef __VMS
7613/* Use openssl random routine */
7614#include <openssl/rand.h>
7615PyDoc_STRVAR(vms_urandom__doc__,
7616"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007617Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007618
7619static PyObject*
7620vms_urandom(PyObject *self, PyObject *args)
7621{
Victor Stinner8c62be82010-05-06 00:08:46 +00007622 int howMany;
7623 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007624
Victor Stinner8c62be82010-05-06 00:08:46 +00007625 /* Read arguments */
7626 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7627 return NULL;
7628 if (howMany < 0)
7629 return PyErr_Format(PyExc_ValueError,
7630 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007631
Victor Stinner8c62be82010-05-06 00:08:46 +00007632 /* Allocate bytes */
7633 result = PyBytes_FromStringAndSize(NULL, howMany);
7634 if (result != NULL) {
7635 /* Get random data */
7636 if (RAND_pseudo_bytes((unsigned char*)
7637 PyBytes_AS_STRING(result),
7638 howMany) < 0) {
7639 Py_DECREF(result);
7640 return PyErr_Format(PyExc_ValueError,
7641 "RAND_pseudo_bytes");
7642 }
7643 }
7644 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007645}
7646#endif
7647
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007648#ifdef HAVE_SETRESUID
7649PyDoc_STRVAR(posix_setresuid__doc__,
7650"setresuid(ruid, euid, suid)\n\n\
7651Set the current process's real, effective, and saved user ids.");
7652
7653static PyObject*
7654posix_setresuid (PyObject *self, PyObject *args)
7655{
Victor Stinner8c62be82010-05-06 00:08:46 +00007656 /* We assume uid_t is no larger than a long. */
7657 long ruid, euid, suid;
7658 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
7659 return NULL;
7660 if (setresuid(ruid, euid, suid) < 0)
7661 return posix_error();
7662 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007663}
7664#endif
7665
7666#ifdef HAVE_SETRESGID
7667PyDoc_STRVAR(posix_setresgid__doc__,
7668"setresgid(rgid, egid, sgid)\n\n\
7669Set the current process's real, effective, and saved group ids.");
7670
7671static PyObject*
7672posix_setresgid (PyObject *self, PyObject *args)
7673{
Victor Stinner8c62be82010-05-06 00:08:46 +00007674 /* We assume uid_t is no larger than a long. */
7675 long rgid, egid, sgid;
7676 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
7677 return NULL;
7678 if (setresgid(rgid, egid, sgid) < 0)
7679 return posix_error();
7680 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007681}
7682#endif
7683
7684#ifdef HAVE_GETRESUID
7685PyDoc_STRVAR(posix_getresuid__doc__,
7686"getresuid() -> (ruid, euid, suid)\n\n\
7687Get tuple of the current process's real, effective, and saved user ids.");
7688
7689static PyObject*
7690posix_getresuid (PyObject *self, PyObject *noargs)
7691{
Victor Stinner8c62be82010-05-06 00:08:46 +00007692 uid_t ruid, euid, suid;
7693 long l_ruid, l_euid, l_suid;
7694 if (getresuid(&ruid, &euid, &suid) < 0)
7695 return posix_error();
7696 /* Force the values into long's as we don't know the size of uid_t. */
7697 l_ruid = ruid;
7698 l_euid = euid;
7699 l_suid = suid;
7700 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007701}
7702#endif
7703
7704#ifdef HAVE_GETRESGID
7705PyDoc_STRVAR(posix_getresgid__doc__,
7706"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00007707Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007708
7709static PyObject*
7710posix_getresgid (PyObject *self, PyObject *noargs)
7711{
Victor Stinner8c62be82010-05-06 00:08:46 +00007712 uid_t rgid, egid, sgid;
7713 long l_rgid, l_egid, l_sgid;
7714 if (getresgid(&rgid, &egid, &sgid) < 0)
7715 return posix_error();
7716 /* Force the values into long's as we don't know the size of uid_t. */
7717 l_rgid = rgid;
7718 l_egid = egid;
7719 l_sgid = sgid;
7720 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007721}
7722#endif
7723
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007724static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00007725 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007726#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007727 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007728#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007729 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007730#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007731 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007732#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007733 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007734#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007735 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007736#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007737#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007738 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007739#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00007740#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007741 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007742#endif /* HAVE_LCHMOD */
7743#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007744 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007745#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00007746#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007747 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007748#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007749#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007750 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007751#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007752#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +00007753 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00007754#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007755#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +00007756 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007757#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007758#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +00007759 {"getcwd", (PyCFunction)posix_getcwd_unicode,
7760 METH_NOARGS, posix_getcwd__doc__},
7761 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
7762 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007763#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007764#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007765 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007766#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +00007767 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7768 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7769 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007770#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +00007771 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007772#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007773#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007774 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007775#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007776#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007777 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007778#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007779 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7780 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7781 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +00007782 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007783#ifdef HAVE_SYMLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007784 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007785#endif /* HAVE_SYMLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007786#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin74e45612010-07-09 15:58:59 +00007787 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
7788 win_symlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007789#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007790#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +00007791 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007792#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007793 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007794#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007795 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007796#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +00007797 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7798 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7799 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007800#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00007801 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007802#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00007803 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007804#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +00007805 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7806 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007807#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007808#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +00007809 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7810 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007811#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00007812 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7813 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007814#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007815#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007816#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +00007817 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007818#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007819#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +00007820 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007821#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007822#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +00007823 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007824#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007825#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007826 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007827#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007828#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007829 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007830#endif /* HAVE_GETEGID */
7831#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007832 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007833#endif /* HAVE_GETEUID */
7834#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007835 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007836#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007837#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007838 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007839#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007840 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007841#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007842 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007843#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007844#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +00007845 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007846#endif /* HAVE_GETPPID */
7847#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007848 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007849#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007850#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007851 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007852#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007853#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +00007854 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007855#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007856#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +00007857 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007858#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007859#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007860 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007861#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007862#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007863 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7864 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Brian Curtin1b9df392010-11-24 20:24:31 +00007865 {"link", win32_link, METH_VARARGS, win32_link__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +00007866#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007867#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007868 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007869#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007870#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007871 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007872#endif /* HAVE_SETEUID */
7873#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007874 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007875#endif /* HAVE_SETEGID */
7876#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007877 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007878#endif /* HAVE_SETREUID */
7879#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007880 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007881#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007882#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007883 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007884#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007885#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007886 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007887#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +00007888#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007889 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +00007890#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007891#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007892 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00007893#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007894#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007895 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007896#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007897#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007898 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007899#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007900#ifdef HAVE_WAIT3
Victor Stinner8c62be82010-05-06 00:08:46 +00007901 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007902#endif /* HAVE_WAIT3 */
7903#ifdef HAVE_WAIT4
Victor Stinner8c62be82010-05-06 00:08:46 +00007904 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007905#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007906#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007907 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007908#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007909#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007910 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007911#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007912#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007913 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007914#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007915#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007916 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007917#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007918#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007919 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007920#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007921#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007922 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007923#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +00007924 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7925 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7926 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
7927 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
7928 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7929 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7930 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7931 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7932 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7933 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7934 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007935#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +00007936 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007937#endif
7938#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +00007939 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007940#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007941#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +00007942 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007943#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007944#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +00007945 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7946 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7947 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007948#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007949#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +00007950 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007951#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007952#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007953 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007954#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007955#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007956 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00007957#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007958 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007959#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +00007960 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007961#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007962#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007963 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007964#endif
7965#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007966 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007967#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007968#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007969#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +00007970 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00007971#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007972#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00007973 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007974#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007975#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +00007976 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007977#endif /* WIFSTOPPED */
7978#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +00007979 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007980#endif /* WIFSIGNALED */
7981#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +00007982 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007983#endif /* WIFEXITED */
7984#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +00007985 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007986#endif /* WEXITSTATUS */
7987#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007988 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007989#endif /* WTERMSIG */
7990#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007991 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007992#endif /* WSTOPSIG */
7993#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007994#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007995 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007996#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007997#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007998 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007999#endif
Fred Drakec9680921999-12-13 16:37:25 +00008000#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +00008001 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008002#endif
8003#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008004 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008005#endif
8006#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008007 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008008#endif
8009#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008010 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008011#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008012 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008013#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008014 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +00008015 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +00008016 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Mark Hammondef8b6542001-05-13 08:04:26 +00008017#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008018#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +00008019 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008020#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008021 #ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008022 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008023 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008024 #ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008025 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008026 #endif
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008027#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008028 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008029#endif
8030#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008031 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008032#endif
8033#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008034 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008035#endif
8036#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008037 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008038#endif
8039
Victor Stinner8c62be82010-05-06 00:08:46 +00008040 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008041};
8042
8043
Barry Warsaw4a342091996-12-19 23:50:02 +00008044static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008045ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008046{
Victor Stinner8c62be82010-05-06 00:08:46 +00008047 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008048}
8049
Guido van Rossumd48f2521997-12-05 22:19:34 +00008050#if defined(PYOS_OS2)
8051/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008052static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008053{
8054 APIRET rc;
8055 ULONG values[QSV_MAX+1];
8056 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008057 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008058
8059 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008060 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008061 Py_END_ALLOW_THREADS
8062
8063 if (rc != NO_ERROR) {
8064 os2_error(rc);
8065 return -1;
8066 }
8067
Fred Drake4d1e64b2002-04-15 19:40:07 +00008068 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8069 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8070 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8071 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8072 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8073 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8074 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008075
8076 switch (values[QSV_VERSION_MINOR]) {
8077 case 0: ver = "2.00"; break;
8078 case 10: ver = "2.10"; break;
8079 case 11: ver = "2.11"; break;
8080 case 30: ver = "3.00"; break;
8081 case 40: ver = "4.00"; break;
8082 case 50: ver = "5.00"; break;
8083 default:
Tim Peters885d4572001-11-28 20:27:42 +00008084 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +00008085 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00008086 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008087 ver = &tmp[0];
8088 }
8089
8090 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008091 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008092 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008093
8094 /* Add Indicator of Which Drive was Used to Boot the System */
8095 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8096 tmp[1] = ':';
8097 tmp[2] = '\0';
8098
Fred Drake4d1e64b2002-04-15 19:40:07 +00008099 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008100}
8101#endif
8102
Barry Warsaw4a342091996-12-19 23:50:02 +00008103static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008104all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008105{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008106#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008107 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008108#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008109#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008110 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008111#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008112#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008113 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008114#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008115#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008116 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008117#endif
Fred Drakec9680921999-12-13 16:37:25 +00008118#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008119 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00008120#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008121#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008122 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008123#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008124#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00008125 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008126#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008127#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +00008128 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008129#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008130#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +00008131 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008132#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008133#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008134 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008135#endif
8136#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008137 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008138#endif
8139#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +00008140 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008141#endif
8142#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +00008143 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008144#endif
8145#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008146 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008147#endif
8148#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +00008149 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008150#endif
8151#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008152 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008153#endif
8154#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008155 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008156#endif
8157#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008158 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008159#endif
8160#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +00008161 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008162#endif
8163#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008164 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008165#endif
8166#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +00008167 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008168#endif
8169#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008170 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008171#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008172#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008173 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008174#endif
8175#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +00008176 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008177#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008178#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008179 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008180#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008181#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008182 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008183#endif
8184#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008185 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008186#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008187
Tim Peters5aa91602002-01-30 05:46:57 +00008188/* MS Windows */
8189#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008190 /* Don't inherit in child processes. */
8191 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008192#endif
8193#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +00008194 /* Optimize for short life (keep in memory). */
8195 /* MS forgot to define this one with a non-underscore form too. */
8196 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008197#endif
8198#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008199 /* Automatically delete when last handle is closed. */
8200 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008201#endif
8202#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +00008203 /* Optimize for random access. */
8204 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008205#endif
8206#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008207 /* Optimize for sequential access. */
8208 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008209#endif
8210
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008211/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008212#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008213 /* Send a SIGIO signal whenever input or output
8214 becomes available on file descriptor */
8215 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008216#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008217#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008218 /* Direct disk access. */
8219 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008220#endif
8221#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +00008222 /* Must be a directory. */
8223 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008224#endif
8225#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +00008226 /* Do not follow links. */
8227 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008228#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008229#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +00008230 /* Do not update the access time. */
8231 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008232#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008233
Victor Stinner8c62be82010-05-06 00:08:46 +00008234 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008235#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008236 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008237#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008238#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008239 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008240#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008241#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008242 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008243#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008244#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008245 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008246#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008247#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +00008248 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008249#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008250#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +00008251 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008252#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008253#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008254 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008255#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008256#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +00008257 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008258#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008259#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008260 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008261#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008262#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008263 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008264#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008265#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008266 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008267#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008268#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008269 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008270#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008271#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +00008272 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008273#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008274#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +00008275 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008276#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008277#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008278 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008279#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008280#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008281 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008282#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008283#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +00008284 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008285#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008286
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008287 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008288#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008289 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008290#endif /* ST_RDONLY */
8291#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008292 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008293#endif /* ST_NOSUID */
8294
Guido van Rossum246bc171999-02-01 23:54:31 +00008295#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008296#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00008297 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8298 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8299 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8300 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8301 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8302 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8303 if (ins(d, "P_PM", (long)P_PM)) return -1;
8304 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8305 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8306 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8307 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8308 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8309 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8310 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8311 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8312 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8313 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8314 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8315 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8316 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008317#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008318 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8319 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8320 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8321 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8322 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008323#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008324#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008325
Guido van Rossumd48f2521997-12-05 22:19:34 +00008326#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00008327 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008328#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008329 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00008330}
8331
8332
Tim Peters5aa91602002-01-30 05:46:57 +00008333#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008334#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008335#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008336
8337#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008338#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008339#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008340
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008341#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00008342#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008343#define MODNAME "posix"
8344#endif
8345
Martin v. Löwis1a214512008-06-11 05:26:20 +00008346static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +00008347 PyModuleDef_HEAD_INIT,
8348 MODNAME,
8349 posix__doc__,
8350 -1,
8351 posix_methods,
8352 NULL,
8353 NULL,
8354 NULL,
8355 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00008356};
8357
8358
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008359PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008360INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008361{
Victor Stinner8c62be82010-05-06 00:08:46 +00008362 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008363
Victor Stinner8c62be82010-05-06 00:08:46 +00008364 m = PyModule_Create(&posixmodule);
8365 if (m == NULL)
8366 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008367
Victor Stinner8c62be82010-05-06 00:08:46 +00008368 /* Initialize environ dictionary */
8369 v = convertenviron();
8370 Py_XINCREF(v);
8371 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
8372 return NULL;
8373 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008374
Victor Stinner8c62be82010-05-06 00:08:46 +00008375 if (all_ins(m))
8376 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00008377
Victor Stinner8c62be82010-05-06 00:08:46 +00008378 if (setup_confname_tables(m))
8379 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00008380
Victor Stinner8c62be82010-05-06 00:08:46 +00008381 Py_INCREF(PyExc_OSError);
8382 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008383
Guido van Rossumb3d39562000-01-31 18:41:26 +00008384#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00008385 if (posix_putenv_garbage == NULL)
8386 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008387#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008388
Victor Stinner8c62be82010-05-06 00:08:46 +00008389 if (!initialized) {
8390 stat_result_desc.name = MODNAME ".stat_result";
8391 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8392 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8393 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8394 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8395 structseq_new = StatResultType.tp_new;
8396 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008397
Victor Stinner8c62be82010-05-06 00:08:46 +00008398 statvfs_result_desc.name = MODNAME ".statvfs_result";
8399 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008400#ifdef NEED_TICKS_PER_SECOND
8401# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +00008402 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008403# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +00008404 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008405# else
Victor Stinner8c62be82010-05-06 00:08:46 +00008406 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008407# endif
8408#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008409 }
8410 Py_INCREF((PyObject*) &StatResultType);
8411 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
8412 Py_INCREF((PyObject*) &StatVFSResultType);
8413 PyModule_AddObject(m, "statvfs_result",
8414 (PyObject*) &StatVFSResultType);
8415 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008416
8417#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +00008418 /*
8419 * Step 2 of weak-linking support on Mac OS X.
8420 *
8421 * The code below removes functions that are not available on the
8422 * currently active platform.
8423 *
8424 * This block allow one to use a python binary that was build on
8425 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8426 * OSX 10.4.
8427 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008428#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008429 if (fstatvfs == NULL) {
8430 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8431 return NULL;
8432 }
8433 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008434#endif /* HAVE_FSTATVFS */
8435
8436#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008437 if (statvfs == NULL) {
8438 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8439 return NULL;
8440 }
8441 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008442#endif /* HAVE_STATVFS */
8443
8444# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00008445 if (lchown == NULL) {
8446 if (PyObject_DelAttrString(m, "lchown") == -1) {
8447 return NULL;
8448 }
8449 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008450#endif /* HAVE_LCHOWN */
8451
8452
8453#endif /* __APPLE__ */
Victor Stinner8c62be82010-05-06 00:08:46 +00008454 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008455
Guido van Rossumb6775db1994-08-01 11:34:53 +00008456}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008457
8458#ifdef __cplusplus
8459}
8460#endif