blob: cb948980250828b49a101da28d7bc556531477c6 [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 Stinner97b89882010-05-06 00:25:39 +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 Stinner97b89882010-05-06 00:25:39 +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 Stinner97b89882010-05-06 00:25:39 +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 Stinner97b89882010-05-06 00:25:39 +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 Stinner97b89882010-05-06 00:25:39 +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 Stinner97b89882010-05-06 00:25:39 +0000119#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000120#define HAVE_WAIT 1
121#else
Victor Stinner97b89882010-05-06 00:25:39 +0000122#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000123#define HAVE_GETCWD 1
Victor Stinner97b89882010-05-06 00:25:39 +0000124#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000125#define HAVE_EXECV 1
126#define HAVE_PIPE 1
Victor Stinner97b89882010-05-06 00:25:39 +0000127#define HAVE_SYSTEM 1
128#define HAVE_CWAIT 1
129#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000130#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000131#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000132#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
133/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner97b89882010-05-06 00:25:39 +0000134#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000135/* Unix functions that the configure script doesn't check for */
136#define HAVE_EXECV 1
137#define HAVE_FORK 1
Victor Stinner97b89882010-05-06 00:25:39 +0000138#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000139#define HAVE_FORK1 1
140#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000141#define HAVE_GETCWD 1
142#define HAVE_GETEGID 1
143#define HAVE_GETEUID 1
144#define HAVE_GETGID 1
145#define HAVE_GETPPID 1
146#define HAVE_GETUID 1
147#define HAVE_KILL 1
148#define HAVE_OPENDIR 1
149#define HAVE_PIPE 1
Victor Stinner97b89882010-05-06 00:25:39 +0000150#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000151#define HAVE_WAIT 1
Victor Stinner97b89882010-05-06 00:25:39 +0000152#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000153#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000154#endif /* _MSC_VER */
155#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000156#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000157#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000158
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000159#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000160
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000161#if defined(__sgi)&&_COMPILER_VERSION>=700
162/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
163 (default) */
164extern char *ctermid_r(char *);
165#endif
166
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000167#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000168#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000170#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000171#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000172extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000173#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000174extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000176#endif
177#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000178extern int chdir(char *);
179extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000180#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000181extern int chdir(const char *);
182extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000183#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000184#ifdef __BORLANDC__
185extern int chmod(const char *, int);
186#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000187extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000188#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000189/*#ifdef HAVE_FCHMOD
190extern int fchmod(int, mode_t);
191#endif*/
192/*#ifdef HAVE_LCHMOD
193extern int lchmod(const char *, mode_t);
194#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000195extern int chown(const char *, uid_t, gid_t);
196extern char *getcwd(char *, int);
197extern char *strerror(int);
198extern int link(const char *, const char *);
199extern int rename(const char *, const char *);
200extern int stat(const char *, struct stat *);
201extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000203extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000204#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000206extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000207#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000209
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000210#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211
Guido van Rossumb6775db1994-08-01 11:34:53 +0000212#ifdef HAVE_UTIME_H
213#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000214#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000216#ifdef HAVE_SYS_UTIME_H
217#include <sys/utime.h>
218#define HAVE_UTIME_H /* pretend we do for the rest of this file */
219#endif /* HAVE_SYS_UTIME_H */
220
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221#ifdef HAVE_SYS_TIMES_H
222#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000223#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224
225#ifdef HAVE_SYS_PARAM_H
226#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000227#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228
229#ifdef HAVE_SYS_UTSNAME_H
230#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000231#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000233#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000235#define NAMLEN(dirent) strlen((dirent)->d_name)
236#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000237#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000238#include <direct.h>
239#define NAMLEN(dirent) strlen((dirent)->d_name)
240#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000242#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000243#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000244#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000246#endif
247#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000249#endif
250#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000252#endif
253#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000255#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000256#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000258#endif
259#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000261#endif
262#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000264#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000265#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000266#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267#include <windows.h>
Victor Stinner97b89882010-05-06 00:25:39 +0000268#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000269#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000270
Guido van Rossumd48f2521997-12-05 22:19:34 +0000271#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000273#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000274
Tim Petersbc2e10e2002-03-03 23:17:02 +0000275#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000276#if defined(PATH_MAX) && PATH_MAX > 1024
277#define MAXPATHLEN PATH_MAX
278#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000279#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000280#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000281#endif /* MAXPATHLEN */
282
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000283#ifdef UNION_WAIT
284/* Emulate some macros on systems that have a union instead of macros */
285
286#ifndef WIFEXITED
287#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
288#endif
289
290#ifndef WEXITSTATUS
291#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
292#endif
293
294#ifndef WTERMSIG
295#define WTERMSIG(u_wait) ((u_wait).w_termsig)
296#endif
297
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000298#define WAIT_TYPE union wait
299#define WAIT_STATUS_INT(s) (s.w_status)
300
301#else /* !UNION_WAIT */
302#define WAIT_TYPE int
303#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000304#endif /* UNION_WAIT */
305
Antoine Pitrouc3ee1662009-05-23 16:02:33 +0000306/* Issue #1983: pid_t can be longer than a C long on some systems */
Antoine Pitrou7852c422009-05-24 11:58:35 +0000307#if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT
Antoine Pitrouc3ee1662009-05-23 16:02:33 +0000308#define PARSE_PID "i"
309#define PyLong_FromPid PyLong_FromLong
310#define PyLong_AsPid PyLong_AsLong
311#elif SIZEOF_PID_T == SIZEOF_LONG
312#define PARSE_PID "l"
313#define PyLong_FromPid PyLong_FromLong
314#define PyLong_AsPid PyLong_AsLong
315#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
316#define PARSE_PID "L"
317#define PyLong_FromPid PyLong_FromLongLong
318#define PyLong_AsPid PyLong_AsLongLong
319#else
320#error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)"
Antoine Pitrouc3ee1662009-05-23 16:02:33 +0000321#endif /* SIZEOF_PID_T */
322
Greg Wardb48bc172000-03-01 21:51:56 +0000323/* Don't use the "_r" form if we don't need it (also, won't have a
324 prototype for it, at least on Solaris -- maybe others as well?). */
325#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
326#define USE_CTERMID_R
327#endif
328
Fred Drake699f3522000-06-29 21:12:41 +0000329/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000330#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000331#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner97b89882010-05-06 00:25:39 +0000332# define STAT win32_stat
333# define FSTAT win32_fstat
334# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000335#else
Victor Stinner97b89882010-05-06 00:25:39 +0000336# define STAT stat
337# define FSTAT fstat
338# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000339#endif
340
Tim Peters11b23062003-04-23 02:39:17 +0000341#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000342#include <sys/mkdev.h>
343#else
344#if defined(MAJOR_IN_SYSMACROS)
345#include <sys/sysmacros.h>
346#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000347#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
348#include <sys/mkdev.h>
349#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000350#endif
Fred Drake699f3522000-06-29 21:12:41 +0000351
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000352#if defined _MSC_VER && _MSC_VER >= 1400
353/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
354 * valid and throw an assertion if it isn't.
355 * Normally, an invalid fd is likely to be a C program error and therefore
356 * an assertion can be useful, but it does contradict the POSIX standard
357 * which for write(2) states:
358 * "Otherwise, -1 shall be returned and errno set to indicate the error."
359 * "[EBADF] The fildes argument is not a valid file descriptor open for
360 * writing."
361 * Furthermore, python allows the user to enter any old integer
362 * as a fd and should merely raise a python exception on error.
363 * The Microsoft CRT doesn't provide an official way to check for the
364 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner97b89882010-05-06 00:25:39 +0000365 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000366 * internal structures involved.
367 * The structures below must be updated for each version of visual studio
368 * according to the file internal.h in the CRT source, until MS comes
369 * up with a less hacky way to do this.
370 * (all of this is to avoid globally modifying the CRT behaviour using
371 * _set_invalid_parameter_handler() and _CrtSetReportMode())
372 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000373/* The actual size of the structure is determined at runtime.
374 * Only the first items must be present.
375 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000376typedef struct {
Victor Stinner97b89882010-05-06 00:25:39 +0000377 intptr_t osfhnd;
378 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000379} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000380
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000381extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000382#define IOINFO_L2E 5
383#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
384#define IOINFO_ARRAYS 64
385#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
386#define FOPEN 0x01
387#define _NO_CONSOLE_FILENO (intptr_t)-2
388
389/* This function emulates what the windows CRT does to validate file handles */
390int
391_PyVerify_fd(int fd)
392{
Victor Stinner97b89882010-05-06 00:25:39 +0000393 const int i1 = fd >> IOINFO_L2E;
394 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000395
Antoine Pitrou835b4452010-08-15 18:32:16 +0000396 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000397
Victor Stinner97b89882010-05-06 00:25:39 +0000398 /* Determine the actual size of the ioinfo structure,
399 * as used by the CRT loaded in memory
400 */
401 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
402 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
403 }
404 if (sizeof_ioinfo == 0) {
405 /* This should not happen... */
406 goto fail;
407 }
408
409 /* See that it isn't a special CLEAR fileno */
410 if (fd != _NO_CONSOLE_FILENO) {
411 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
412 * we check pointer validity and other info
413 */
414 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
415 /* finally, check that the file is open */
416 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
417 if (info->osfile & FOPEN) {
418 return 1;
419 }
420 }
421 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000422 fail:
Victor Stinner97b89882010-05-06 00:25:39 +0000423 errno = EBADF;
424 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000425}
426
427/* the special case of checking dup2. The target fd must be in a sensible range */
428static int
429_PyVerify_fd_dup2(int fd1, int fd2)
430{
Victor Stinner97b89882010-05-06 00:25:39 +0000431 if (!_PyVerify_fd(fd1))
432 return 0;
433 if (fd2 == _NO_CONSOLE_FILENO)
434 return 0;
435 if ((unsigned)fd2 < _NHANDLE_)
436 return 1;
437 else
438 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000439}
440#else
441/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
442#define _PyVerify_fd_dup2(A, B) (1)
443#endif
444
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000445/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000446#ifdef WITH_NEXT_FRAMEWORK
447/* On Darwin/MacOSX a shared library or framework has no access to
448** environ directly, we must obtain it with _NSGetEnviron().
449*/
450#include <crt_externs.h>
451static char **environ;
452#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000453extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000454#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000455
Barry Warsaw53699e91996-12-10 23:23:01 +0000456static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000457convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000458{
Victor Stinner97b89882010-05-06 00:25:39 +0000459 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000460#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +0000461 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000462#else
Victor Stinner97b89882010-05-06 00:25:39 +0000463 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000464#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000465#if defined(PYOS_OS2)
Victor Stinner97b89882010-05-06 00:25:39 +0000466 APIRET rc;
467 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
468#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000469
Victor Stinner97b89882010-05-06 00:25:39 +0000470 d = PyDict_New();
471 if (d == NULL)
472 return NULL;
473#ifdef WITH_NEXT_FRAMEWORK
474 if (environ == NULL)
475 environ = *_NSGetEnviron();
476#endif
477#ifdef MS_WINDOWS
478 /* _wenviron must be initialized in this way if the program is started
479 through main() instead of wmain(). */
480 _wgetenv(L"");
481 if (_wenviron == NULL)
482 return d;
483 /* This part ignores errors */
484 for (e = _wenviron; *e != NULL; e++) {
485 PyObject *k;
486 PyObject *v;
487 wchar_t *p = wcschr(*e, L'=');
488 if (p == NULL)
489 continue;
490 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
491 if (k == NULL) {
492 PyErr_Clear();
493 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000494 }
Victor Stinner97b89882010-05-06 00:25:39 +0000495 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
496 if (v == NULL) {
497 PyErr_Clear();
498 Py_DECREF(k);
499 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000500 }
Victor Stinner97b89882010-05-06 00:25:39 +0000501 if (PyDict_GetItem(d, k) == NULL) {
502 if (PyDict_SetItem(d, k, v) != 0)
503 PyErr_Clear();
504 }
505 Py_DECREF(k);
506 Py_DECREF(v);
507 }
508#else
509 if (environ == NULL)
510 return d;
511 /* This part ignores errors */
512 for (e = environ; *e != NULL; e++) {
513 PyObject *k;
514 PyObject *v;
515 char *p = strchr(*e, '=');
516 if (p == NULL)
517 continue;
518 k = PyUnicode_Decode(*e, (int)(p-*e),
519 Py_FileSystemDefaultEncoding, "surrogateescape");
520 if (k == NULL) {
521 PyErr_Clear();
522 continue;
523 }
524 v = PyUnicode_Decode(p+1, strlen(p+1),
525 Py_FileSystemDefaultEncoding, "surrogateescape");
526 if (v == NULL) {
527 PyErr_Clear();
528 Py_DECREF(k);
529 continue;
530 }
531 if (PyDict_GetItem(d, k) == NULL) {
532 if (PyDict_SetItem(d, k, v) != 0)
533 PyErr_Clear();
534 }
535 Py_DECREF(k);
536 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000537 }
538#endif
Victor Stinner97b89882010-05-06 00:25:39 +0000539#if defined(PYOS_OS2)
540 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
541 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
542 PyObject *v = PyBytes_FromString(buffer);
543 PyDict_SetItemString(d, "BEGINLIBPATH", v);
544 Py_DECREF(v);
545 }
546 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
547 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
548 PyObject *v = PyBytes_FromString(buffer);
549 PyDict_SetItemString(d, "ENDLIBPATH", v);
550 Py_DECREF(v);
551 }
552#endif
553 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000554}
555
Martin v. Löwis011e8422009-05-05 04:43:17 +0000556/* Convert a bytes object to a char*. Optionally lock the buffer if it is a
557 bytes array. */
558
559static char*
560bytes2str(PyObject* o, int lock)
561{
Victor Stinner97b89882010-05-06 00:25:39 +0000562 if(PyBytes_Check(o))
563 return PyBytes_AsString(o);
564 else if(PyByteArray_Check(o)) {
565 if (lock && PyObject_GetBuffer(o, NULL, 0) < 0)
566 /* On a bytearray, this should not fail. */
567 PyErr_BadInternalCall();
568 return PyByteArray_AsString(o);
569 } else {
570 /* The FS converter should have verified that this
571 is either bytes or bytearray. */
572 Py_FatalError("bad object passed to bytes2str");
573 /* not reached. */
574 return "";
575 }
Martin v. Löwis011e8422009-05-05 04:43:17 +0000576}
577
578/* Release the lock, decref the object. */
579static void
580release_bytes(PyObject* o)
581{
Victor Stinner97b89882010-05-06 00:25:39 +0000582 if (PyByteArray_Check(o))
583 o->ob_type->tp_as_buffer->bf_releasebuffer(o, 0);
584 Py_DECREF(o);
Martin v. Löwis011e8422009-05-05 04:43:17 +0000585}
586
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000587
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000588/* Set a POSIX-specific error from errno, and return NULL */
589
Barry Warsawd58d7641998-07-23 16:14:40 +0000590static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000591posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000592{
Victor Stinner97b89882010-05-06 00:25:39 +0000593 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000594}
Barry Warsawd58d7641998-07-23 16:14:40 +0000595static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000596posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000597{
Victor Stinner97b89882010-05-06 00:25:39 +0000598 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000599}
600
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000601#ifdef MS_WINDOWS
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000602static PyObject *
603posix_error_with_unicode_filename(Py_UNICODE* name)
604{
Victor Stinner97b89882010-05-06 00:25:39 +0000605 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000606}
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000607#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000608
609
Mark Hammondef8b6542001-05-13 08:04:26 +0000610static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000611posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000612{
Victor Stinner97b89882010-05-06 00:25:39 +0000613 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError,
614 bytes2str(name, 0));
615 release_bytes(name);
616 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000617}
618
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000619#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000620static PyObject *
621win32_error(char* function, char* filename)
622{
Victor Stinner97b89882010-05-06 00:25:39 +0000623 /* XXX We should pass the function name along in the future.
624 (winreg.c also wants to pass the function name.)
625 This would however require an additional param to the
626 Windows error object, which is non-trivial.
627 */
628 errno = GetLastError();
629 if (filename)
630 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
631 else
632 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000633}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000634
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000635static PyObject *
636win32_error_unicode(char* function, Py_UNICODE* filename)
637{
Victor Stinner97b89882010-05-06 00:25:39 +0000638 /* XXX - see win32_error for comments on 'function' */
639 errno = GetLastError();
640 if (filename)
641 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
642 else
643 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000644}
645
Thomas Wouters477c8d52006-05-27 19:21:47 +0000646static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000647convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000648{
Victor Stinner97b89882010-05-06 00:25:39 +0000649 if (PyUnicode_CheckExact(*param))
650 Py_INCREF(*param);
651 else if (PyUnicode_Check(*param))
652 /* For a Unicode subtype that's not a Unicode object,
653 return a true Unicode object with the same data. */
654 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
655 PyUnicode_GET_SIZE(*param));
656 else
657 *param = PyUnicode_FromEncodedObject(*param,
658 Py_FileSystemDefaultEncoding,
659 "strict");
660 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000661}
662
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000663#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000664
Guido van Rossumd48f2521997-12-05 22:19:34 +0000665#if defined(PYOS_OS2)
666/**********************************************************************
667 * Helper Function to Trim and Format OS/2 Messages
668 **********************************************************************/
Victor Stinner97b89882010-05-06 00:25:39 +0000669static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000670os2_formatmsg(char *msgbuf, int msglen, char *reason)
671{
672 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
673
674 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
675 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
676
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000677 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000678 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
679 }
680
681 /* Add Optional Reason Text */
682 if (reason) {
683 strcat(msgbuf, " : ");
684 strcat(msgbuf, reason);
685 }
686}
687
688/**********************************************************************
689 * Decode an OS/2 Operating System Error Code
690 *
691 * A convenience function to lookup an OS/2 error code and return a
692 * text message we can use to raise a Python exception.
693 *
694 * Notes:
695 * The messages for errors returned from the OS/2 kernel reside in
696 * the file OSO001.MSG in the \OS2 directory hierarchy.
697 *
698 **********************************************************************/
Victor Stinner97b89882010-05-06 00:25:39 +0000699static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000700os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
701{
702 APIRET rc;
703 ULONG msglen;
704
705 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
706 Py_BEGIN_ALLOW_THREADS
707 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
708 errorcode, "oso001.msg", &msglen);
709 Py_END_ALLOW_THREADS
710
711 if (rc == NO_ERROR)
712 os2_formatmsg(msgbuf, msglen, reason);
713 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000714 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner97b89882010-05-06 00:25:39 +0000715 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000716
717 return msgbuf;
718}
719
720/* Set an OS/2-specific error and return NULL. OS/2 kernel
721 errors are not in a global variable e.g. 'errno' nor are
722 they congruent with posix error numbers. */
723
Victor Stinner97b89882010-05-06 00:25:39 +0000724static PyObject *
725os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000726{
727 char text[1024];
728 PyObject *v;
729
730 os2_strerror(text, sizeof(text), code, "");
731
732 v = Py_BuildValue("(is)", code, text);
733 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000734 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000735 Py_DECREF(v);
736 }
737 return NULL; /* Signal to Python that an Exception is Pending */
738}
739
740#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000741
742/* POSIX generic methods */
743
Barry Warsaw53699e91996-12-10 23:23:01 +0000744static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000745posix_fildes(PyObject *fdobj, int (*func)(int))
746{
Victor Stinner97b89882010-05-06 00:25:39 +0000747 int fd;
748 int res;
749 fd = PyObject_AsFileDescriptor(fdobj);
750 if (fd < 0)
751 return NULL;
752 if (!_PyVerify_fd(fd))
753 return posix_error();
754 Py_BEGIN_ALLOW_THREADS
755 res = (*func)(fd);
756 Py_END_ALLOW_THREADS
757 if (res < 0)
758 return posix_error();
759 Py_INCREF(Py_None);
760 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000761}
Guido van Rossum21142a01999-01-08 21:05:37 +0000762
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000763#ifdef MS_WINDOWS
Tim Peters11b23062003-04-23 02:39:17 +0000764static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000765unicode_file_names(void)
766{
Victor Stinner97b89882010-05-06 00:25:39 +0000767 static int canusewide = -1;
768 if (canusewide == -1) {
769 /* As per doc for ::GetVersion(), this is the correct test for
770 the Windows NT family. */
771 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
772 }
773 return canusewide;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000774}
775#endif
Tim Peters11b23062003-04-23 02:39:17 +0000776
Guido van Rossum21142a01999-01-08 21:05:37 +0000777static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000778posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000779{
Victor Stinner97b89882010-05-06 00:25:39 +0000780 PyObject *opath1 = NULL;
781 char *path1;
782 int res;
783 if (!PyArg_ParseTuple(args, format,
784 PyUnicode_FSConverter, &opath1))
785 return NULL;
786 path1 = bytes2str(opath1, 1);
787 Py_BEGIN_ALLOW_THREADS
788 res = (*func)(path1);
789 Py_END_ALLOW_THREADS
790 if (res < 0)
791 return posix_error_with_allocated_filename(opath1);
792 release_bytes(opath1);
793 Py_INCREF(Py_None);
794 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000795}
796
Barry Warsaw53699e91996-12-10 23:23:01 +0000797static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000798posix_2str(PyObject *args,
Victor Stinner97b89882010-05-06 00:25:39 +0000799 char *format,
800 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000801{
Victor Stinner97b89882010-05-06 00:25:39 +0000802 PyObject *opath1 = NULL, *opath2 = NULL;
803 char *path1, *path2;
804 int res;
805 if (!PyArg_ParseTuple(args, format,
806 PyUnicode_FSConverter, &opath1,
807 PyUnicode_FSConverter, &opath2)) {
808 return NULL;
809 }
810 path1 = bytes2str(opath1, 1);
811 path2 = bytes2str(opath2, 1);
812 Py_BEGIN_ALLOW_THREADS
813 res = (*func)(path1, path2);
814 Py_END_ALLOW_THREADS
815 release_bytes(opath1);
816 release_bytes(opath2);
817 if (res != 0)
818 /* XXX how to report both path1 and path2??? */
819 return posix_error();
820 Py_INCREF(Py_None);
821 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000822}
823
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000824#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000825static PyObject*
Victor Stinner97b89882010-05-06 00:25:39 +0000826win32_1str(PyObject* args, char* func,
827 char* format, BOOL (__stdcall *funcA)(LPCSTR),
828 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000829{
Victor Stinner97b89882010-05-06 00:25:39 +0000830 PyObject *uni;
831 char *ansi;
832 BOOL result;
833 if (unicode_file_names()) {
834 if (!PyArg_ParseTuple(args, wformat, &uni))
835 PyErr_Clear();
836 else {
837 Py_BEGIN_ALLOW_THREADS
838 result = funcW(PyUnicode_AsUnicode(uni));
839 Py_END_ALLOW_THREADS
840 if (!result)
841 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
842 Py_INCREF(Py_None);
843 return Py_None;
844 }
845 }
846 if (!PyArg_ParseTuple(args, format, &ansi))
847 return NULL;
848 Py_BEGIN_ALLOW_THREADS
849 result = funcA(ansi);
850 Py_END_ALLOW_THREADS
851 if (!result)
852 return win32_error(func, ansi);
853 Py_INCREF(Py_None);
854 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000855
856}
857
858/* This is a reimplementation of the C library's chdir function,
859 but one that produces Win32 errors instead of DOS error codes.
860 chdir is essentially a wrapper around SetCurrentDirectory; however,
861 it also needs to set "magic" environment variables indicating
862 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000863static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000864win32_chdir(LPCSTR path)
865{
Victor Stinner97b89882010-05-06 00:25:39 +0000866 char new_path[MAX_PATH+1];
867 int result;
868 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000869
Victor Stinner97b89882010-05-06 00:25:39 +0000870 if(!SetCurrentDirectoryA(path))
871 return FALSE;
872 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
873 if (!result)
874 return FALSE;
875 /* In the ANSI API, there should not be any paths longer
876 than MAX_PATH. */
877 assert(result <= MAX_PATH+1);
878 if (strncmp(new_path, "\\\\", 2) == 0 ||
879 strncmp(new_path, "//", 2) == 0)
880 /* UNC path, nothing to do. */
881 return TRUE;
882 env[1] = new_path[0];
883 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000884}
885
886/* The Unicode version differs from the ANSI version
887 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000888static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000889win32_wchdir(LPCWSTR path)
890{
Victor Stinner97b89882010-05-06 00:25:39 +0000891 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
892 int result;
893 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000894
Victor Stinner97b89882010-05-06 00:25:39 +0000895 if(!SetCurrentDirectoryW(path))
896 return FALSE;
897 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
898 if (!result)
899 return FALSE;
900 if (result > MAX_PATH+1) {
901 new_path = malloc(result * sizeof(wchar_t));
902 if (!new_path) {
903 SetLastError(ERROR_OUTOFMEMORY);
904 return FALSE;
905 }
906 result = GetCurrentDirectoryW(result, new_path);
907 if (!result) {
908 free(new_path);
909 return FALSE;
910 }
911 }
912 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
913 wcsncmp(new_path, L"//", 2) == 0)
914 /* UNC path, nothing to do. */
915 return TRUE;
916 env[1] = new_path[0];
917 result = SetEnvironmentVariableW(env, new_path);
918 if (new_path != _new_path)
919 free(new_path);
920 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000921}
922#endif
923
Martin v. Löwis14694662006-02-03 12:54:16 +0000924#ifdef MS_WINDOWS
925/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
926 - time stamps are restricted to second resolution
927 - file modification times suffer from forth-and-back conversions between
928 UTC and local time
929 Therefore, we implement our own stat, based on the Win32 API directly.
930*/
Victor Stinner97b89882010-05-06 00:25:39 +0000931#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +0000932
933struct win32_stat{
934 int st_dev;
935 __int64 st_ino;
936 unsigned short st_mode;
937 int st_nlink;
938 int st_uid;
939 int st_gid;
940 int st_rdev;
941 __int64 st_size;
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +0000942 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000943 int st_atime_nsec;
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +0000944 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000945 int st_mtime_nsec;
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +0000946 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000947 int st_ctime_nsec;
948};
949
950static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
951
952static void
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +0000953FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +0000954{
Victor Stinner97b89882010-05-06 00:25:39 +0000955 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
956 /* Cannot simply cast and dereference in_ptr,
957 since it might not be aligned properly */
958 __int64 in;
959 memcpy(&in, in_ptr, sizeof(in));
960 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +0000961 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +0000962}
963
Thomas Wouters477c8d52006-05-27 19:21:47 +0000964static void
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +0000965time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000966{
Victor Stinner97b89882010-05-06 00:25:39 +0000967 /* XXX endianness */
968 __int64 out;
969 out = time_in + secs_between_epochs;
970 out = out * 10000000 + nsec_in / 100;
971 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000972}
973
Martin v. Löwis14694662006-02-03 12:54:16 +0000974/* Below, we *know* that ugo+r is 0444 */
975#if _S_IREAD != 0400
976#error Unsupported C library
977#endif
978static int
979attributes_to_mode(DWORD attr)
980{
Victor Stinner97b89882010-05-06 00:25:39 +0000981 int m = 0;
982 if (attr & FILE_ATTRIBUTE_DIRECTORY)
983 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
984 else
985 m |= _S_IFREG;
986 if (attr & FILE_ATTRIBUTE_READONLY)
987 m |= 0444;
988 else
989 m |= 0666;
990 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +0000991}
992
993static int
994attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
995{
Victor Stinner97b89882010-05-06 00:25:39 +0000996 memset(result, 0, sizeof(*result));
997 result->st_mode = attributes_to_mode(info->dwFileAttributes);
998 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
999 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1000 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1001 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Martin v. Löwis14694662006-02-03 12:54:16 +00001002
Victor Stinner97b89882010-05-06 00:25:39 +00001003 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001004}
1005
Thomas Wouters89f507f2006-12-13 04:49:30 +00001006/* Emulate GetFileAttributesEx[AW] on Windows 95 */
1007static int checked = 0;
1008static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
1009static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
1010static void
1011check_gfax()
1012{
Victor Stinner97b89882010-05-06 00:25:39 +00001013 HINSTANCE hKernel32;
1014 if (checked)
1015 return;
1016 checked = 1;
1017 hKernel32 = GetModuleHandle("KERNEL32");
1018 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
1019 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
Thomas Wouters89f507f2006-12-13 04:49:30 +00001020}
1021
Guido van Rossumd8faa362007-04-27 19:54:29 +00001022static BOOL
1023attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1024{
Victor Stinner97b89882010-05-06 00:25:39 +00001025 HANDLE hFindFile;
1026 WIN32_FIND_DATAA FileData;
1027 hFindFile = FindFirstFileA(pszFile, &FileData);
1028 if (hFindFile == INVALID_HANDLE_VALUE)
1029 return FALSE;
1030 FindClose(hFindFile);
1031 pfad->dwFileAttributes = FileData.dwFileAttributes;
1032 pfad->ftCreationTime = FileData.ftCreationTime;
1033 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1034 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1035 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1036 pfad->nFileSizeLow = FileData.nFileSizeLow;
1037 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001038}
1039
1040static BOOL
1041attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1042{
Victor Stinner97b89882010-05-06 00:25:39 +00001043 HANDLE hFindFile;
1044 WIN32_FIND_DATAW FileData;
1045 hFindFile = FindFirstFileW(pszFile, &FileData);
1046 if (hFindFile == INVALID_HANDLE_VALUE)
1047 return FALSE;
1048 FindClose(hFindFile);
1049 pfad->dwFileAttributes = FileData.dwFileAttributes;
1050 pfad->ftCreationTime = FileData.ftCreationTime;
1051 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1052 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1053 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1054 pfad->nFileSizeLow = FileData.nFileSizeLow;
1055 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001056}
1057
Thomas Wouters89f507f2006-12-13 04:49:30 +00001058static BOOL WINAPI
Victor Stinner97b89882010-05-06 00:25:39 +00001059Py_GetFileAttributesExA(LPCSTR pszFile,
1060 GET_FILEEX_INFO_LEVELS level,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001061 LPVOID pv)
1062{
Victor Stinner97b89882010-05-06 00:25:39 +00001063 BOOL result;
1064 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1065 /* First try to use the system's implementation, if that is
1066 available and either succeeds to gives an error other than
1067 that it isn't implemented. */
1068 check_gfax();
1069 if (gfaxa) {
1070 result = gfaxa(pszFile, level, pv);
1071 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1072 return result;
1073 }
1074 /* It's either not present, or not implemented.
1075 Emulate using FindFirstFile. */
1076 if (level != GetFileExInfoStandard) {
1077 SetLastError(ERROR_INVALID_PARAMETER);
1078 return FALSE;
1079 }
1080 /* Use GetFileAttributes to validate that the file name
1081 does not contain wildcards (which FindFirstFile would
1082 accept). */
1083 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
1084 return FALSE;
1085 return attributes_from_dir(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001086}
1087
1088static BOOL WINAPI
Victor Stinner97b89882010-05-06 00:25:39 +00001089Py_GetFileAttributesExW(LPCWSTR pszFile,
1090 GET_FILEEX_INFO_LEVELS level,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001091 LPVOID pv)
1092{
Victor Stinner97b89882010-05-06 00:25:39 +00001093 BOOL result;
1094 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1095 /* First try to use the system's implementation, if that is
1096 available and either succeeds to gives an error other than
1097 that it isn't implemented. */
1098 check_gfax();
1099 if (gfaxa) {
1100 result = gfaxw(pszFile, level, pv);
1101 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1102 return result;
1103 }
1104 /* It's either not present, or not implemented.
1105 Emulate using FindFirstFile. */
1106 if (level != GetFileExInfoStandard) {
1107 SetLastError(ERROR_INVALID_PARAMETER);
1108 return FALSE;
1109 }
1110 /* Use GetFileAttributes to validate that the file name
1111 does not contain wildcards (which FindFirstFile would
1112 accept). */
1113 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
1114 return FALSE;
1115 return attributes_from_dir_w(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001116}
1117
Victor Stinner97b89882010-05-06 00:25:39 +00001118static int
Martin v. Löwis14694662006-02-03 12:54:16 +00001119win32_stat(const char* path, struct win32_stat *result)
1120{
Victor Stinner97b89882010-05-06 00:25:39 +00001121 WIN32_FILE_ATTRIBUTE_DATA info;
1122 int code;
1123 char *dot;
1124 /* XXX not supported on Win95 and NT 3.x */
1125 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
1126 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1127 /* Protocol violation: we explicitly clear errno, instead of
1128 setting it to a POSIX error. Callers should use GetLastError. */
1129 errno = 0;
1130 return -1;
1131 } else {
1132 /* Could not get attributes on open file. Fall back to
1133 reading the directory. */
1134 if (!attributes_from_dir(path, &info)) {
1135 /* Very strange. This should not fail now */
1136 errno = 0;
1137 return -1;
1138 }
1139 }
1140 }
1141 code = attribute_data_to_stat(&info, result);
1142 if (code != 0)
1143 return code;
1144 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1145 dot = strrchr(path, '.');
1146 if (dot) {
1147 if (stricmp(dot, ".bat") == 0 ||
1148 stricmp(dot, ".cmd") == 0 ||
1149 stricmp(dot, ".exe") == 0 ||
1150 stricmp(dot, ".com") == 0)
1151 result->st_mode |= 0111;
1152 }
1153 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001154}
1155
Victor Stinner97b89882010-05-06 00:25:39 +00001156static int
Martin v. Löwis14694662006-02-03 12:54:16 +00001157win32_wstat(const wchar_t* path, struct win32_stat *result)
1158{
Victor Stinner97b89882010-05-06 00:25:39 +00001159 int code;
1160 const wchar_t *dot;
1161 WIN32_FILE_ATTRIBUTE_DATA info;
1162 /* XXX not supported on Win95 and NT 3.x */
1163 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
1164 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1165 /* Protocol violation: we explicitly clear errno, instead of
1166 setting it to a POSIX error. Callers should use GetLastError. */
1167 errno = 0;
1168 return -1;
1169 } else {
1170 /* Could not get attributes on open file. Fall back to
1171 reading the directory. */
1172 if (!attributes_from_dir_w(path, &info)) {
1173 /* Very strange. This should not fail now */
1174 errno = 0;
1175 return -1;
1176 }
1177 }
1178 }
1179 code = attribute_data_to_stat(&info, result);
1180 if (code < 0)
1181 return code;
1182 /* Set IFEXEC if it is an .exe, .bat, ... */
1183 dot = wcsrchr(path, '.');
1184 if (dot) {
1185 if (_wcsicmp(dot, L".bat") == 0 ||
1186 _wcsicmp(dot, L".cmd") == 0 ||
1187 _wcsicmp(dot, L".exe") == 0 ||
1188 _wcsicmp(dot, L".com") == 0)
1189 result->st_mode |= 0111;
1190 }
1191 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001192}
1193
1194static int
1195win32_fstat(int file_number, struct win32_stat *result)
1196{
Victor Stinner97b89882010-05-06 00:25:39 +00001197 BY_HANDLE_FILE_INFORMATION info;
1198 HANDLE h;
1199 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001200
Victor Stinner97b89882010-05-06 00:25:39 +00001201 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001202
Victor Stinner97b89882010-05-06 00:25:39 +00001203 /* Protocol violation: we explicitly clear errno, instead of
1204 setting it to a POSIX error. Callers should use GetLastError. */
1205 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001206
Victor Stinner97b89882010-05-06 00:25:39 +00001207 if (h == INVALID_HANDLE_VALUE) {
1208 /* This is really a C library error (invalid file handle).
1209 We set the Win32 error to the closes one matching. */
1210 SetLastError(ERROR_INVALID_HANDLE);
1211 return -1;
1212 }
1213 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001214
Victor Stinner97b89882010-05-06 00:25:39 +00001215 type = GetFileType(h);
1216 if (type == FILE_TYPE_UNKNOWN) {
1217 DWORD error = GetLastError();
1218 if (error != 0) {
1219 return -1;
1220 }
1221 /* else: valid but unknown file */
1222 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001223
Victor Stinner97b89882010-05-06 00:25:39 +00001224 if (type != FILE_TYPE_DISK) {
1225 if (type == FILE_TYPE_CHAR)
1226 result->st_mode = _S_IFCHR;
1227 else if (type == FILE_TYPE_PIPE)
1228 result->st_mode = _S_IFIFO;
1229 return 0;
1230 }
1231
1232 if (!GetFileInformationByHandle(h, &info)) {
1233 return -1;
1234 }
1235
1236 /* similar to stat() */
1237 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1238 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1239 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1240 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1241 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1242 /* specific to fstat() */
1243 result->st_nlink = info.nNumberOfLinks;
1244 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1245 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001246}
1247
1248#endif /* MS_WINDOWS */
1249
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001250PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001251"stat_result: Result from stat or lstat.\n\n\
1252This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001253 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001254or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1255\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001256Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1257or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001258\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001259See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001260
1261static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner97b89882010-05-06 00:25:39 +00001262 {"st_mode", "protection bits"},
1263 {"st_ino", "inode"},
1264 {"st_dev", "device"},
1265 {"st_nlink", "number of hard links"},
1266 {"st_uid", "user ID of owner"},
1267 {"st_gid", "group ID of owner"},
1268 {"st_size", "total size, in bytes"},
1269 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1270 {NULL, "integer time of last access"},
1271 {NULL, "integer time of last modification"},
1272 {NULL, "integer time of last change"},
1273 {"st_atime", "time of last access"},
1274 {"st_mtime", "time of last modification"},
1275 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001276#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner97b89882010-05-06 00:25:39 +00001277 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001278#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001279#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner97b89882010-05-06 00:25:39 +00001280 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001281#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001282#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner97b89882010-05-06 00:25:39 +00001283 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001284#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001285#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00001286 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001287#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001288#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner97b89882010-05-06 00:25:39 +00001289 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001290#endif
1291#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner97b89882010-05-06 00:25:39 +00001292 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001293#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001294 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001295};
1296
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001297#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001298#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001299#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001300#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001301#endif
1302
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001303#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001304#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1305#else
1306#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1307#endif
1308
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001309#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001310#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1311#else
1312#define ST_RDEV_IDX ST_BLOCKS_IDX
1313#endif
1314
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001315#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1316#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1317#else
1318#define ST_FLAGS_IDX ST_RDEV_IDX
1319#endif
1320
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001321#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001322#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001323#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001324#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001325#endif
1326
1327#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1328#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1329#else
1330#define ST_BIRTHTIME_IDX ST_GEN_IDX
1331#endif
1332
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001333static PyStructSequence_Desc stat_result_desc = {
Victor Stinner97b89882010-05-06 00:25:39 +00001334 "stat_result", /* name */
1335 stat_result__doc__, /* doc */
1336 stat_result_fields,
1337 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001338};
1339
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001340PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001341"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1342This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001343 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001344or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001345\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001346See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001347
1348static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner97b89882010-05-06 00:25:39 +00001349 {"f_bsize", },
1350 {"f_frsize", },
1351 {"f_blocks", },
1352 {"f_bfree", },
1353 {"f_bavail", },
1354 {"f_files", },
1355 {"f_ffree", },
1356 {"f_favail", },
1357 {"f_flag", },
1358 {"f_namemax",},
1359 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001360};
1361
1362static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner97b89882010-05-06 00:25:39 +00001363 "statvfs_result", /* name */
1364 statvfs_result__doc__, /* doc */
1365 statvfs_result_fields,
1366 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001367};
1368
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001369static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001370static PyTypeObject StatResultType;
1371static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001372static newfunc structseq_new;
1373
1374static PyObject *
1375statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1376{
Victor Stinner97b89882010-05-06 00:25:39 +00001377 PyStructSequence *result;
1378 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001379
Victor Stinner97b89882010-05-06 00:25:39 +00001380 result = (PyStructSequence*)structseq_new(type, args, kwds);
1381 if (!result)
1382 return NULL;
1383 /* If we have been initialized from a tuple,
1384 st_?time might be set to None. Initialize it
1385 from the int slots. */
1386 for (i = 7; i <= 9; i++) {
1387 if (result->ob_item[i+3] == Py_None) {
1388 Py_DECREF(Py_None);
1389 Py_INCREF(result->ob_item[i]);
1390 result->ob_item[i+3] = result->ob_item[i];
1391 }
1392 }
1393 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001394}
1395
1396
1397
1398/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001399static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001400
1401PyDoc_STRVAR(stat_float_times__doc__,
1402"stat_float_times([newval]) -> oldval\n\n\
1403Determine whether os.[lf]stat represents time stamps as float objects.\n\
1404If newval is True, future calls to stat() return floats, if it is False,\n\
1405future calls return ints. \n\
1406If newval is omitted, return the current setting.\n");
1407
1408static PyObject*
1409stat_float_times(PyObject* self, PyObject *args)
1410{
Victor Stinner97b89882010-05-06 00:25:39 +00001411 int newval = -1;
1412 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1413 return NULL;
1414 if (newval == -1)
1415 /* Return old value */
1416 return PyBool_FromLong(_stat_float_times);
1417 _stat_float_times = newval;
1418 Py_INCREF(Py_None);
1419 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001420}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001421
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001422static void
1423fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1424{
Victor Stinner97b89882010-05-06 00:25:39 +00001425 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001426#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner97b89882010-05-06 00:25:39 +00001427 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001428#else
Victor Stinner97b89882010-05-06 00:25:39 +00001429 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001430#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001431 if (!ival)
1432 return;
1433 if (_stat_float_times) {
1434 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1435 } else {
1436 fval = ival;
1437 Py_INCREF(fval);
1438 }
1439 PyStructSequence_SET_ITEM(v, index, ival);
1440 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001441}
1442
Tim Peters5aa91602002-01-30 05:46:57 +00001443/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001444 (used by posix_stat() and posix_fstat()) */
1445static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001446_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001447{
Victor Stinner97b89882010-05-06 00:25:39 +00001448 unsigned long ansec, mnsec, cnsec;
1449 PyObject *v = PyStructSequence_New(&StatResultType);
1450 if (v == NULL)
1451 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001452
Victor Stinner97b89882010-05-06 00:25:39 +00001453 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001454#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner97b89882010-05-06 00:25:39 +00001455 PyStructSequence_SET_ITEM(v, 1,
1456 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001457#else
Victor Stinner97b89882010-05-06 00:25:39 +00001458 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001459#endif
1460#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner97b89882010-05-06 00:25:39 +00001461 PyStructSequence_SET_ITEM(v, 2,
1462 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001463#else
Victor Stinner97b89882010-05-06 00:25:39 +00001464 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001465#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001466 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1467 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1468 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001469#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner97b89882010-05-06 00:25:39 +00001470 PyStructSequence_SET_ITEM(v, 6,
1471 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001472#else
Victor Stinner97b89882010-05-06 00:25:39 +00001473 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001474#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001475
Martin v. Löwis14694662006-02-03 12:54:16 +00001476#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner97b89882010-05-06 00:25:39 +00001477 ansec = st->st_atim.tv_nsec;
1478 mnsec = st->st_mtim.tv_nsec;
1479 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001480#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner97b89882010-05-06 00:25:39 +00001481 ansec = st->st_atimespec.tv_nsec;
1482 mnsec = st->st_mtimespec.tv_nsec;
1483 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001484#elif defined(HAVE_STAT_NSEC)
Victor Stinner97b89882010-05-06 00:25:39 +00001485 ansec = st->st_atime_nsec;
1486 mnsec = st->st_mtime_nsec;
1487 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001488#else
Victor Stinner97b89882010-05-06 00:25:39 +00001489 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001490#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001491 fill_time(v, 7, st->st_atime, ansec);
1492 fill_time(v, 8, st->st_mtime, mnsec);
1493 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001494
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001495#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner97b89882010-05-06 00:25:39 +00001496 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1497 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001498#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001499#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner97b89882010-05-06 00:25:39 +00001500 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1501 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001502#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001503#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner97b89882010-05-06 00:25:39 +00001504 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1505 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001506#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001507#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner97b89882010-05-06 00:25:39 +00001508 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1509 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001510#endif
1511#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner97b89882010-05-06 00:25:39 +00001512 {
1513 PyObject *val;
1514 unsigned long bsec,bnsec;
1515 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001516#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner97b89882010-05-06 00:25:39 +00001517 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001518#else
Victor Stinner97b89882010-05-06 00:25:39 +00001519 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001520#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001521 if (_stat_float_times) {
1522 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1523 } else {
1524 val = PyLong_FromLong((long)bsec);
1525 }
1526 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1527 val);
1528 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001529#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001530#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00001531 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1532 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001533#endif
Fred Drake699f3522000-06-29 21:12:41 +00001534
Victor Stinner97b89882010-05-06 00:25:39 +00001535 if (PyErr_Occurred()) {
1536 Py_DECREF(v);
1537 return NULL;
1538 }
Fred Drake699f3522000-06-29 21:12:41 +00001539
Victor Stinner97b89882010-05-06 00:25:39 +00001540 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001541}
1542
Martin v. Löwisd8948722004-06-02 09:57:56 +00001543#ifdef MS_WINDOWS
1544
1545/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1546 where / can be used in place of \ and the trailing slash is optional.
1547 Both SERVER and SHARE must have at least one character.
1548*/
1549
1550#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1551#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001552#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001553#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001554#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001555
Tim Peters4ad82172004-08-30 17:02:04 +00001556static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001557IsUNCRootA(char *path, int pathlen)
1558{
Victor Stinner97b89882010-05-06 00:25:39 +00001559 #define ISSLASH ISSLASHA
Martin v. Löwisd8948722004-06-02 09:57:56 +00001560
Victor Stinner97b89882010-05-06 00:25:39 +00001561 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001562
Victor Stinner97b89882010-05-06 00:25:39 +00001563 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1564 /* minimum UNCRoot is \\x\y */
1565 return FALSE;
1566 for (i = 2; i < pathlen ; i++)
1567 if (ISSLASH(path[i])) break;
1568 if (i == 2 || i == pathlen)
1569 /* do not allow \\\SHARE or \\SERVER */
1570 return FALSE;
1571 share = i+1;
1572 for (i = share; i < pathlen; i++)
1573 if (ISSLASH(path[i])) break;
1574 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001575
Victor Stinner97b89882010-05-06 00:25:39 +00001576 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001577}
1578
Tim Peters4ad82172004-08-30 17:02:04 +00001579static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001580IsUNCRootW(Py_UNICODE *path, int pathlen)
1581{
Victor Stinner97b89882010-05-06 00:25:39 +00001582 #define ISSLASH ISSLASHW
Martin v. Löwisd8948722004-06-02 09:57:56 +00001583
Victor Stinner97b89882010-05-06 00:25:39 +00001584 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001585
Victor Stinner97b89882010-05-06 00:25:39 +00001586 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1587 /* minimum UNCRoot is \\x\y */
1588 return FALSE;
1589 for (i = 2; i < pathlen ; i++)
1590 if (ISSLASH(path[i])) break;
1591 if (i == 2 || i == pathlen)
1592 /* do not allow \\\SHARE or \\SERVER */
1593 return FALSE;
1594 share = i+1;
1595 for (i = share; i < pathlen; i++)
1596 if (ISSLASH(path[i])) break;
1597 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001598
Victor Stinner97b89882010-05-06 00:25:39 +00001599 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001600}
Martin v. Löwisd8948722004-06-02 09:57:56 +00001601#endif /* MS_WINDOWS */
1602
Barry Warsaw53699e91996-12-10 23:23:01 +00001603static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001604posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner97b89882010-05-06 00:25:39 +00001605 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001606#ifdef __VMS
Victor Stinner97b89882010-05-06 00:25:39 +00001607 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001608#else
Victor Stinner97b89882010-05-06 00:25:39 +00001609 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001610#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001611 char *wformat,
1612 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001613{
Victor Stinner97b89882010-05-06 00:25:39 +00001614 STRUCT_STAT st;
1615 PyObject *opath;
1616 char *path;
1617 int res;
1618 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001619
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001620#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00001621 /* If on wide-character-capable OS see if argument
1622 is Unicode and if so use wide API. */
1623 if (unicode_file_names()) {
1624 PyUnicodeObject *po;
1625 if (PyArg_ParseTuple(args, wformat, &po)) {
1626 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001627
Victor Stinner97b89882010-05-06 00:25:39 +00001628 Py_BEGIN_ALLOW_THREADS
1629 /* PyUnicode_AS_UNICODE result OK without
1630 thread lock as it is a simple dereference. */
1631 res = wstatfunc(wpath, &st);
1632 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001633
Victor Stinner97b89882010-05-06 00:25:39 +00001634 if (res != 0)
1635 return win32_error_unicode("stat", wpath);
1636 return _pystat_fromstructstat(&st);
1637 }
1638 /* Drop the argument parsing error as narrow strings
1639 are also valid. */
1640 PyErr_Clear();
1641 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001642#endif
1643
Victor Stinner97b89882010-05-06 00:25:39 +00001644 if (!PyArg_ParseTuple(args, format,
1645 PyUnicode_FSConverter, &opath))
1646 return NULL;
1647 path = bytes2str(opath, 1);
1648 Py_BEGIN_ALLOW_THREADS
1649 res = (*statfunc)(path, &st);
1650 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001651
Victor Stinner97b89882010-05-06 00:25:39 +00001652 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001653#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00001654 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001655#else
Victor Stinner97b89882010-05-06 00:25:39 +00001656 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001657#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001658 }
1659 else
1660 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001661
Victor Stinner97b89882010-05-06 00:25:39 +00001662 release_bytes(opath);
1663 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001664}
1665
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001666/* POSIX methods */
1667
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001668PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001669"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001670Use the real uid/gid to test for access to a path. Note that most\n\
1671operations will use the effective uid/gid, therefore this routine can\n\
1672be used in a suid/sgid environment to test if the invoking user has the\n\
1673specified access to the path. The mode argument can be F_OK to test\n\
1674existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001675
1676static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001677posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001678{
Victor Stinner97b89882010-05-06 00:25:39 +00001679 PyObject *opath;
1680 char *path;
1681 int mode;
1682
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001683#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00001684 DWORD attr;
1685 if (unicode_file_names()) {
1686 PyUnicodeObject *po;
1687 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1688 Py_BEGIN_ALLOW_THREADS
1689 /* PyUnicode_AS_UNICODE OK without thread lock as
1690 it is a simple dereference. */
1691 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1692 Py_END_ALLOW_THREADS
1693 goto finish;
1694 }
1695 /* Drop the argument parsing error as narrow strings
1696 are also valid. */
1697 PyErr_Clear();
1698 }
1699 if (!PyArg_ParseTuple(args, "O&i:access",
1700 PyUnicode_FSConverter, &opath, &mode))
1701 return 0;
1702 path = bytes2str(opath, 1);
1703 Py_BEGIN_ALLOW_THREADS
1704 attr = GetFileAttributesA(path);
1705 Py_END_ALLOW_THREADS
1706 release_bytes(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001707finish:
Victor Stinner97b89882010-05-06 00:25:39 +00001708 if (attr == 0xFFFFFFFF)
1709 /* File does not exist, or cannot read attributes */
1710 return PyBool_FromLong(0);
1711 /* Access is possible if either write access wasn't requested, or
1712 the file isn't read-only, or if it's a directory, as there are
1713 no read-only directories on Windows. */
1714 return PyBool_FromLong(!(mode & 2)
1715 || !(attr & FILE_ATTRIBUTE_READONLY)
1716 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001717#else
Victor Stinner97b89882010-05-06 00:25:39 +00001718 int res;
1719 if (!PyArg_ParseTuple(args, "O&i:access",
1720 PyUnicode_FSConverter, &opath, &mode))
1721 return NULL;
1722 path = bytes2str(opath, 1);
1723 Py_BEGIN_ALLOW_THREADS
1724 res = access(path, mode);
1725 Py_END_ALLOW_THREADS
1726 release_bytes(opath);
1727 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001728#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001729}
1730
Guido van Rossumd371ff11999-01-25 16:12:23 +00001731#ifndef F_OK
1732#define F_OK 0
1733#endif
1734#ifndef R_OK
1735#define R_OK 4
1736#endif
1737#ifndef W_OK
1738#define W_OK 2
1739#endif
1740#ifndef X_OK
1741#define X_OK 1
1742#endif
1743
1744#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001745PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001746"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001747Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001748
1749static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001750posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001751{
Victor Stinner97b89882010-05-06 00:25:39 +00001752 int id;
1753 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001754
Victor Stinner97b89882010-05-06 00:25:39 +00001755 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1756 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001757
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001758#if defined(__VMS)
Victor Stinner97b89882010-05-06 00:25:39 +00001759 /* file descriptor 0 only, the default input device (stdin) */
1760 if (id == 0) {
1761 ret = ttyname();
1762 }
1763 else {
1764 ret = NULL;
1765 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001766#else
Victor Stinner97b89882010-05-06 00:25:39 +00001767 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001768#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001769 if (ret == NULL)
1770 return posix_error();
Victor Stinnerbae0e622010-08-15 09:15:02 +00001771 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001772}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001773#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001774
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001775#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001776PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001777"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001778Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001779
1780static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001781posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001782{
Victor Stinner97b89882010-05-06 00:25:39 +00001783 char *ret;
1784 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001785
Greg Wardb48bc172000-03-01 21:51:56 +00001786#ifdef USE_CTERMID_R
Victor Stinner97b89882010-05-06 00:25:39 +00001787 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001788#else
Victor Stinner97b89882010-05-06 00:25:39 +00001789 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001790#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001791 if (ret == NULL)
1792 return posix_error();
Victor Stinnerbae0e622010-08-15 09:15:02 +00001793 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001794}
1795#endif
1796
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001797PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001798"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001799Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001800
Barry Warsaw53699e91996-12-10 23:23:01 +00001801static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001802posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001803{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001804#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00001805 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001806#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner97b89882010-05-06 00:25:39 +00001807 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001808#elif defined(__VMS)
Victor Stinner97b89882010-05-06 00:25:39 +00001809 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001810#else
Victor Stinner97b89882010-05-06 00:25:39 +00001811 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001812#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001813}
1814
Fred Drake4d1e64b2002-04-15 19:40:07 +00001815#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001816PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001817"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001818Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001819opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001820
1821static PyObject *
1822posix_fchdir(PyObject *self, PyObject *fdobj)
1823{
Victor Stinner97b89882010-05-06 00:25:39 +00001824 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001825}
1826#endif /* HAVE_FCHDIR */
1827
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001828
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001829PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001830"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001831Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001832
Barry Warsaw53699e91996-12-10 23:23:01 +00001833static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001834posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001835{
Victor Stinner97b89882010-05-06 00:25:39 +00001836 PyObject *opath = NULL;
1837 char *path = NULL;
1838 int i;
1839 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001840#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00001841 DWORD attr;
1842 if (unicode_file_names()) {
1843 PyUnicodeObject *po;
1844 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1845 Py_BEGIN_ALLOW_THREADS
1846 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1847 if (attr != 0xFFFFFFFF) {
1848 if (i & _S_IWRITE)
1849 attr &= ~FILE_ATTRIBUTE_READONLY;
1850 else
1851 attr |= FILE_ATTRIBUTE_READONLY;
1852 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1853 }
1854 else
1855 res = 0;
1856 Py_END_ALLOW_THREADS
1857 if (!res)
1858 return win32_error_unicode("chmod",
1859 PyUnicode_AS_UNICODE(po));
1860 Py_INCREF(Py_None);
1861 return Py_None;
1862 }
1863 /* Drop the argument parsing error as narrow strings
1864 are also valid. */
1865 PyErr_Clear();
1866 }
1867 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1868 &opath, &i))
1869 return NULL;
1870 path = bytes2str(opath, 1);
1871 Py_BEGIN_ALLOW_THREADS
1872 attr = GetFileAttributesA(path);
1873 if (attr != 0xFFFFFFFF) {
1874 if (i & _S_IWRITE)
1875 attr &= ~FILE_ATTRIBUTE_READONLY;
1876 else
1877 attr |= FILE_ATTRIBUTE_READONLY;
1878 res = SetFileAttributesA(path, attr);
1879 }
1880 else
1881 res = 0;
1882 Py_END_ALLOW_THREADS
1883 if (!res) {
1884 win32_error("chmod", path);
1885 release_bytes(opath);
1886 return NULL;
1887 }
1888 release_bytes(opath);
1889 Py_INCREF(Py_None);
1890 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001891#else /* MS_WINDOWS */
Victor Stinner97b89882010-05-06 00:25:39 +00001892 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1893 &opath, &i))
1894 return NULL;
1895 path = bytes2str(opath, 1);
1896 Py_BEGIN_ALLOW_THREADS
1897 res = chmod(path, i);
1898 Py_END_ALLOW_THREADS
1899 if (res < 0)
1900 return posix_error_with_allocated_filename(opath);
1901 release_bytes(opath);
1902 Py_INCREF(Py_None);
1903 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001904#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001905}
1906
Christian Heimes4e30a842007-11-30 22:12:06 +00001907#ifdef HAVE_FCHMOD
1908PyDoc_STRVAR(posix_fchmod__doc__,
1909"fchmod(fd, mode)\n\n\
1910Change the access permissions of the file given by file\n\
1911descriptor fd.");
1912
1913static PyObject *
1914posix_fchmod(PyObject *self, PyObject *args)
1915{
Victor Stinner97b89882010-05-06 00:25:39 +00001916 int fd, mode, res;
1917 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1918 return NULL;
1919 Py_BEGIN_ALLOW_THREADS
1920 res = fchmod(fd, mode);
1921 Py_END_ALLOW_THREADS
1922 if (res < 0)
1923 return posix_error();
1924 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001925}
1926#endif /* HAVE_FCHMOD */
1927
1928#ifdef HAVE_LCHMOD
1929PyDoc_STRVAR(posix_lchmod__doc__,
1930"lchmod(path, mode)\n\n\
1931Change the access permissions of a file. If path is a symlink, this\n\
1932affects the link itself rather than the target.");
1933
1934static PyObject *
1935posix_lchmod(PyObject *self, PyObject *args)
1936{
Victor Stinner97b89882010-05-06 00:25:39 +00001937 PyObject *opath;
1938 char *path;
1939 int i;
1940 int res;
1941 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
1942 &opath, &i))
1943 return NULL;
1944 path = bytes2str(opath, 1);
1945 Py_BEGIN_ALLOW_THREADS
1946 res = lchmod(path, i);
1947 Py_END_ALLOW_THREADS
1948 if (res < 0)
1949 return posix_error_with_allocated_filename(opath);
1950 release_bytes(opath);
1951 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001952}
1953#endif /* HAVE_LCHMOD */
1954
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001955
Thomas Wouterscf297e42007-02-23 15:07:44 +00001956#ifdef HAVE_CHFLAGS
1957PyDoc_STRVAR(posix_chflags__doc__,
1958"chflags(path, flags)\n\n\
1959Set file flags.");
1960
1961static PyObject *
1962posix_chflags(PyObject *self, PyObject *args)
1963{
Victor Stinner97b89882010-05-06 00:25:39 +00001964 PyObject *opath;
1965 char *path;
1966 unsigned long flags;
1967 int res;
1968 if (!PyArg_ParseTuple(args, "O&k:chflags",
1969 PyUnicode_FSConverter, &opath, &flags))
1970 return NULL;
1971 path = bytes2str(opath, 1);
1972 Py_BEGIN_ALLOW_THREADS
1973 res = chflags(path, flags);
1974 Py_END_ALLOW_THREADS
1975 if (res < 0)
1976 return posix_error_with_allocated_filename(opath);
1977 release_bytes(opath);
1978 Py_INCREF(Py_None);
1979 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00001980}
1981#endif /* HAVE_CHFLAGS */
1982
1983#ifdef HAVE_LCHFLAGS
1984PyDoc_STRVAR(posix_lchflags__doc__,
1985"lchflags(path, flags)\n\n\
1986Set file flags.\n\
1987This function will not follow symbolic links.");
1988
1989static PyObject *
1990posix_lchflags(PyObject *self, PyObject *args)
1991{
Victor Stinner97b89882010-05-06 00:25:39 +00001992 PyObject *opath;
1993 char *path;
1994 unsigned long flags;
1995 int res;
1996 if (!PyArg_ParseTuple(args, "O&k:lchflags",
1997 PyUnicode_FSConverter, &opath, &flags))
1998 return NULL;
1999 path = bytes2str(opath, 1);
2000 Py_BEGIN_ALLOW_THREADS
2001 res = lchflags(path, flags);
2002 Py_END_ALLOW_THREADS
2003 if (res < 0)
2004 return posix_error_with_allocated_filename(opath);
2005 release_bytes(opath);
2006 Py_INCREF(Py_None);
2007 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002008}
2009#endif /* HAVE_LCHFLAGS */
2010
Martin v. Löwis244edc82001-10-04 22:44:26 +00002011#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002012PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002013"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002014Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002015
2016static PyObject *
2017posix_chroot(PyObject *self, PyObject *args)
2018{
Victor Stinner97b89882010-05-06 00:25:39 +00002019 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002020}
2021#endif
2022
Guido van Rossum21142a01999-01-08 21:05:37 +00002023#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002024PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002025"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002026force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002027
2028static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002029posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002030{
Stefan Krah67733312010-11-26 17:04:40 +00002031 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002032}
2033#endif /* HAVE_FSYNC */
2034
2035#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002036
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002037#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002038extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2039#endif
2040
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002041PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002042"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002043force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002044 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002045
2046static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002047posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002048{
Stefan Krah67733312010-11-26 17:04:40 +00002049 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002050}
2051#endif /* HAVE_FDATASYNC */
2052
2053
Fredrik Lundh10723342000-07-10 16:38:09 +00002054#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002055PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002056"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002057Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002058
Barry Warsaw53699e91996-12-10 23:23:01 +00002059static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002060posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002061{
Victor Stinner97b89882010-05-06 00:25:39 +00002062 PyObject *opath;
2063 char *path;
2064 long uid, gid;
2065 int res;
2066 if (!PyArg_ParseTuple(args, "O&ll:chown",
2067 PyUnicode_FSConverter, &opath,
2068 &uid, &gid))
2069 return NULL;
2070 path = bytes2str(opath, 1);
2071 Py_BEGIN_ALLOW_THREADS
2072 res = chown(path, (uid_t) uid, (gid_t) gid);
2073 Py_END_ALLOW_THREADS
2074 if (res < 0)
2075 return posix_error_with_allocated_filename(opath);
2076 release_bytes(opath);
2077 Py_INCREF(Py_None);
2078 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002079}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002080#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002081
Christian Heimes4e30a842007-11-30 22:12:06 +00002082#ifdef HAVE_FCHOWN
2083PyDoc_STRVAR(posix_fchown__doc__,
2084"fchown(fd, uid, gid)\n\n\
2085Change the owner and group id of the file given by file descriptor\n\
2086fd to the numeric uid and gid.");
2087
2088static PyObject *
2089posix_fchown(PyObject *self, PyObject *args)
2090{
Victor Stinner97b89882010-05-06 00:25:39 +00002091 int fd;
2092 long uid, gid;
2093 int res;
2094 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
2095 return NULL;
2096 Py_BEGIN_ALLOW_THREADS
2097 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2098 Py_END_ALLOW_THREADS
2099 if (res < 0)
2100 return posix_error();
2101 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002102}
2103#endif /* HAVE_FCHOWN */
2104
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002105#ifdef HAVE_LCHOWN
2106PyDoc_STRVAR(posix_lchown__doc__,
2107"lchown(path, uid, gid)\n\n\
2108Change the owner and group id of path to the numeric uid and gid.\n\
2109This function will not follow symbolic links.");
2110
2111static PyObject *
2112posix_lchown(PyObject *self, PyObject *args)
2113{
Victor Stinner97b89882010-05-06 00:25:39 +00002114 PyObject *opath;
2115 char *path;
2116 long uid, gid;
2117 int res;
2118 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2119 PyUnicode_FSConverter, &opath,
2120 &uid, &gid))
2121 return NULL;
2122 path = bytes2str(opath, 1);
2123 Py_BEGIN_ALLOW_THREADS
2124 res = lchown(path, (uid_t) uid, (gid_t) gid);
2125 Py_END_ALLOW_THREADS
2126 if (res < 0)
2127 return posix_error_with_allocated_filename(opath);
2128 release_bytes(opath);
2129 Py_INCREF(Py_None);
2130 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002131}
2132#endif /* HAVE_LCHOWN */
2133
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002134
Guido van Rossum36bc6801995-06-14 22:54:23 +00002135#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002136static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002137posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002138{
Victor Stinner97b89882010-05-06 00:25:39 +00002139 char buf[1026];
2140 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002141
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002142#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002143 if (!use_bytes && unicode_file_names()) {
2144 wchar_t wbuf[1026];
2145 wchar_t *wbuf2 = wbuf;
2146 PyObject *resobj;
2147 DWORD len;
2148 Py_BEGIN_ALLOW_THREADS
2149 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2150 /* If the buffer is large enough, len does not include the
2151 terminating \0. If the buffer is too small, len includes
2152 the space needed for the terminator. */
2153 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2154 wbuf2 = malloc(len * sizeof(wchar_t));
2155 if (wbuf2)
2156 len = GetCurrentDirectoryW(len, wbuf2);
2157 }
2158 Py_END_ALLOW_THREADS
2159 if (!wbuf2) {
2160 PyErr_NoMemory();
2161 return NULL;
2162 }
2163 if (!len) {
2164 if (wbuf2 != wbuf) free(wbuf2);
2165 return win32_error("getcwdu", NULL);
2166 }
2167 resobj = PyUnicode_FromWideChar(wbuf2, len);
2168 if (wbuf2 != wbuf) free(wbuf2);
2169 return resobj;
2170 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002171#endif
2172
Victor Stinner97b89882010-05-06 00:25:39 +00002173 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002174#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner97b89882010-05-06 00:25:39 +00002175 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002176#else
Victor Stinner97b89882010-05-06 00:25:39 +00002177 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002178#endif
Victor Stinner97b89882010-05-06 00:25:39 +00002179 Py_END_ALLOW_THREADS
2180 if (res == NULL)
2181 return posix_error();
2182 if (use_bytes)
2183 return PyBytes_FromStringAndSize(buf, strlen(buf));
2184 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"surrogateescape");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002185}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002186
2187PyDoc_STRVAR(posix_getcwd__doc__,
2188"getcwd() -> path\n\n\
2189Return a unicode string representing the current working directory.");
2190
2191static PyObject *
2192posix_getcwd_unicode(PyObject *self)
2193{
2194 return posix_getcwd(0);
2195}
2196
2197PyDoc_STRVAR(posix_getcwdb__doc__,
2198"getcwdb() -> path\n\n\
2199Return a bytes string representing the current working directory.");
2200
2201static PyObject *
2202posix_getcwd_bytes(PyObject *self)
2203{
2204 return posix_getcwd(1);
2205}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002206#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002207
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002208
Guido van Rossumb6775db1994-08-01 11:34:53 +00002209#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002210PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002211"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002212Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002213
Barry Warsaw53699e91996-12-10 23:23:01 +00002214static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002215posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002216{
Victor Stinner97b89882010-05-06 00:25:39 +00002217 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002218}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002219#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002220
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002221
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002222PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002223"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002224Return a list containing the names of the entries in the directory.\n\
2225\n\
Victor Stinner97b89882010-05-06 00:25:39 +00002226 path: path of directory to list\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002227\n\
2228The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002229entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002230
Barry Warsaw53699e91996-12-10 23:23:01 +00002231static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002232posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002233{
Victor Stinner97b89882010-05-06 00:25:39 +00002234 /* XXX Should redo this putting the (now four) versions of opendir
2235 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002236#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002237
Victor Stinner97b89882010-05-06 00:25:39 +00002238 PyObject *d, *v;
2239 HANDLE hFindFile;
2240 BOOL result;
2241 WIN32_FIND_DATA FileData;
2242 PyObject *opath;
2243 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2244 char *bufptr = namebuf;
2245 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002246
Victor Stinner97b89882010-05-06 00:25:39 +00002247 /* If on wide-character-capable OS see if argument
2248 is Unicode and if so use wide API. */
2249 if (unicode_file_names()) {
2250 PyObject *po;
2251 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2252 WIN32_FIND_DATAW wFileData;
2253 Py_UNICODE *wnamebuf;
2254 /* Overallocate for \\*.*\0 */
2255 len = PyUnicode_GET_SIZE(po);
2256 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2257 if (!wnamebuf) {
2258 PyErr_NoMemory();
2259 return NULL;
2260 }
2261 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2262 if (len > 0) {
2263 Py_UNICODE wch = wnamebuf[len-1];
2264 if (wch != L'/' && wch != L'\\' && wch != L':')
2265 wnamebuf[len++] = L'\\';
2266 wcscpy(wnamebuf + len, L"*.*");
2267 }
2268 if ((d = PyList_New(0)) == NULL) {
2269 free(wnamebuf);
2270 return NULL;
2271 }
Antoine Pitroubd25d592010-08-09 23:47:57 +00002272 Py_BEGIN_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002273 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroubd25d592010-08-09 23:47:57 +00002274 Py_END_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002275 if (hFindFile == INVALID_HANDLE_VALUE) {
2276 int error = GetLastError();
2277 if (error == ERROR_FILE_NOT_FOUND) {
2278 free(wnamebuf);
2279 return d;
2280 }
2281 Py_DECREF(d);
2282 win32_error_unicode("FindFirstFileW", wnamebuf);
2283 free(wnamebuf);
2284 return NULL;
2285 }
2286 do {
2287 /* Skip over . and .. */
2288 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2289 wcscmp(wFileData.cFileName, L"..") != 0) {
2290 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2291 if (v == NULL) {
2292 Py_DECREF(d);
2293 d = NULL;
2294 break;
2295 }
2296 if (PyList_Append(d, v) != 0) {
2297 Py_DECREF(v);
2298 Py_DECREF(d);
2299 d = NULL;
2300 break;
2301 }
2302 Py_DECREF(v);
2303 }
2304 Py_BEGIN_ALLOW_THREADS
2305 result = FindNextFileW(hFindFile, &wFileData);
2306 Py_END_ALLOW_THREADS
2307 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2308 it got to the end of the directory. */
2309 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2310 Py_DECREF(d);
2311 win32_error_unicode("FindNextFileW", wnamebuf);
2312 FindClose(hFindFile);
2313 free(wnamebuf);
2314 return NULL;
2315 }
2316 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002317
Victor Stinner97b89882010-05-06 00:25:39 +00002318 if (FindClose(hFindFile) == FALSE) {
2319 Py_DECREF(d);
2320 win32_error_unicode("FindClose", wnamebuf);
2321 free(wnamebuf);
2322 return NULL;
2323 }
2324 free(wnamebuf);
2325 return d;
2326 }
2327 /* Drop the argument parsing error as narrow strings
2328 are also valid. */
2329 PyErr_Clear();
2330 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002331
Victor Stinner97b89882010-05-06 00:25:39 +00002332 if (!PyArg_ParseTuple(args, "O&:listdir",
2333 PyUnicode_FSConverter, &opath))
2334 return NULL;
2335 if (PyObject_Size(opath)+1 > MAX_PATH) {
2336 PyErr_SetString(PyExc_ValueError, "path too long");
2337 Py_DECREF(opath);
2338 return NULL;
2339 }
2340 strcpy(namebuf, bytes2str(opath, 0));
2341 len = PyObject_Size(opath);
2342 if (len > 0) {
2343 char ch = namebuf[len-1];
2344 if (ch != SEP && ch != ALTSEP && ch != ':')
2345 namebuf[len++] = '/';
2346 strcpy(namebuf + len, "*.*");
2347 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002348
Victor Stinner97b89882010-05-06 00:25:39 +00002349 if ((d = PyList_New(0)) == NULL)
2350 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002351
Antoine Pitroubd25d592010-08-09 23:47:57 +00002352 Py_BEGIN_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002353 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroubd25d592010-08-09 23:47:57 +00002354 Py_END_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002355 if (hFindFile == INVALID_HANDLE_VALUE) {
2356 int error = GetLastError();
2357 if (error == ERROR_FILE_NOT_FOUND)
2358 return d;
2359 Py_DECREF(d);
2360 return win32_error("FindFirstFile", namebuf);
2361 }
2362 do {
2363 /* Skip over . and .. */
2364 if (strcmp(FileData.cFileName, ".") != 0 &&
2365 strcmp(FileData.cFileName, "..") != 0) {
2366 v = PyBytes_FromString(FileData.cFileName);
2367 if (v == NULL) {
2368 Py_DECREF(d);
2369 d = NULL;
2370 break;
2371 }
2372 if (PyList_Append(d, v) != 0) {
2373 Py_DECREF(v);
2374 Py_DECREF(d);
2375 d = NULL;
2376 break;
2377 }
2378 Py_DECREF(v);
2379 }
2380 Py_BEGIN_ALLOW_THREADS
2381 result = FindNextFile(hFindFile, &FileData);
2382 Py_END_ALLOW_THREADS
2383 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2384 it got to the end of the directory. */
2385 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2386 Py_DECREF(d);
2387 win32_error("FindNextFile", namebuf);
2388 FindClose(hFindFile);
2389 return NULL;
2390 }
2391 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002392
Victor Stinner97b89882010-05-06 00:25:39 +00002393 if (FindClose(hFindFile) == FALSE) {
2394 Py_DECREF(d);
2395 return win32_error("FindClose", namebuf);
2396 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002397
Victor Stinner97b89882010-05-06 00:25:39 +00002398 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002399
Tim Peters0bb44a42000-09-15 07:44:49 +00002400#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002401
2402#ifndef MAX_PATH
2403#define MAX_PATH CCHMAXPATH
2404#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002405 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002406 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002407 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002408 PyObject *d, *v;
2409 char namebuf[MAX_PATH+5];
2410 HDIR hdir = 1;
2411 ULONG srchcnt = 1;
2412 FILEFINDBUF3 ep;
2413 APIRET rc;
2414
Victor Stinner97b89882010-05-06 00:25:39 +00002415 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002416 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002417 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002418 name = bytes2str(oname);
2419 len = PyObject_Size(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002420 if (len >= MAX_PATH) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00002421 release_bytes(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002422 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002423 return NULL;
2424 }
2425 strcpy(namebuf, name);
2426 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002427 if (*pt == ALTSEP)
2428 *pt = SEP;
2429 if (namebuf[len-1] != SEP)
2430 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002431 strcpy(namebuf + len, "*.*");
2432
Neal Norwitz6c913782007-10-14 03:23:09 +00002433 if ((d = PyList_New(0)) == NULL) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00002434 release_bytes(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002435 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002436 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002437
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002438 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2439 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002440 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002441 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2442 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2443 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002444
2445 if (rc != NO_ERROR) {
2446 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002447 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002448 }
2449
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002450 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002451 do {
2452 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002453 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002454 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002455
2456 strcpy(namebuf, ep.achName);
2457
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002458 /* Leave Case of Name Alone -- In Native Form */
2459 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002460
Christian Heimes72b710a2008-05-26 13:28:38 +00002461 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002462 if (v == NULL) {
2463 Py_DECREF(d);
2464 d = NULL;
2465 break;
2466 }
2467 if (PyList_Append(d, v) != 0) {
2468 Py_DECREF(v);
2469 Py_DECREF(d);
2470 d = NULL;
2471 break;
2472 }
2473 Py_DECREF(v);
2474 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2475 }
2476
Martin v. Löwis011e8422009-05-05 04:43:17 +00002477 release_bytes(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002478 return d;
2479#else
Victor Stinner97b89882010-05-06 00:25:39 +00002480 PyObject *oname;
2481 char *name;
2482 PyObject *d, *v;
2483 DIR *dirp;
2484 struct dirent *ep;
2485 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002486
Victor Stinner97b89882010-05-06 00:25:39 +00002487 errno = 0;
2488 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2489 arg_is_unicode = 0;
2490 PyErr_Clear();
2491 }
2492 if (!PyArg_ParseTuple(args, "O&:listdir", PyUnicode_FSConverter, &oname))
2493 return NULL;
2494 name = bytes2str(oname, 1);
Antoine Pitrou037077f2010-09-04 17:26:01 +00002495 Py_BEGIN_ALLOW_THREADS
2496 dirp = opendir(name);
2497 Py_END_ALLOW_THREADS
2498 if (dirp == NULL) {
Victor Stinner97b89882010-05-06 00:25:39 +00002499 return posix_error_with_allocated_filename(oname);
2500 }
2501 if ((d = PyList_New(0)) == NULL) {
Antoine Pitrou037077f2010-09-04 17:26:01 +00002502 Py_BEGIN_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002503 closedir(dirp);
Antoine Pitrou037077f2010-09-04 17:26:01 +00002504 Py_END_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002505 release_bytes(oname);
2506 return NULL;
2507 }
2508 for (;;) {
2509 errno = 0;
2510 Py_BEGIN_ALLOW_THREADS
2511 ep = readdir(dirp);
2512 Py_END_ALLOW_THREADS
2513 if (ep == NULL) {
2514 if (errno == 0) {
2515 break;
2516 } else {
Antoine Pitrou037077f2010-09-04 17:26:01 +00002517 Py_BEGIN_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002518 closedir(dirp);
Antoine Pitrou037077f2010-09-04 17:26:01 +00002519 Py_END_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002520 Py_DECREF(d);
2521 return posix_error_with_allocated_filename(oname);
2522 }
2523 }
2524 if (ep->d_name[0] == '.' &&
2525 (NAMLEN(ep) == 1 ||
2526 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2527 continue;
Victor Stinner203406c2010-05-14 18:07:39 +00002528 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner97b89882010-05-06 00:25:39 +00002529 if (v == NULL) {
Victor Stinner203406c2010-05-14 18:07:39 +00002530 Py_DECREF(d);
2531 d = NULL;
Victor Stinner97b89882010-05-06 00:25:39 +00002532 break;
2533 }
Victor Stinner203406c2010-05-14 18:07:39 +00002534 if (arg_is_unicode) {
2535 PyObject *w;
2536
2537 w = PyUnicode_FromEncodedObject(v,
2538 Py_FileSystemDefaultEncoding,
2539 "surrogateescape");
2540 Py_DECREF(v);
2541 if (w != NULL)
2542 v = w;
2543 else {
2544 /* Encoding failed to decode ASCII bytes.
2545 Raise exception. */
2546 Py_DECREF(d);
2547 d = NULL;
2548 break;
2549 }
2550 }
Victor Stinner97b89882010-05-06 00:25:39 +00002551 if (PyList_Append(d, v) != 0) {
2552 Py_DECREF(v);
Victor Stinner203406c2010-05-14 18:07:39 +00002553 Py_DECREF(d);
2554 d = NULL;
Victor Stinner97b89882010-05-06 00:25:39 +00002555 break;
2556 }
2557 Py_DECREF(v);
2558 }
Antoine Pitrou037077f2010-09-04 17:26:01 +00002559 Py_BEGIN_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002560 closedir(dirp);
Antoine Pitrou037077f2010-09-04 17:26:01 +00002561 Py_END_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002562 release_bytes(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002563
Victor Stinner97b89882010-05-06 00:25:39 +00002564 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002565
Tim Peters0bb44a42000-09-15 07:44:49 +00002566#endif /* which OS */
2567} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002568
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002569#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002570/* A helper function for abspath on win32 */
2571static PyObject *
2572posix__getfullpathname(PyObject *self, PyObject *args)
2573{
Victor Stinner97b89882010-05-06 00:25:39 +00002574 PyObject *opath;
2575 char *path;
2576 char outbuf[MAX_PATH*2];
2577 char *temp;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002578#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002579 if (unicode_file_names()) {
2580 PyUnicodeObject *po;
2581 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2582 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2583 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2584 Py_UNICODE *wtemp;
2585 DWORD result;
2586 PyObject *v;
2587 result = GetFullPathNameW(wpath,
2588 sizeof(woutbuf)/sizeof(woutbuf[0]),
2589 woutbuf, &wtemp);
2590 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2591 woutbufp = malloc(result * sizeof(Py_UNICODE));
2592 if (!woutbufp)
2593 return PyErr_NoMemory();
2594 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2595 }
2596 if (result)
2597 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2598 else
2599 v = win32_error_unicode("GetFullPathNameW", wpath);
2600 if (woutbufp != woutbuf)
2601 free(woutbufp);
2602 return v;
2603 }
2604 /* Drop the argument parsing error as narrow strings
2605 are also valid. */
2606 PyErr_Clear();
2607 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002608#endif
Victor Stinner97b89882010-05-06 00:25:39 +00002609 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2610 PyUnicode_FSConverter, &opath))
2611 return NULL;
2612 path = bytes2str(opath, 1);
2613 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2614 outbuf, &temp)) {
2615 win32_error("GetFullPathName", path);
2616 release_bytes(opath);
2617 return NULL;
2618 }
2619 release_bytes(opath);
2620 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2621 return PyUnicode_Decode(outbuf, strlen(outbuf),
2622 Py_FileSystemDefaultEncoding, NULL);
2623 }
2624 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002625} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002626#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002627
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002628PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002629"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002630Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002631
Barry Warsaw53699e91996-12-10 23:23:01 +00002632static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002633posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002634{
Victor Stinner97b89882010-05-06 00:25:39 +00002635 int res;
2636 PyObject *opath;
2637 char *path;
2638 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002639
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002640#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002641 if (unicode_file_names()) {
2642 PyUnicodeObject *po;
2643 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2644 Py_BEGIN_ALLOW_THREADS
2645 /* PyUnicode_AS_UNICODE OK without thread lock as
2646 it is a simple dereference. */
2647 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2648 Py_END_ALLOW_THREADS
2649 if (!res)
2650 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2651 Py_INCREF(Py_None);
2652 return Py_None;
2653 }
2654 /* Drop the argument parsing error as narrow strings
2655 are also valid. */
2656 PyErr_Clear();
2657 }
2658 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2659 PyUnicode_FSConverter, &opath, &mode))
2660 return NULL;
2661 path = bytes2str(opath, 1);
2662 Py_BEGIN_ALLOW_THREADS
2663 /* PyUnicode_AS_UNICODE OK without thread lock as
2664 it is a simple dereference. */
2665 res = CreateDirectoryA(path, NULL);
2666 Py_END_ALLOW_THREADS
2667 if (!res) {
2668 win32_error("mkdir", path);
2669 release_bytes(opath);
2670 return NULL;
2671 }
2672 release_bytes(opath);
2673 Py_INCREF(Py_None);
2674 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002675#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002676
Victor Stinner97b89882010-05-06 00:25:39 +00002677 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2678 PyUnicode_FSConverter, &opath, &mode))
2679 return NULL;
2680 path = bytes2str(opath, 1);
2681 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002682#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner97b89882010-05-06 00:25:39 +00002683 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002684#else
Victor Stinner97b89882010-05-06 00:25:39 +00002685 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002686#endif
Victor Stinner97b89882010-05-06 00:25:39 +00002687 Py_END_ALLOW_THREADS
2688 if (res < 0)
2689 return posix_error_with_allocated_filename(opath);
2690 release_bytes(opath);
2691 Py_INCREF(Py_None);
2692 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002693#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002694}
2695
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002696
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002697/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2698#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002699#include <sys/resource.h>
2700#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002701
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002702
2703#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002704PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002705"nice(inc) -> new_priority\n\n\
2706Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002707
Barry Warsaw53699e91996-12-10 23:23:01 +00002708static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002709posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002710{
Victor Stinner97b89882010-05-06 00:25:39 +00002711 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002712
Victor Stinner97b89882010-05-06 00:25:39 +00002713 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2714 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002715
Victor Stinner97b89882010-05-06 00:25:39 +00002716 /* There are two flavours of 'nice': one that returns the new
2717 priority (as required by almost all standards out there) and the
2718 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2719 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002720
Victor Stinner97b89882010-05-06 00:25:39 +00002721 If we are of the nice family that returns the new priority, we
2722 need to clear errno before the call, and check if errno is filled
2723 before calling posix_error() on a returnvalue of -1, because the
2724 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002725
Victor Stinner97b89882010-05-06 00:25:39 +00002726 errno = 0;
2727 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002728#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner97b89882010-05-06 00:25:39 +00002729 if (value == 0)
2730 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002731#endif
Victor Stinner97b89882010-05-06 00:25:39 +00002732 if (value == -1 && errno != 0)
2733 /* either nice() or getpriority() returned an error */
2734 return posix_error();
2735 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002736}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002737#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002738
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002739PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002740"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002741Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002742
Barry Warsaw53699e91996-12-10 23:23:01 +00002743static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002744posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002745{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002746#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002747 PyObject *o1, *o2;
2748 char *p1, *p2;
2749 BOOL result;
2750 if (unicode_file_names()) {
2751 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2752 goto error;
2753 if (!convert_to_unicode(&o1))
2754 goto error;
2755 if (!convert_to_unicode(&o2)) {
2756 Py_DECREF(o1);
2757 goto error;
2758 }
2759 Py_BEGIN_ALLOW_THREADS
2760 result = MoveFileW(PyUnicode_AsUnicode(o1),
2761 PyUnicode_AsUnicode(o2));
2762 Py_END_ALLOW_THREADS
2763 Py_DECREF(o1);
2764 Py_DECREF(o2);
2765 if (!result)
2766 return win32_error("rename", NULL);
2767 Py_INCREF(Py_None);
2768 return Py_None;
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +00002769error:
Victor Stinner97b89882010-05-06 00:25:39 +00002770 PyErr_Clear();
2771 }
2772 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2773 return NULL;
2774 Py_BEGIN_ALLOW_THREADS
2775 result = MoveFileA(p1, p2);
2776 Py_END_ALLOW_THREADS
2777 if (!result)
2778 return win32_error("rename", NULL);
2779 Py_INCREF(Py_None);
2780 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002781#else
Victor Stinner97b89882010-05-06 00:25:39 +00002782 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002783#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002784}
2785
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002786
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002787PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002788"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002789Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002790
Barry Warsaw53699e91996-12-10 23:23:01 +00002791static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002792posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002793{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002794#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002795 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002796#else
Victor Stinner97b89882010-05-06 00:25:39 +00002797 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002798#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002799}
2800
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002801
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002802PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002803"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002804Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002805
Barry Warsaw53699e91996-12-10 23:23:01 +00002806static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002807posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002808{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002809#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002810 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002811#else
Victor Stinner97b89882010-05-06 00:25:39 +00002812 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002813#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002814}
2815
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002816
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002817#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002818PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002819"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002820Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002821
Barry Warsaw53699e91996-12-10 23:23:01 +00002822static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002823posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002824{
Victor Stinner97b89882010-05-06 00:25:39 +00002825 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002826#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002827 wchar_t *command;
2828 if (!PyArg_ParseTuple(args, "u:system", &command))
2829 return NULL;
Victor Stinnera5ab4fc2010-04-16 12:47:52 +00002830
Victor Stinner97b89882010-05-06 00:25:39 +00002831 Py_BEGIN_ALLOW_THREADS
2832 sts = _wsystem(command);
2833 Py_END_ALLOW_THREADS
Victor Stinnera5ab4fc2010-04-16 12:47:52 +00002834#else
Victor Stinner97b89882010-05-06 00:25:39 +00002835 PyObject *command_obj;
2836 char *command;
2837 if (!PyArg_ParseTuple(args, "O&:system",
2838 PyUnicode_FSConverter, &command_obj))
2839 return NULL;
Victor Stinnera5ab4fc2010-04-16 12:47:52 +00002840
Victor Stinner97b89882010-05-06 00:25:39 +00002841 command = bytes2str(command_obj, 1);
2842 Py_BEGIN_ALLOW_THREADS
2843 sts = system(command);
2844 Py_END_ALLOW_THREADS
2845 release_bytes(command_obj);
Victor Stinnera5ab4fc2010-04-16 12:47:52 +00002846#endif
Victor Stinner97b89882010-05-06 00:25:39 +00002847 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002848}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002849#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002850
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002851
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002852PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002853"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002854Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002855
Barry Warsaw53699e91996-12-10 23:23:01 +00002856static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002857posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002858{
Victor Stinner97b89882010-05-06 00:25:39 +00002859 int i;
2860 if (!PyArg_ParseTuple(args, "i:umask", &i))
2861 return NULL;
2862 i = (int)umask(i);
2863 if (i < 0)
2864 return posix_error();
2865 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002866}
2867
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002868
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002869PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002870"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002871Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002872
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002873PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002874"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002875Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002876
Barry Warsaw53699e91996-12-10 23:23:01 +00002877static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002878posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002879{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002880#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002881 return win32_1str(args, "remove", "y:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002882#else
Victor Stinner97b89882010-05-06 00:25:39 +00002883 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002884#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002885}
2886
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002887
Guido van Rossumb6775db1994-08-01 11:34:53 +00002888#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002889PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002890"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002891Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002892
Barry Warsaw53699e91996-12-10 23:23:01 +00002893static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002894posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002895{
Victor Stinner97b89882010-05-06 00:25:39 +00002896 struct utsname u;
2897 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002898
Victor Stinner97b89882010-05-06 00:25:39 +00002899 Py_BEGIN_ALLOW_THREADS
2900 res = uname(&u);
2901 Py_END_ALLOW_THREADS
2902 if (res < 0)
2903 return posix_error();
2904 return Py_BuildValue("(sssss)",
2905 u.sysname,
2906 u.nodename,
2907 u.release,
2908 u.version,
2909 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002910}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002911#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002912
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002913static int
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002914extract_time(PyObject *t, time_t* sec, long* usec)
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002915{
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002916 time_t intval;
Victor Stinner97b89882010-05-06 00:25:39 +00002917 if (PyFloat_Check(t)) {
2918 double tval = PyFloat_AsDouble(t);
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002919 PyObject *intobj = PyNumber_Long(t);
Victor Stinner97b89882010-05-06 00:25:39 +00002920 if (!intobj)
2921 return -1;
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002922#if SIZEOF_TIME_T > SIZEOF_LONG
2923 intval = PyLong_AsUnsignedLongLongMask(intobj);
2924#else
Victor Stinner97b89882010-05-06 00:25:39 +00002925 intval = PyLong_AsLong(intobj);
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002926#endif
Victor Stinner97b89882010-05-06 00:25:39 +00002927 Py_DECREF(intobj);
2928 if (intval == -1 && PyErr_Occurred())
2929 return -1;
2930 *sec = intval;
2931 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
2932 if (*usec < 0)
2933 /* If rounding gave us a negative number,
2934 truncate. */
2935 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002936 return 0;
Victor Stinner97b89882010-05-06 00:25:39 +00002937 }
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002938#if SIZEOF_TIME_T > SIZEOF_LONG
2939 intval = PyLong_AsUnsignedLongLongMask(t);
2940#else
Victor Stinner97b89882010-05-06 00:25:39 +00002941 intval = PyLong_AsLong(t);
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002942#endif
Victor Stinner97b89882010-05-06 00:25:39 +00002943 if (intval == -1 && PyErr_Occurred())
2944 return -1;
2945 *sec = intval;
2946 *usec = 0;
2947 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002948}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002949
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002950PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002951"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002952utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002953Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002954second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002955
Barry Warsaw53699e91996-12-10 23:23:01 +00002956static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002957posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002958{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002959#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002960 PyObject *arg;
2961 PyUnicodeObject *obwpath;
2962 wchar_t *wpath = NULL;
2963 PyObject *oapath;
2964 char *apath;
2965 HANDLE hFile;
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002966 time_t atimesec, mtimesec;
2967 long ausec, musec;
Victor Stinner97b89882010-05-06 00:25:39 +00002968 FILETIME atime, mtime;
2969 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002970
Victor Stinner97b89882010-05-06 00:25:39 +00002971 if (unicode_file_names()) {
2972 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2973 wpath = PyUnicode_AS_UNICODE(obwpath);
2974 Py_BEGIN_ALLOW_THREADS
2975 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2976 NULL, OPEN_EXISTING,
2977 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2978 Py_END_ALLOW_THREADS
2979 if (hFile == INVALID_HANDLE_VALUE)
2980 return win32_error_unicode("utime", wpath);
2981 } else
2982 /* Drop the argument parsing error as narrow strings
2983 are also valid. */
2984 PyErr_Clear();
2985 }
2986 if (!wpath) {
2987 if (!PyArg_ParseTuple(args, "O&O:utime",
2988 PyUnicode_FSConverter, &oapath, &arg))
2989 return NULL;
2990 apath = bytes2str(oapath, 1);
2991 Py_BEGIN_ALLOW_THREADS
2992 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2993 NULL, OPEN_EXISTING,
2994 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2995 Py_END_ALLOW_THREADS
2996 if (hFile == INVALID_HANDLE_VALUE) {
2997 win32_error("utime", apath);
2998 release_bytes(oapath);
2999 return NULL;
3000 }
3001 release_bytes(oapath);
3002 }
3003
3004 if (arg == Py_None) {
3005 SYSTEMTIME now;
3006 GetSystemTime(&now);
3007 if (!SystemTimeToFileTime(&now, &mtime) ||
3008 !SystemTimeToFileTime(&now, &atime)) {
3009 win32_error("utime", NULL);
3010 goto done;
Stefan Krah67733312010-11-26 17:04:40 +00003011 }
Victor Stinner97b89882010-05-06 00:25:39 +00003012 }
3013 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3014 PyErr_SetString(PyExc_TypeError,
3015 "utime() arg 2 must be a tuple (atime, mtime)");
3016 goto done;
3017 }
3018 else {
3019 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3020 &atimesec, &ausec) == -1)
3021 goto done;
3022 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3023 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3024 &mtimesec, &musec) == -1)
3025 goto done;
3026 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3027 }
3028 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3029 /* Avoid putting the file name into the error here,
3030 as that may confuse the user into believing that
3031 something is wrong with the file, when it also
3032 could be the time stamp that gives a problem. */
3033 win32_error("utime", NULL);
3034 }
3035 Py_INCREF(Py_None);
3036 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003037done:
Victor Stinner97b89882010-05-06 00:25:39 +00003038 CloseHandle(hFile);
3039 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003040#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003041
Victor Stinner97b89882010-05-06 00:25:39 +00003042 PyObject *opath;
3043 char *path;
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00003044 time_t atime, mtime;
3045 long ausec, musec;
Victor Stinner97b89882010-05-06 00:25:39 +00003046 int res;
3047 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003048
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003049#if defined(HAVE_UTIMES)
Victor Stinner97b89882010-05-06 00:25:39 +00003050 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003051#define ATIME buf[0].tv_sec
3052#define MTIME buf[1].tv_sec
3053#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003054/* XXX should define struct utimbuf instead, above */
Victor Stinner97b89882010-05-06 00:25:39 +00003055 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003056#define ATIME buf.actime
3057#define MTIME buf.modtime
3058#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003059#else /* HAVE_UTIMES */
Victor Stinner97b89882010-05-06 00:25:39 +00003060 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003061#define ATIME buf[0]
3062#define MTIME buf[1]
3063#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003064#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003065
Mark Hammond817c9292003-12-03 01:22:38 +00003066
Victor Stinner97b89882010-05-06 00:25:39 +00003067 if (!PyArg_ParseTuple(args, "O&O:utime",
3068 PyUnicode_FSConverter, &opath, &arg))
3069 return NULL;
3070 path = bytes2str(opath, 1);
3071 if (arg == Py_None) {
3072 /* optional time values not given */
3073 Py_BEGIN_ALLOW_THREADS
3074 res = utime(path, NULL);
3075 Py_END_ALLOW_THREADS
3076 }
3077 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3078 PyErr_SetString(PyExc_TypeError,
3079 "utime() arg 2 must be a tuple (atime, mtime)");
3080 release_bytes(opath);
3081 return NULL;
3082 }
3083 else {
3084 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3085 &atime, &ausec) == -1) {
3086 release_bytes(opath);
3087 return NULL;
3088 }
3089 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3090 &mtime, &musec) == -1) {
3091 release_bytes(opath);
3092 return NULL;
3093 }
3094 ATIME = atime;
3095 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003096#ifdef HAVE_UTIMES
Victor Stinner97b89882010-05-06 00:25:39 +00003097 buf[0].tv_usec = ausec;
3098 buf[1].tv_usec = musec;
3099 Py_BEGIN_ALLOW_THREADS
3100 res = utimes(path, buf);
3101 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003102#else
Victor Stinner97b89882010-05-06 00:25:39 +00003103 Py_BEGIN_ALLOW_THREADS
3104 res = utime(path, UTIME_ARG);
3105 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003106#endif /* HAVE_UTIMES */
Victor Stinner97b89882010-05-06 00:25:39 +00003107 }
3108 if (res < 0) {
3109 return posix_error_with_allocated_filename(opath);
3110 }
3111 release_bytes(opath);
3112 Py_INCREF(Py_None);
3113 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003114#undef UTIME_ARG
3115#undef ATIME
3116#undef MTIME
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003117#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003118}
3119
Guido van Rossum85e3b011991-06-03 12:42:10 +00003120
Guido van Rossum3b066191991-06-04 19:40:25 +00003121/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003122
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003123PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003124"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003125Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003126
Barry Warsaw53699e91996-12-10 23:23:01 +00003127static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003128posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003129{
Victor Stinner97b89882010-05-06 00:25:39 +00003130 int sts;
3131 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3132 return NULL;
3133 _exit(sts);
3134 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003135}
3136
Martin v. Löwis114619e2002-10-07 06:44:21 +00003137#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3138static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003139free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003140{
Victor Stinner97b89882010-05-06 00:25:39 +00003141 Py_ssize_t i;
3142 for (i = 0; i < count; i++)
3143 PyMem_Free(array[i]);
3144 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003145}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003146
Antoine Pitrou69f71142009-05-24 21:25:49 +00003147static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003148int fsconvert_strdup(PyObject *o, char**out)
3149{
Victor Stinner97b89882010-05-06 00:25:39 +00003150 PyObject *bytes;
3151 Py_ssize_t size;
3152 if (!PyUnicode_FSConverter(o, &bytes))
3153 return 0;
3154 size = PyObject_Size(bytes);
3155 *out = PyMem_Malloc(size+1);
3156 if (!*out)
3157 return 0;
3158 /* Don't lock bytes, as we hold the GIL */
3159 memcpy(*out, bytes2str(bytes, 0), size+1);
3160 Py_DECREF(bytes);
3161 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003162}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003163#endif
3164
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003165
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003166#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003167PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003168"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003169Execute an executable path with arguments, replacing current process.\n\
3170\n\
Victor Stinner97b89882010-05-06 00:25:39 +00003171 path: path of executable file\n\
3172 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003173
Barry Warsaw53699e91996-12-10 23:23:01 +00003174static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003175posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003176{
Victor Stinner97b89882010-05-06 00:25:39 +00003177 PyObject *opath;
3178 char *path;
3179 PyObject *argv;
3180 char **argvlist;
3181 Py_ssize_t i, argc;
3182 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003183
Victor Stinner97b89882010-05-06 00:25:39 +00003184 /* execv has two arguments: (path, argv), where
3185 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003186
Victor Stinner97b89882010-05-06 00:25:39 +00003187 if (!PyArg_ParseTuple(args, "O&O:execv",
3188 PyUnicode_FSConverter,
3189 &opath, &argv))
3190 return NULL;
3191 path = bytes2str(opath, 1);
3192 if (PyList_Check(argv)) {
3193 argc = PyList_Size(argv);
3194 getitem = PyList_GetItem;
3195 }
3196 else if (PyTuple_Check(argv)) {
3197 argc = PyTuple_Size(argv);
3198 getitem = PyTuple_GetItem;
3199 }
3200 else {
3201 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3202 release_bytes(opath);
3203 return NULL;
3204 }
3205 if (argc < 1) {
3206 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3207 release_bytes(opath);
3208 return NULL;
3209 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003210
Victor Stinner97b89882010-05-06 00:25:39 +00003211 argvlist = PyMem_NEW(char *, argc+1);
3212 if (argvlist == NULL) {
3213 release_bytes(opath);
3214 return PyErr_NoMemory();
3215 }
3216 for (i = 0; i < argc; i++) {
3217 if (!fsconvert_strdup((*getitem)(argv, i),
3218 &argvlist[i])) {
3219 free_string_array(argvlist, i);
3220 PyErr_SetString(PyExc_TypeError,
3221 "execv() arg 2 must contain only strings");
3222 release_bytes(opath);
3223 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003224
Victor Stinner97b89882010-05-06 00:25:39 +00003225 }
3226 }
3227 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003228
Victor Stinner97b89882010-05-06 00:25:39 +00003229 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003230
Victor Stinner97b89882010-05-06 00:25:39 +00003231 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003232
Victor Stinner97b89882010-05-06 00:25:39 +00003233 free_string_array(argvlist, argc);
3234 release_bytes(opath);
3235 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003236}
3237
Victor Stinnera27dcb72010-04-25 22:39:07 +00003238static char**
3239parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3240{
Victor Stinner97b89882010-05-06 00:25:39 +00003241 char **envlist;
3242 Py_ssize_t i, pos, envc;
3243 PyObject *keys=NULL, *vals=NULL;
3244 PyObject *key, *val, *key2, *val2;
3245 char *p, *k, *v;
3246 size_t len;
Victor Stinnera27dcb72010-04-25 22:39:07 +00003247
Victor Stinner97b89882010-05-06 00:25:39 +00003248 i = PyMapping_Size(env);
3249 if (i < 0)
3250 return NULL;
3251 envlist = PyMem_NEW(char *, i + 1);
3252 if (envlist == NULL) {
3253 PyErr_NoMemory();
3254 return NULL;
3255 }
3256 envc = 0;
3257 keys = PyMapping_Keys(env);
3258 vals = PyMapping_Values(env);
3259 if (!keys || !vals)
3260 goto error;
3261 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3262 PyErr_Format(PyExc_TypeError,
3263 "env.keys() or env.values() is not a list");
3264 goto error;
3265 }
Victor Stinnera27dcb72010-04-25 22:39:07 +00003266
Victor Stinner97b89882010-05-06 00:25:39 +00003267 for (pos = 0; pos < i; pos++) {
3268 key = PyList_GetItem(keys, pos);
3269 val = PyList_GetItem(vals, pos);
3270 if (!key || !val)
3271 goto error;
Victor Stinnera27dcb72010-04-25 22:39:07 +00003272
Victor Stinner97b89882010-05-06 00:25:39 +00003273 if (PyUnicode_FSConverter(key, &key2) == 0)
3274 goto error;
3275 if (PyUnicode_FSConverter(val, &val2) == 0) {
3276 Py_DECREF(key2);
3277 goto error;
3278 }
Victor Stinnera27dcb72010-04-25 22:39:07 +00003279
3280#if defined(PYOS_OS2)
Victor Stinner97b89882010-05-06 00:25:39 +00003281 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3282 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinnera27dcb72010-04-25 22:39:07 +00003283#endif
Victor Stinner97b89882010-05-06 00:25:39 +00003284 k = PyBytes_AsString(key2);
3285 v = PyBytes_AsString(val2);
3286 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinnera27dcb72010-04-25 22:39:07 +00003287
Victor Stinner97b89882010-05-06 00:25:39 +00003288 p = PyMem_NEW(char, len);
3289 if (p == NULL) {
3290 PyErr_NoMemory();
3291 Py_DECREF(key2);
3292 Py_DECREF(val2);
3293 goto error;
3294 }
3295 PyOS_snprintf(p, len, "%s=%s", k, v);
3296 envlist[envc++] = p;
3297 Py_DECREF(key2);
3298 Py_DECREF(val2);
Victor Stinnera27dcb72010-04-25 22:39:07 +00003299#if defined(PYOS_OS2)
Victor Stinner97b89882010-05-06 00:25:39 +00003300 }
Victor Stinnera27dcb72010-04-25 22:39:07 +00003301#endif
Victor Stinner97b89882010-05-06 00:25:39 +00003302 }
3303 Py_DECREF(vals);
3304 Py_DECREF(keys);
Victor Stinnera27dcb72010-04-25 22:39:07 +00003305
Victor Stinner97b89882010-05-06 00:25:39 +00003306 envlist[envc] = 0;
3307 *envc_ptr = envc;
3308 return envlist;
Victor Stinnera27dcb72010-04-25 22:39:07 +00003309
3310error:
Victor Stinner97b89882010-05-06 00:25:39 +00003311 Py_XDECREF(keys);
3312 Py_XDECREF(vals);
3313 while (--envc >= 0)
3314 PyMem_DEL(envlist[envc]);
3315 PyMem_DEL(envlist);
3316 return NULL;
Victor Stinnera27dcb72010-04-25 22:39:07 +00003317}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003318
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003319PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003320"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003321Execute a path with arguments and environment, replacing current process.\n\
3322\n\
Victor Stinner97b89882010-05-06 00:25:39 +00003323 path: path of executable file\n\
3324 args: tuple or list of arguments\n\
3325 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003326
Barry Warsaw53699e91996-12-10 23:23:01 +00003327static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003328posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003329{
Victor Stinner97b89882010-05-06 00:25:39 +00003330 PyObject *opath;
3331 char *path;
3332 PyObject *argv, *env;
3333 char **argvlist;
3334 char **envlist;
3335 Py_ssize_t i, argc, envc;
3336 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3337 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003338
Victor Stinner97b89882010-05-06 00:25:39 +00003339 /* execve has three arguments: (path, argv, env), where
3340 argv is a list or tuple of strings and env is a dictionary
3341 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003342
Victor Stinner97b89882010-05-06 00:25:39 +00003343 if (!PyArg_ParseTuple(args, "O&OO:execve",
3344 PyUnicode_FSConverter,
3345 &opath, &argv, &env))
3346 return NULL;
3347 path = bytes2str(opath, 1);
3348 if (PyList_Check(argv)) {
3349 argc = PyList_Size(argv);
3350 getitem = PyList_GetItem;
3351 }
3352 else if (PyTuple_Check(argv)) {
3353 argc = PyTuple_Size(argv);
3354 getitem = PyTuple_GetItem;
3355 }
3356 else {
3357 PyErr_SetString(PyExc_TypeError,
3358 "execve() arg 2 must be a tuple or list");
3359 goto fail_0;
3360 }
3361 if (!PyMapping_Check(env)) {
3362 PyErr_SetString(PyExc_TypeError,
3363 "execve() arg 3 must be a mapping object");
3364 goto fail_0;
3365 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003366
Victor Stinner97b89882010-05-06 00:25:39 +00003367 argvlist = PyMem_NEW(char *, argc+1);
3368 if (argvlist == NULL) {
3369 PyErr_NoMemory();
3370 goto fail_0;
3371 }
3372 for (i = 0; i < argc; i++) {
3373 if (!fsconvert_strdup((*getitem)(argv, i),
3374 &argvlist[i]))
3375 {
3376 lastarg = i;
3377 goto fail_1;
3378 }
3379 }
3380 lastarg = argc;
3381 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003382
Victor Stinner97b89882010-05-06 00:25:39 +00003383 envlist = parse_envlist(env, &envc);
3384 if (envlist == NULL)
3385 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003386
Victor Stinner97b89882010-05-06 00:25:39 +00003387 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003388
Victor Stinner97b89882010-05-06 00:25:39 +00003389 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003390
Victor Stinner97b89882010-05-06 00:25:39 +00003391 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003392
Victor Stinner97b89882010-05-06 00:25:39 +00003393 while (--envc >= 0)
3394 PyMem_DEL(envlist[envc]);
3395 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003396 fail_1:
Victor Stinner97b89882010-05-06 00:25:39 +00003397 free_string_array(argvlist, lastarg);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003398 fail_0:
Victor Stinner97b89882010-05-06 00:25:39 +00003399 release_bytes(opath);
3400 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003401}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003402#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003403
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003404
Guido van Rossuma1065681999-01-25 23:20:23 +00003405#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003406PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003407"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003408Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003409\n\
Victor Stinner97b89882010-05-06 00:25:39 +00003410 mode: mode of process creation\n\
3411 path: path of executable file\n\
3412 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003413
3414static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003415posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003416{
Victor Stinner97b89882010-05-06 00:25:39 +00003417 PyObject *opath;
3418 char *path;
3419 PyObject *argv;
3420 char **argvlist;
3421 int mode, i;
3422 Py_ssize_t argc;
3423 Py_intptr_t spawnval;
3424 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003425
Victor Stinner97b89882010-05-06 00:25:39 +00003426 /* spawnv has three arguments: (mode, path, argv), where
3427 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003428
Victor Stinner97b89882010-05-06 00:25:39 +00003429 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3430 PyUnicode_FSConverter,
3431 &opath, &argv))
3432 return NULL;
3433 path = bytes2str(opath, 1);
3434 if (PyList_Check(argv)) {
3435 argc = PyList_Size(argv);
3436 getitem = PyList_GetItem;
3437 }
3438 else if (PyTuple_Check(argv)) {
3439 argc = PyTuple_Size(argv);
3440 getitem = PyTuple_GetItem;
3441 }
3442 else {
3443 PyErr_SetString(PyExc_TypeError,
3444 "spawnv() arg 2 must be a tuple or list");
3445 release_bytes(opath);
3446 return NULL;
3447 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003448
Victor Stinner97b89882010-05-06 00:25:39 +00003449 argvlist = PyMem_NEW(char *, argc+1);
3450 if (argvlist == NULL) {
3451 release_bytes(opath);
3452 return PyErr_NoMemory();
3453 }
3454 for (i = 0; i < argc; i++) {
3455 if (!fsconvert_strdup((*getitem)(argv, i),
3456 &argvlist[i])) {
3457 free_string_array(argvlist, i);
3458 PyErr_SetString(
3459 PyExc_TypeError,
3460 "spawnv() arg 2 must contain only strings");
3461 release_bytes(opath);
3462 return NULL;
3463 }
3464 }
3465 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003466
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003467#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner97b89882010-05-06 00:25:39 +00003468 Py_BEGIN_ALLOW_THREADS
3469 spawnval = spawnv(mode, path, argvlist);
3470 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003471#else
Victor Stinner97b89882010-05-06 00:25:39 +00003472 if (mode == _OLD_P_OVERLAY)
3473 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003474
Victor Stinner97b89882010-05-06 00:25:39 +00003475 Py_BEGIN_ALLOW_THREADS
3476 spawnval = _spawnv(mode, path, argvlist);
3477 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003478#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003479
Victor Stinner97b89882010-05-06 00:25:39 +00003480 free_string_array(argvlist, argc);
3481 release_bytes(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003482
Victor Stinner97b89882010-05-06 00:25:39 +00003483 if (spawnval == -1)
3484 return posix_error();
3485 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003486#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner97b89882010-05-06 00:25:39 +00003487 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003488#else
Victor Stinner97b89882010-05-06 00:25:39 +00003489 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003490#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003491}
3492
3493
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003494PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003495"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003496Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003497\n\
Victor Stinner97b89882010-05-06 00:25:39 +00003498 mode: mode of process creation\n\
3499 path: path of executable file\n\
3500 args: tuple or list of arguments\n\
3501 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003502
3503static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003504posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003505{
Victor Stinner97b89882010-05-06 00:25:39 +00003506 PyObject *opath;
3507 char *path;
3508 PyObject *argv, *env;
3509 char **argvlist;
3510 char **envlist;
3511 PyObject *res = NULL;
Antoine Pitrou835b4452010-08-15 18:32:16 +00003512 int mode;
3513 Py_ssize_t argc, i, envc;
Victor Stinner97b89882010-05-06 00:25:39 +00003514 Py_intptr_t spawnval;
3515 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3516 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003517
Victor Stinner97b89882010-05-06 00:25:39 +00003518 /* spawnve has four arguments: (mode, path, argv, env), where
3519 argv is a list or tuple of strings and env is a dictionary
3520 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003521
Victor Stinner97b89882010-05-06 00:25:39 +00003522 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3523 PyUnicode_FSConverter,
3524 &opath, &argv, &env))
3525 return NULL;
3526 path = bytes2str(opath, 1);
3527 if (PyList_Check(argv)) {
3528 argc = PyList_Size(argv);
3529 getitem = PyList_GetItem;
3530 }
3531 else if (PyTuple_Check(argv)) {
3532 argc = PyTuple_Size(argv);
3533 getitem = PyTuple_GetItem;
3534 }
3535 else {
3536 PyErr_SetString(PyExc_TypeError,
3537 "spawnve() arg 2 must be a tuple or list");
3538 goto fail_0;
3539 }
3540 if (!PyMapping_Check(env)) {
3541 PyErr_SetString(PyExc_TypeError,
3542 "spawnve() arg 3 must be a mapping object");
3543 goto fail_0;
3544 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003545
Victor Stinner97b89882010-05-06 00:25:39 +00003546 argvlist = PyMem_NEW(char *, argc+1);
3547 if (argvlist == NULL) {
3548 PyErr_NoMemory();
3549 goto fail_0;
3550 }
3551 for (i = 0; i < argc; i++) {
3552 if (!fsconvert_strdup((*getitem)(argv, i),
3553 &argvlist[i]))
3554 {
3555 lastarg = i;
3556 goto fail_1;
3557 }
3558 }
3559 lastarg = argc;
3560 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003561
Victor Stinner97b89882010-05-06 00:25:39 +00003562 envlist = parse_envlist(env, &envc);
3563 if (envlist == NULL)
3564 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003565
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003566#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner97b89882010-05-06 00:25:39 +00003567 Py_BEGIN_ALLOW_THREADS
3568 spawnval = spawnve(mode, path, argvlist, envlist);
3569 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003570#else
Victor Stinner97b89882010-05-06 00:25:39 +00003571 if (mode == _OLD_P_OVERLAY)
3572 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003573
Victor Stinner97b89882010-05-06 00:25:39 +00003574 Py_BEGIN_ALLOW_THREADS
3575 spawnval = _spawnve(mode, path, argvlist, envlist);
3576 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003577#endif
Tim Peters25059d32001-12-07 20:35:43 +00003578
Victor Stinner97b89882010-05-06 00:25:39 +00003579 if (spawnval == -1)
3580 (void) posix_error();
3581 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003582#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner97b89882010-05-06 00:25:39 +00003583 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003584#else
Victor Stinner97b89882010-05-06 00:25:39 +00003585 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003586#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003587
Victor Stinner97b89882010-05-06 00:25:39 +00003588 while (--envc >= 0)
3589 PyMem_DEL(envlist[envc]);
3590 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003591 fail_1:
Victor Stinner97b89882010-05-06 00:25:39 +00003592 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003593 fail_0:
Victor Stinner97b89882010-05-06 00:25:39 +00003594 release_bytes(opath);
3595 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003596}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003597
3598/* OS/2 supports spawnvp & spawnvpe natively */
3599#if defined(PYOS_OS2)
3600PyDoc_STRVAR(posix_spawnvp__doc__,
3601"spawnvp(mode, file, args)\n\n\
3602Execute the program 'file' in a new process, using the environment\n\
3603search path to find the file.\n\
3604\n\
Victor Stinner97b89882010-05-06 00:25:39 +00003605 mode: mode of process creation\n\
3606 file: executable file name\n\
3607 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003608
3609static PyObject *
3610posix_spawnvp(PyObject *self, PyObject *args)
3611{
Victor Stinner97b89882010-05-06 00:25:39 +00003612 PyObject *opath;
3613 char *path;
3614 PyObject *argv;
3615 char **argvlist;
3616 int mode, i, argc;
3617 Py_intptr_t spawnval;
3618 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003619
Victor Stinner97b89882010-05-06 00:25:39 +00003620 /* spawnvp has three arguments: (mode, path, argv), where
3621 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003622
Victor Stinner97b89882010-05-06 00:25:39 +00003623 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3624 PyUnicode_FSConverter,
3625 &opath, &argv))
3626 return NULL;
3627 path = bytes2str(opath);
3628 if (PyList_Check(argv)) {
3629 argc = PyList_Size(argv);
3630 getitem = PyList_GetItem;
3631 }
3632 else if (PyTuple_Check(argv)) {
3633 argc = PyTuple_Size(argv);
3634 getitem = PyTuple_GetItem;
3635 }
3636 else {
3637 PyErr_SetString(PyExc_TypeError,
3638 "spawnvp() arg 2 must be a tuple or list");
3639 release_bytes(opath);
3640 return NULL;
3641 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003642
Victor Stinner97b89882010-05-06 00:25:39 +00003643 argvlist = PyMem_NEW(char *, argc+1);
3644 if (argvlist == NULL) {
3645 release_bytes(opath);
3646 return PyErr_NoMemory();
3647 }
3648 for (i = 0; i < argc; i++) {
3649 if (!fsconvert_strdup((*getitem)(argv, i),
3650 &argvlist[i])) {
3651 free_string_array(argvlist, i);
3652 PyErr_SetString(
3653 PyExc_TypeError,
3654 "spawnvp() arg 2 must contain only strings");
3655 release_bytes(opath);
3656 return NULL;
3657 }
3658 }
3659 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003660
Victor Stinner97b89882010-05-06 00:25:39 +00003661 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003662#if defined(PYCC_GCC)
Victor Stinner97b89882010-05-06 00:25:39 +00003663 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003664#else
Victor Stinner97b89882010-05-06 00:25:39 +00003665 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003666#endif
Victor Stinner97b89882010-05-06 00:25:39 +00003667 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003668
Victor Stinner97b89882010-05-06 00:25:39 +00003669 free_string_array(argvlist, argc);
3670 release_bytes(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003671
Victor Stinner97b89882010-05-06 00:25:39 +00003672 if (spawnval == -1)
3673 return posix_error();
3674 else
3675 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003676}
3677
3678
3679PyDoc_STRVAR(posix_spawnvpe__doc__,
3680"spawnvpe(mode, file, args, env)\n\n\
3681Execute the program 'file' in a new process, using the environment\n\
3682search path to find the file.\n\
3683\n\
Victor Stinner97b89882010-05-06 00:25:39 +00003684 mode: mode of process creation\n\
3685 file: executable file name\n\
3686 args: tuple or list of arguments\n\
3687 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003688
3689static PyObject *
3690posix_spawnvpe(PyObject *self, PyObject *args)
3691{
Victor Stinner97b89882010-05-06 00:25:39 +00003692 PyObject *opath
3693 char *path;
3694 PyObject *argv, *env;
3695 char **argvlist;
3696 char **envlist;
3697 PyObject *res=NULL;
Antoine Pitrou835b4452010-08-15 18:32:16 +00003698 int mode;
3699 Py_ssize_t argc, i, envc;
Victor Stinner97b89882010-05-06 00:25:39 +00003700 Py_intptr_t spawnval;
3701 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3702 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003703
Victor Stinner97b89882010-05-06 00:25:39 +00003704 /* spawnvpe has four arguments: (mode, path, argv, env), where
3705 argv is a list or tuple of strings and env is a dictionary
3706 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003707
Victor Stinner97b89882010-05-06 00:25:39 +00003708 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3709 PyUnicode_FSConverter,
3710 &opath, &argv, &env))
3711 return NULL;
3712 path = bytes2str(opath);
3713 if (PyList_Check(argv)) {
3714 argc = PyList_Size(argv);
3715 getitem = PyList_GetItem;
3716 }
3717 else if (PyTuple_Check(argv)) {
3718 argc = PyTuple_Size(argv);
3719 getitem = PyTuple_GetItem;
3720 }
3721 else {
3722 PyErr_SetString(PyExc_TypeError,
3723 "spawnvpe() arg 2 must be a tuple or list");
3724 goto fail_0;
3725 }
3726 if (!PyMapping_Check(env)) {
3727 PyErr_SetString(PyExc_TypeError,
3728 "spawnvpe() arg 3 must be a mapping object");
3729 goto fail_0;
3730 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003731
Victor Stinner97b89882010-05-06 00:25:39 +00003732 argvlist = PyMem_NEW(char *, argc+1);
3733 if (argvlist == NULL) {
3734 PyErr_NoMemory();
3735 goto fail_0;
3736 }
3737 for (i = 0; i < argc; i++) {
3738 if (!fsconvert_strdup((*getitem)(argv, i),
3739 &argvlist[i]))
3740 {
3741 lastarg = i;
3742 goto fail_1;
3743 }
3744 }
3745 lastarg = argc;
3746 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003747
Victor Stinner97b89882010-05-06 00:25:39 +00003748 envlist = parse_envlist(env, &envc);
3749 if (envlist == NULL)
3750 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003751
Victor Stinner97b89882010-05-06 00:25:39 +00003752 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003753#if defined(PYCC_GCC)
Victor Stinner97b89882010-05-06 00:25:39 +00003754 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003755#else
Victor Stinner97b89882010-05-06 00:25:39 +00003756 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003757#endif
Victor Stinner97b89882010-05-06 00:25:39 +00003758 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003759
Victor Stinner97b89882010-05-06 00:25:39 +00003760 if (spawnval == -1)
3761 (void) posix_error();
3762 else
3763 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003764
Victor Stinner97b89882010-05-06 00:25:39 +00003765 while (--envc >= 0)
3766 PyMem_DEL(envlist[envc]);
3767 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003768 fail_1:
Victor Stinner97b89882010-05-06 00:25:39 +00003769 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003770 fail_0:
Victor Stinner97b89882010-05-06 00:25:39 +00003771 release_bytes(opath);
3772 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003773}
3774#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003775#endif /* HAVE_SPAWNV */
3776
3777
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003778#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003779PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003780"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003781Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3782\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003783Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003784
3785static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003786posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003787{
Victor Stinner97b89882010-05-06 00:25:39 +00003788 pid_t pid;
3789 int result;
3790 _PyImport_AcquireLock();
3791 pid = fork1();
3792 result = _PyImport_ReleaseLock();
3793 if (pid == -1)
3794 return posix_error();
3795 if (pid == 0)
3796 PyOS_AfterFork();
3797 if (result < 0) {
3798 /* Don't clobber the OSError if the fork failed. */
3799 PyErr_SetString(PyExc_RuntimeError,
3800 "not holding the import lock");
3801 return NULL;
3802 }
3803 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003804}
3805#endif
3806
3807
Guido van Rossumad0ee831995-03-01 10:34:45 +00003808#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003809PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003810"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003811Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003812Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003813
Barry Warsaw53699e91996-12-10 23:23:01 +00003814static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003815posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003816{
Victor Stinner97b89882010-05-06 00:25:39 +00003817 pid_t pid;
3818 int result;
3819 _PyImport_AcquireLock();
3820 pid = fork();
3821 result = _PyImport_ReleaseLock();
3822 if (pid == -1)
3823 return posix_error();
3824 if (pid == 0)
3825 PyOS_AfterFork();
3826 if (result < 0) {
3827 /* Don't clobber the OSError if the fork failed. */
3828 PyErr_SetString(PyExc_RuntimeError,
3829 "not holding the import lock");
3830 return NULL;
3831 }
3832 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003833}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003834#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003835
Neal Norwitzb59798b2003-03-21 01:43:31 +00003836/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003837/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3838#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003839#define DEV_PTY_FILE "/dev/ptc"
3840#define HAVE_DEV_PTMX
3841#else
3842#define DEV_PTY_FILE "/dev/ptmx"
3843#endif
3844
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003845#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003846#ifdef HAVE_PTY_H
3847#include <pty.h>
3848#else
3849#ifdef HAVE_LIBUTIL_H
3850#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003851#endif /* HAVE_LIBUTIL_H */
3852#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003853#ifdef HAVE_STROPTS_H
3854#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003855#endif
3856#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003857
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003858#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003859PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003860"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003861Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003862
3863static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003864posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003865{
Victor Stinner97b89882010-05-06 00:25:39 +00003866 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003867#ifndef HAVE_OPENPTY
Victor Stinner97b89882010-05-06 00:25:39 +00003868 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003869#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003870#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner97b89882010-05-06 00:25:39 +00003871 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003872#ifdef sun
Victor Stinner97b89882010-05-06 00:25:39 +00003873 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003874#endif
3875#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003876
Thomas Wouters70c21a12000-07-14 14:28:33 +00003877#ifdef HAVE_OPENPTY
Victor Stinner97b89882010-05-06 00:25:39 +00003878 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3879 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003880#elif defined(HAVE__GETPTY)
Victor Stinner97b89882010-05-06 00:25:39 +00003881 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3882 if (slave_name == NULL)
3883 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00003884
Victor Stinner97b89882010-05-06 00:25:39 +00003885 slave_fd = open(slave_name, O_RDWR);
3886 if (slave_fd < 0)
3887 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003888#else
Victor Stinner97b89882010-05-06 00:25:39 +00003889 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3890 if (master_fd < 0)
3891 return posix_error();
3892 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3893 /* change permission of slave */
3894 if (grantpt(master_fd) < 0) {
3895 PyOS_setsig(SIGCHLD, sig_saved);
3896 return posix_error();
3897 }
3898 /* unlock slave */
3899 if (unlockpt(master_fd) < 0) {
3900 PyOS_setsig(SIGCHLD, sig_saved);
3901 return posix_error();
3902 }
3903 PyOS_setsig(SIGCHLD, sig_saved);
3904 slave_name = ptsname(master_fd); /* get name of slave */
3905 if (slave_name == NULL)
3906 return posix_error();
3907 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3908 if (slave_fd < 0)
3909 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003910#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner97b89882010-05-06 00:25:39 +00003911 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3912 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003913#ifndef __hpux
Victor Stinner97b89882010-05-06 00:25:39 +00003914 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003915#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003916#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003917#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003918
Victor Stinner97b89882010-05-06 00:25:39 +00003919 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003920
Fred Drake8cef4cf2000-06-28 16:40:38 +00003921}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003922#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003923
3924#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003925PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003926"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003927Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3928Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003929To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003930
3931static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003932posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003933{
Victor Stinner97b89882010-05-06 00:25:39 +00003934 int master_fd = -1, result;
3935 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003936
Victor Stinner97b89882010-05-06 00:25:39 +00003937 _PyImport_AcquireLock();
3938 pid = forkpty(&master_fd, NULL, NULL, NULL);
3939 result = _PyImport_ReleaseLock();
3940 if (pid == -1)
3941 return posix_error();
3942 if (pid == 0)
3943 PyOS_AfterFork();
3944 if (result < 0) {
3945 /* Don't clobber the OSError if the fork failed. */
3946 PyErr_SetString(PyExc_RuntimeError,
3947 "not holding the import lock");
3948 return NULL;
3949 }
3950 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003951}
3952#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003953
Guido van Rossumad0ee831995-03-01 10:34:45 +00003954#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003955PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003956"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003957Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003958
Barry Warsaw53699e91996-12-10 23:23:01 +00003959static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003960posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003961{
Victor Stinner97b89882010-05-06 00:25:39 +00003962 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003963}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003964#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003965
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003966
Guido van Rossumad0ee831995-03-01 10:34:45 +00003967#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003968PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003969"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003970Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003971
Barry Warsaw53699e91996-12-10 23:23:01 +00003972static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003973posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003974{
Victor Stinner97b89882010-05-06 00:25:39 +00003975 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003976}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003977#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003978
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003979
Guido van Rossumad0ee831995-03-01 10:34:45 +00003980#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003981PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003982"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003983Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003984
Barry Warsaw53699e91996-12-10 23:23:01 +00003985static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003986posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003987{
Victor Stinner97b89882010-05-06 00:25:39 +00003988 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003989}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003990#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003991
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003992
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003993PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003994"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003995Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003996
Barry Warsaw53699e91996-12-10 23:23:01 +00003997static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003998posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003999{
Victor Stinner97b89882010-05-06 00:25:39 +00004000 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004001}
4002
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004003
Fred Drakec9680921999-12-13 16:37:25 +00004004#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004005PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004006"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004007Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004008
4009static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004010posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004011{
4012 PyObject *result = NULL;
4013
Fred Drakec9680921999-12-13 16:37:25 +00004014#ifdef NGROUPS_MAX
4015#define MAX_GROUPS NGROUPS_MAX
4016#else
Victor Stinner97b89882010-05-06 00:25:39 +00004017 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004018#define MAX_GROUPS 64
4019#endif
Victor Stinner97b89882010-05-06 00:25:39 +00004020 gid_t grouplist[MAX_GROUPS];
Ronald Oussoren47076f72010-07-23 15:46:03 +00004021
4022 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
4023 * This is a helper variable to store the intermediate result when
4024 * that happens.
4025 *
4026 * To keep the code readable the OSX behaviour is unconditional,
4027 * according to the POSIX spec this should be safe on all unix-y
4028 * systems.
4029 */
4030 gid_t* alt_grouplist = grouplist;
Victor Stinner97b89882010-05-06 00:25:39 +00004031 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004032
Victor Stinner97b89882010-05-06 00:25:39 +00004033 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussoren47076f72010-07-23 15:46:03 +00004034 if (n < 0) {
4035 if (errno == EINVAL) {
4036 n = getgroups(0, NULL);
4037 if (n == -1) {
4038 return posix_error();
4039 }
4040 if (n == 0) {
4041 /* Avoid malloc(0) */
4042 alt_grouplist = grouplist;
4043 } else {
4044 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4045 if (alt_grouplist == NULL) {
4046 errno = EINVAL;
4047 return posix_error();
4048 }
4049 n = getgroups(n, alt_grouplist);
4050 if (n == -1) {
4051 PyMem_Free(alt_grouplist);
4052 return posix_error();
4053 }
4054 }
4055 } else {
4056 return posix_error();
4057 }
4058 }
4059 result = PyList_New(n);
4060 if (result != NULL) {
Victor Stinner97b89882010-05-06 00:25:39 +00004061 int i;
4062 for (i = 0; i < n; ++i) {
Ronald Oussoren47076f72010-07-23 15:46:03 +00004063 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner97b89882010-05-06 00:25:39 +00004064 if (o == NULL) {
Stefan Krah67733312010-11-26 17:04:40 +00004065 Py_DECREF(result);
4066 result = NULL;
4067 break;
Fred Drakec9680921999-12-13 16:37:25 +00004068 }
Victor Stinner97b89882010-05-06 00:25:39 +00004069 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004070 }
Ronald Oussoren47076f72010-07-23 15:46:03 +00004071 }
4072
4073 if (alt_grouplist != grouplist) {
4074 PyMem_Free(alt_grouplist);
Victor Stinner97b89882010-05-06 00:25:39 +00004075 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004076
Fred Drakec9680921999-12-13 16:37:25 +00004077 return result;
4078}
4079#endif
4080
Martin v. Löwis606edc12002-06-13 21:09:11 +00004081#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004082PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004083"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004084Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004085
4086static PyObject *
4087posix_getpgid(PyObject *self, PyObject *args)
4088{
Victor Stinner97b89882010-05-06 00:25:39 +00004089 pid_t pid, pgid;
4090 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
4091 return NULL;
4092 pgid = getpgid(pid);
4093 if (pgid < 0)
4094 return posix_error();
4095 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004096}
4097#endif /* HAVE_GETPGID */
4098
4099
Guido van Rossumb6775db1994-08-01 11:34:53 +00004100#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004101PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004102"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004103Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004104
Barry Warsaw53699e91996-12-10 23:23:01 +00004105static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004106posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004107{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004108#ifdef GETPGRP_HAVE_ARG
Victor Stinner97b89882010-05-06 00:25:39 +00004109 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004110#else /* GETPGRP_HAVE_ARG */
Victor Stinner97b89882010-05-06 00:25:39 +00004111 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004112#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004113}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004114#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004115
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004116
Guido van Rossumb6775db1994-08-01 11:34:53 +00004117#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004118PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004119"setpgrp()\n\n\
Senthil Kumaran28fdadb2010-06-17 16:51:08 +00004120Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004121
Barry Warsaw53699e91996-12-10 23:23:01 +00004122static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004123posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004124{
Guido van Rossum64933891994-10-20 21:56:42 +00004125#ifdef SETPGRP_HAVE_ARG
Victor Stinner97b89882010-05-06 00:25:39 +00004126 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004127#else /* SETPGRP_HAVE_ARG */
Victor Stinner97b89882010-05-06 00:25:39 +00004128 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004129#endif /* SETPGRP_HAVE_ARG */
Victor Stinner97b89882010-05-06 00:25:39 +00004130 return posix_error();
4131 Py_INCREF(Py_None);
4132 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004133}
4134
Guido van Rossumb6775db1994-08-01 11:34:53 +00004135#endif /* HAVE_SETPGRP */
4136
Guido van Rossumad0ee831995-03-01 10:34:45 +00004137#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004138PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004139"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004140Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004141
Barry Warsaw53699e91996-12-10 23:23:01 +00004142static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004143posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004144{
Victor Stinner97b89882010-05-06 00:25:39 +00004145 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004146}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004147#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004148
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004149
Fred Drake12c6e2d1999-12-14 21:25:03 +00004150#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004151PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004152"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004153Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004154
4155static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004156posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004157{
Victor Stinner97b89882010-05-06 00:25:39 +00004158 PyObject *result = NULL;
4159 char *name;
4160 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004161
Victor Stinner97b89882010-05-06 00:25:39 +00004162 errno = 0;
4163 name = getlogin();
4164 if (name == NULL) {
4165 if (errno)
Victor Stinner85675992010-08-15 09:35:13 +00004166 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004167 else
Victor Stinner85675992010-08-15 09:35:13 +00004168 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner97b89882010-05-06 00:25:39 +00004169 }
4170 else
Victor Stinner85675992010-08-15 09:35:13 +00004171 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner97b89882010-05-06 00:25:39 +00004172 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004173
Fred Drake12c6e2d1999-12-14 21:25:03 +00004174 return result;
4175}
4176#endif
4177
Guido van Rossumad0ee831995-03-01 10:34:45 +00004178#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004179PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004180"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004181Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004182
Barry Warsaw53699e91996-12-10 23:23:01 +00004183static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004184posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004185{
Victor Stinner97b89882010-05-06 00:25:39 +00004186 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004187}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004188#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004189
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004190
Guido van Rossumad0ee831995-03-01 10:34:45 +00004191#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004192PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004193"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004194Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004195
Barry Warsaw53699e91996-12-10 23:23:01 +00004196static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004197posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004198{
Victor Stinner97b89882010-05-06 00:25:39 +00004199 pid_t pid;
4200 int sig;
4201 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
4202 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004203#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004204 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4205 APIRET rc;
4206 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004207 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004208
4209 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4210 APIRET rc;
4211 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004212 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004213
4214 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004215 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004216#else
Victor Stinner97b89882010-05-06 00:25:39 +00004217 if (kill(pid, sig) == -1)
4218 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004219#endif
Victor Stinner97b89882010-05-06 00:25:39 +00004220 Py_INCREF(Py_None);
4221 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004222}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004223#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004224
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004225#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004226PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004227"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004228Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004229
4230static PyObject *
4231posix_killpg(PyObject *self, PyObject *args)
4232{
Victor Stinner97b89882010-05-06 00:25:39 +00004233 int sig;
4234 pid_t pgid;
4235 /* XXX some man pages make the `pgid` parameter an int, others
4236 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4237 take the same type. Moreover, pid_t is always at least as wide as
4238 int (else compilation of this module fails), which is safe. */
4239 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
4240 return NULL;
4241 if (killpg(pgid, sig) == -1)
4242 return posix_error();
4243 Py_INCREF(Py_None);
4244 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004245}
4246#endif
4247
Guido van Rossumc0125471996-06-28 18:55:32 +00004248#ifdef HAVE_PLOCK
4249
4250#ifdef HAVE_SYS_LOCK_H
4251#include <sys/lock.h>
4252#endif
4253
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004254PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004255"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004256Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004257
Barry Warsaw53699e91996-12-10 23:23:01 +00004258static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004259posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004260{
Victor Stinner97b89882010-05-06 00:25:39 +00004261 int op;
4262 if (!PyArg_ParseTuple(args, "i:plock", &op))
4263 return NULL;
4264 if (plock(op) == -1)
4265 return posix_error();
4266 Py_INCREF(Py_None);
4267 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004268}
4269#endif
4270
Guido van Rossumb6775db1994-08-01 11:34:53 +00004271#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004272PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004273"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004274Set the current process's user id.");
4275
Barry Warsaw53699e91996-12-10 23:23:01 +00004276static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004277posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004278{
Victor Stinner97b89882010-05-06 00:25:39 +00004279 long uid_arg;
4280 uid_t uid;
4281 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
4282 return NULL;
4283 uid = uid_arg;
4284 if (uid != uid_arg) {
4285 PyErr_SetString(PyExc_OverflowError, "user id too big");
4286 return NULL;
4287 }
4288 if (setuid(uid) < 0)
4289 return posix_error();
4290 Py_INCREF(Py_None);
4291 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004292}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004293#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004294
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004295
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004296#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004297PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004298"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004299Set the current process's effective user id.");
4300
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004301static PyObject *
4302posix_seteuid (PyObject *self, PyObject *args)
4303{
Victor Stinner97b89882010-05-06 00:25:39 +00004304 long euid_arg;
4305 uid_t euid;
4306 if (!PyArg_ParseTuple(args, "l", &euid_arg))
4307 return NULL;
4308 euid = euid_arg;
4309 if (euid != euid_arg) {
4310 PyErr_SetString(PyExc_OverflowError, "user id too big");
4311 return NULL;
4312 }
4313 if (seteuid(euid) < 0) {
4314 return posix_error();
4315 } else {
4316 Py_INCREF(Py_None);
4317 return Py_None;
4318 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004319}
4320#endif /* HAVE_SETEUID */
4321
4322#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004323PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004324"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004325Set the current process's effective group id.");
4326
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004327static PyObject *
4328posix_setegid (PyObject *self, PyObject *args)
4329{
Victor Stinner97b89882010-05-06 00:25:39 +00004330 long egid_arg;
4331 gid_t egid;
4332 if (!PyArg_ParseTuple(args, "l", &egid_arg))
4333 return NULL;
4334 egid = egid_arg;
4335 if (egid != egid_arg) {
4336 PyErr_SetString(PyExc_OverflowError, "group id too big");
4337 return NULL;
4338 }
4339 if (setegid(egid) < 0) {
4340 return posix_error();
4341 } else {
4342 Py_INCREF(Py_None);
4343 return Py_None;
4344 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004345}
4346#endif /* HAVE_SETEGID */
4347
4348#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004349PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004350"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004351Set the current process's real and effective user ids.");
4352
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004353static PyObject *
4354posix_setreuid (PyObject *self, PyObject *args)
4355{
Victor Stinner97b89882010-05-06 00:25:39 +00004356 long ruid_arg, euid_arg;
4357 uid_t ruid, euid;
4358 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
4359 return NULL;
4360 if (ruid_arg == -1)
4361 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
4362 else
4363 ruid = ruid_arg; /* otherwise, assign from our long */
4364 if (euid_arg == -1)
4365 euid = (uid_t)-1;
4366 else
4367 euid = euid_arg;
4368 if ((euid_arg != -1 && euid != euid_arg) ||
4369 (ruid_arg != -1 && ruid != ruid_arg)) {
4370 PyErr_SetString(PyExc_OverflowError, "user id too big");
4371 return NULL;
4372 }
4373 if (setreuid(ruid, euid) < 0) {
4374 return posix_error();
4375 } else {
4376 Py_INCREF(Py_None);
4377 return Py_None;
4378 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004379}
4380#endif /* HAVE_SETREUID */
4381
4382#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004383PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004384"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004385Set the current process's real and effective group ids.");
4386
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004387static PyObject *
4388posix_setregid (PyObject *self, PyObject *args)
4389{
Victor Stinner97b89882010-05-06 00:25:39 +00004390 long rgid_arg, egid_arg;
4391 gid_t rgid, egid;
4392 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
4393 return NULL;
4394 if (rgid_arg == -1)
4395 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
4396 else
4397 rgid = rgid_arg; /* otherwise, assign from our long */
4398 if (egid_arg == -1)
4399 egid = (gid_t)-1;
4400 else
4401 egid = egid_arg;
4402 if ((egid_arg != -1 && egid != egid_arg) ||
4403 (rgid_arg != -1 && rgid != rgid_arg)) {
4404 PyErr_SetString(PyExc_OverflowError, "group id too big");
4405 return NULL;
4406 }
4407 if (setregid(rgid, egid) < 0) {
4408 return posix_error();
4409 } else {
4410 Py_INCREF(Py_None);
4411 return Py_None;
4412 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004413}
4414#endif /* HAVE_SETREGID */
4415
Guido van Rossumb6775db1994-08-01 11:34:53 +00004416#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004417PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004418"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004419Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004420
Barry Warsaw53699e91996-12-10 23:23:01 +00004421static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004422posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004423{
Victor Stinner97b89882010-05-06 00:25:39 +00004424 long gid_arg;
4425 gid_t gid;
4426 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
4427 return NULL;
4428 gid = gid_arg;
4429 if (gid != gid_arg) {
4430 PyErr_SetString(PyExc_OverflowError, "group id too big");
4431 return NULL;
4432 }
4433 if (setgid(gid) < 0)
4434 return posix_error();
4435 Py_INCREF(Py_None);
4436 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004437}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004438#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004439
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004440#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004441PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004442"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004443Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004444
4445static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004446posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004447{
Victor Stinner97b89882010-05-06 00:25:39 +00004448 int i, len;
4449 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004450
Victor Stinner97b89882010-05-06 00:25:39 +00004451 if (!PySequence_Check(groups)) {
4452 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4453 return NULL;
4454 }
4455 len = PySequence_Size(groups);
4456 if (len > MAX_GROUPS) {
4457 PyErr_SetString(PyExc_ValueError, "too many groups");
4458 return NULL;
4459 }
4460 for(i = 0; i < len; i++) {
4461 PyObject *elem;
4462 elem = PySequence_GetItem(groups, i);
4463 if (!elem)
4464 return NULL;
4465 if (!PyLong_Check(elem)) {
4466 PyErr_SetString(PyExc_TypeError,
4467 "groups must be integers");
4468 Py_DECREF(elem);
4469 return NULL;
4470 } else {
4471 unsigned long x = PyLong_AsUnsignedLong(elem);
4472 if (PyErr_Occurred()) {
4473 PyErr_SetString(PyExc_TypeError,
4474 "group id too big");
4475 Py_DECREF(elem);
4476 return NULL;
4477 }
4478 grouplist[i] = x;
4479 /* read back the value to see if it fitted in gid_t */
4480 if (grouplist[i] != x) {
4481 PyErr_SetString(PyExc_TypeError,
4482 "group id too big");
4483 Py_DECREF(elem);
4484 return NULL;
4485 }
4486 }
4487 Py_DECREF(elem);
4488 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004489
Victor Stinner97b89882010-05-06 00:25:39 +00004490 if (setgroups(len, grouplist) < 0)
4491 return posix_error();
4492 Py_INCREF(Py_None);
4493 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004494}
4495#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004496
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004497#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4498static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004499wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004500{
Victor Stinner97b89882010-05-06 00:25:39 +00004501 PyObject *result;
4502 static PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004503
Victor Stinner97b89882010-05-06 00:25:39 +00004504 if (pid == -1)
4505 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004506
Victor Stinner97b89882010-05-06 00:25:39 +00004507 if (struct_rusage == NULL) {
4508 PyObject *m = PyImport_ImportModuleNoBlock("resource");
4509 if (m == NULL)
4510 return NULL;
4511 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4512 Py_DECREF(m);
4513 if (struct_rusage == NULL)
4514 return NULL;
4515 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004516
Victor Stinner97b89882010-05-06 00:25:39 +00004517 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4518 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4519 if (!result)
4520 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004521
4522#ifndef doubletime
4523#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4524#endif
4525
Victor Stinner97b89882010-05-06 00:25:39 +00004526 PyStructSequence_SET_ITEM(result, 0,
4527 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4528 PyStructSequence_SET_ITEM(result, 1,
4529 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004530#define SET_INT(result, index, value)\
Victor Stinner97b89882010-05-06 00:25:39 +00004531 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
4532 SET_INT(result, 2, ru->ru_maxrss);
4533 SET_INT(result, 3, ru->ru_ixrss);
4534 SET_INT(result, 4, ru->ru_idrss);
4535 SET_INT(result, 5, ru->ru_isrss);
4536 SET_INT(result, 6, ru->ru_minflt);
4537 SET_INT(result, 7, ru->ru_majflt);
4538 SET_INT(result, 8, ru->ru_nswap);
4539 SET_INT(result, 9, ru->ru_inblock);
4540 SET_INT(result, 10, ru->ru_oublock);
4541 SET_INT(result, 11, ru->ru_msgsnd);
4542 SET_INT(result, 12, ru->ru_msgrcv);
4543 SET_INT(result, 13, ru->ru_nsignals);
4544 SET_INT(result, 14, ru->ru_nvcsw);
4545 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004546#undef SET_INT
4547
Victor Stinner97b89882010-05-06 00:25:39 +00004548 if (PyErr_Occurred()) {
4549 Py_DECREF(result);
4550 return NULL;
4551 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004552
Victor Stinner97b89882010-05-06 00:25:39 +00004553 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004554}
4555#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4556
4557#ifdef HAVE_WAIT3
4558PyDoc_STRVAR(posix_wait3__doc__,
4559"wait3(options) -> (pid, status, rusage)\n\n\
4560Wait for completion of a child process.");
4561
4562static PyObject *
4563posix_wait3(PyObject *self, PyObject *args)
4564{
Victor Stinner97b89882010-05-06 00:25:39 +00004565 pid_t pid;
4566 int options;
4567 struct rusage ru;
4568 WAIT_TYPE status;
4569 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004570
Victor Stinner97b89882010-05-06 00:25:39 +00004571 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4572 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004573
Victor Stinner97b89882010-05-06 00:25:39 +00004574 Py_BEGIN_ALLOW_THREADS
4575 pid = wait3(&status, options, &ru);
4576 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004577
Victor Stinner97b89882010-05-06 00:25:39 +00004578 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004579}
4580#endif /* HAVE_WAIT3 */
4581
4582#ifdef HAVE_WAIT4
4583PyDoc_STRVAR(posix_wait4__doc__,
4584"wait4(pid, options) -> (pid, status, rusage)\n\n\
4585Wait for completion of a given child process.");
4586
4587static PyObject *
4588posix_wait4(PyObject *self, PyObject *args)
4589{
Victor Stinner97b89882010-05-06 00:25:39 +00004590 pid_t pid;
4591 int options;
4592 struct rusage ru;
4593 WAIT_TYPE status;
4594 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004595
Victor Stinner97b89882010-05-06 00:25:39 +00004596 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
4597 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004598
Victor Stinner97b89882010-05-06 00:25:39 +00004599 Py_BEGIN_ALLOW_THREADS
4600 pid = wait4(pid, &status, options, &ru);
4601 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004602
Victor Stinner97b89882010-05-06 00:25:39 +00004603 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004604}
4605#endif /* HAVE_WAIT4 */
4606
Guido van Rossumb6775db1994-08-01 11:34:53 +00004607#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004608PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004609"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004610Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004611
Barry Warsaw53699e91996-12-10 23:23:01 +00004612static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004613posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004614{
Victor Stinner97b89882010-05-06 00:25:39 +00004615 pid_t pid;
4616 int options;
4617 WAIT_TYPE status;
4618 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004619
Victor Stinner97b89882010-05-06 00:25:39 +00004620 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
4621 return NULL;
4622 Py_BEGIN_ALLOW_THREADS
4623 pid = waitpid(pid, &status, options);
4624 Py_END_ALLOW_THREADS
4625 if (pid == -1)
4626 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004627
Victor Stinner97b89882010-05-06 00:25:39 +00004628 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004629}
4630
Tim Petersab034fa2002-02-01 11:27:43 +00004631#elif defined(HAVE_CWAIT)
4632
4633/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004634PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004635"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004636"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004637
4638static PyObject *
4639posix_waitpid(PyObject *self, PyObject *args)
4640{
Victor Stinner97b89882010-05-06 00:25:39 +00004641 Py_intptr_t pid;
4642 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004643
Victor Stinner97b89882010-05-06 00:25:39 +00004644 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
4645 return NULL;
4646 Py_BEGIN_ALLOW_THREADS
4647 pid = _cwait(&status, pid, options);
4648 Py_END_ALLOW_THREADS
4649 if (pid == -1)
4650 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004651
Victor Stinner97b89882010-05-06 00:25:39 +00004652 /* shift the status left a byte so this is more like the POSIX waitpid */
4653 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004654}
4655#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004656
Guido van Rossumad0ee831995-03-01 10:34:45 +00004657#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004658PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004659"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004660Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004661
Barry Warsaw53699e91996-12-10 23:23:01 +00004662static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004663posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004664{
Victor Stinner97b89882010-05-06 00:25:39 +00004665 pid_t pid;
4666 WAIT_TYPE status;
4667 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004668
Victor Stinner97b89882010-05-06 00:25:39 +00004669 Py_BEGIN_ALLOW_THREADS
4670 pid = wait(&status);
4671 Py_END_ALLOW_THREADS
4672 if (pid == -1)
4673 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004674
Victor Stinner97b89882010-05-06 00:25:39 +00004675 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00004676}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004677#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004678
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004679
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004680PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004681"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004682Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004683
Barry Warsaw53699e91996-12-10 23:23:01 +00004684static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004685posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004686{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004687#ifdef HAVE_LSTAT
Victor Stinner97b89882010-05-06 00:25:39 +00004688 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004689#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004690#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00004691 return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004692#else
Victor Stinner97b89882010-05-06 00:25:39 +00004693 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004694#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004695#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004696}
4697
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004698
Guido van Rossumb6775db1994-08-01 11:34:53 +00004699#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004700PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004701"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004702Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004703
Barry Warsaw53699e91996-12-10 23:23:01 +00004704static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004705posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004706{
Victor Stinner97b89882010-05-06 00:25:39 +00004707 PyObject* v;
4708 char buf[MAXPATHLEN];
4709 PyObject *opath;
4710 char *path;
4711 int n;
4712 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004713
Victor Stinner97b89882010-05-06 00:25:39 +00004714 if (!PyArg_ParseTuple(args, "O&:readlink",
4715 PyUnicode_FSConverter, &opath))
4716 return NULL;
4717 path = bytes2str(opath, 1);
4718 v = PySequence_GetItem(args, 0);
4719 if (v == NULL) {
4720 release_bytes(opath);
4721 return NULL;
4722 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004723
Victor Stinner97b89882010-05-06 00:25:39 +00004724 if (PyUnicode_Check(v)) {
4725 arg_is_unicode = 1;
4726 }
4727 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004728
Victor Stinner97b89882010-05-06 00:25:39 +00004729 Py_BEGIN_ALLOW_THREADS
4730 n = readlink(path, buf, (int) sizeof buf);
4731 Py_END_ALLOW_THREADS
4732 if (n < 0)
4733 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004734
Victor Stinner97b89882010-05-06 00:25:39 +00004735 release_bytes(opath);
Victor Stinner203406c2010-05-14 18:07:39 +00004736 v = PyBytes_FromStringAndSize(buf, n);
4737 if (arg_is_unicode) {
4738 PyObject *w;
4739
4740 w = PyUnicode_FromEncodedObject(v,
4741 Py_FileSystemDefaultEncoding,
4742 "surrogateescape");
4743 if (w != NULL) {
4744 Py_DECREF(v);
4745 v = w;
4746 }
4747 else {
4748 v = NULL;
4749 }
4750 }
4751 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004752}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004753#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004754
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004755
Guido van Rossumb6775db1994-08-01 11:34:53 +00004756#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004757PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004758"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00004759Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004760
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004761static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004762posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004763{
Victor Stinner97b89882010-05-06 00:25:39 +00004764 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004765}
4766#endif /* HAVE_SYMLINK */
4767
4768
4769#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00004770#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4771static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004772system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004773{
4774 ULONG value = 0;
4775
4776 Py_BEGIN_ALLOW_THREADS
4777 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4778 Py_END_ALLOW_THREADS
4779
4780 return value;
4781}
4782
4783static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004784posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004785{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004786 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner97b89882010-05-06 00:25:39 +00004787 return Py_BuildValue("ddddd",
4788 (double)0 /* t.tms_utime / HZ */,
4789 (double)0 /* t.tms_stime / HZ */,
4790 (double)0 /* t.tms_cutime / HZ */,
4791 (double)0 /* t.tms_cstime / HZ */,
4792 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00004793}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004794#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00004795#define NEED_TICKS_PER_SECOND
4796static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00004797static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004798posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004799{
Victor Stinner97b89882010-05-06 00:25:39 +00004800 struct tms t;
4801 clock_t c;
4802 errno = 0;
4803 c = times(&t);
4804 if (c == (clock_t) -1)
4805 return posix_error();
4806 return Py_BuildValue("ddddd",
4807 (double)t.tms_utime / ticks_per_second,
4808 (double)t.tms_stime / ticks_per_second,
4809 (double)t.tms_cutime / ticks_per_second,
4810 (double)t.tms_cstime / ticks_per_second,
4811 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004812}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004813#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004814#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004815
4816
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004817#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00004818#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004819static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004820posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004821{
Victor Stinner97b89882010-05-06 00:25:39 +00004822 FILETIME create, exit, kernel, user;
4823 HANDLE hProc;
4824 hProc = GetCurrentProcess();
4825 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4826 /* The fields of a FILETIME structure are the hi and lo part
4827 of a 64-bit value expressed in 100 nanosecond units.
4828 1e7 is one second in such units; 1e-7 the inverse.
4829 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4830 */
4831 return Py_BuildValue(
4832 "ddddd",
4833 (double)(user.dwHighDateTime*429.4967296 +
4834 user.dwLowDateTime*1e-7),
4835 (double)(kernel.dwHighDateTime*429.4967296 +
4836 kernel.dwLowDateTime*1e-7),
4837 (double)0,
4838 (double)0,
4839 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004840}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004841#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004842
4843#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004844PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004845"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004846Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004847#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004848
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004849
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004850#ifdef HAVE_GETSID
4851PyDoc_STRVAR(posix_getsid__doc__,
4852"getsid(pid) -> sid\n\n\
4853Call the system call getsid().");
4854
4855static PyObject *
4856posix_getsid(PyObject *self, PyObject *args)
4857{
Victor Stinner97b89882010-05-06 00:25:39 +00004858 pid_t pid;
4859 int sid;
4860 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
4861 return NULL;
4862 sid = getsid(pid);
4863 if (sid < 0)
4864 return posix_error();
4865 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004866}
4867#endif /* HAVE_GETSID */
4868
4869
Guido van Rossumb6775db1994-08-01 11:34:53 +00004870#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004871PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004872"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004873Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004874
Barry Warsaw53699e91996-12-10 23:23:01 +00004875static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004876posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004877{
Victor Stinner97b89882010-05-06 00:25:39 +00004878 if (setsid() < 0)
4879 return posix_error();
4880 Py_INCREF(Py_None);
4881 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004882}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004883#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004884
Guido van Rossumb6775db1994-08-01 11:34:53 +00004885#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004886PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004887"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004888Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004889
Barry Warsaw53699e91996-12-10 23:23:01 +00004890static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004891posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004892{
Victor Stinner97b89882010-05-06 00:25:39 +00004893 pid_t pid;
4894 int pgrp;
4895 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
4896 return NULL;
4897 if (setpgid(pid, pgrp) < 0)
4898 return posix_error();
4899 Py_INCREF(Py_None);
4900 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004901}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004902#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004903
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004904
Guido van Rossumb6775db1994-08-01 11:34:53 +00004905#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004906PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004907"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004908Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004909
Barry Warsaw53699e91996-12-10 23:23:01 +00004910static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004911posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004912{
Victor Stinner97b89882010-05-06 00:25:39 +00004913 int fd;
4914 pid_t pgid;
4915 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
4916 return NULL;
4917 pgid = tcgetpgrp(fd);
4918 if (pgid < 0)
4919 return posix_error();
4920 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004921}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004922#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004923
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004924
Guido van Rossumb6775db1994-08-01 11:34:53 +00004925#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004926PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004927"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004928Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004929
Barry Warsaw53699e91996-12-10 23:23:01 +00004930static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004931posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004932{
Victor Stinner97b89882010-05-06 00:25:39 +00004933 int fd;
4934 pid_t pgid;
4935 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
4936 return NULL;
4937 if (tcsetpgrp(fd, pgid) < 0)
4938 return posix_error();
4939 Py_INCREF(Py_None);
4940 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004941}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004942#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004943
Guido van Rossum687dd131993-05-17 08:34:16 +00004944/* Functions acting on file descriptors */
4945
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004946PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004947"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004948Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004949
Barry Warsaw53699e91996-12-10 23:23:01 +00004950static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004951posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004952{
Victor Stinner97b89882010-05-06 00:25:39 +00004953 PyObject *ofile;
4954 char *file;
4955 int flag;
4956 int mode = 0777;
4957 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004958
4959#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00004960 if (unicode_file_names()) {
4961 PyUnicodeObject *po;
4962 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4963 Py_BEGIN_ALLOW_THREADS
4964 /* PyUnicode_AS_UNICODE OK without thread
4965 lock as it is a simple dereference. */
4966 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4967 Py_END_ALLOW_THREADS
4968 if (fd < 0)
4969 return posix_error();
4970 return PyLong_FromLong((long)fd);
4971 }
4972 /* Drop the argument parsing error as narrow strings
4973 are also valid. */
4974 PyErr_Clear();
4975 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004976#endif
4977
Victor Stinner97b89882010-05-06 00:25:39 +00004978 if (!PyArg_ParseTuple(args, "O&i|i",
4979 PyUnicode_FSConverter, &ofile,
4980 &flag, &mode))
4981 return NULL;
4982 file = bytes2str(ofile, 1);
4983 Py_BEGIN_ALLOW_THREADS
4984 fd = open(file, flag, mode);
4985 Py_END_ALLOW_THREADS
4986 if (fd < 0)
4987 return posix_error_with_allocated_filename(ofile);
4988 release_bytes(ofile);
4989 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004990}
4991
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004992
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004993PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004994"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004995Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004996
Barry Warsaw53699e91996-12-10 23:23:01 +00004997static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004998posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004999{
Victor Stinner97b89882010-05-06 00:25:39 +00005000 int fd, res;
5001 if (!PyArg_ParseTuple(args, "i:close", &fd))
5002 return NULL;
5003 if (!_PyVerify_fd(fd))
5004 return posix_error();
5005 Py_BEGIN_ALLOW_THREADS
5006 res = close(fd);
5007 Py_END_ALLOW_THREADS
5008 if (res < 0)
5009 return posix_error();
5010 Py_INCREF(Py_None);
5011 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005012}
5013
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005014
Victor Stinner97b89882010-05-06 00:25:39 +00005015PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00005016"closerange(fd_low, fd_high)\n\n\
5017Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
5018
5019static PyObject *
5020posix_closerange(PyObject *self, PyObject *args)
5021{
Victor Stinner97b89882010-05-06 00:25:39 +00005022 int fd_from, fd_to, i;
5023 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
5024 return NULL;
5025 Py_BEGIN_ALLOW_THREADS
5026 for (i = fd_from; i < fd_to; i++)
5027 if (_PyVerify_fd(i))
5028 close(i);
5029 Py_END_ALLOW_THREADS
5030 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00005031}
5032
5033
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005034PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005035"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005036Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005037
Barry Warsaw53699e91996-12-10 23:23:01 +00005038static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005039posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005040{
Victor Stinner97b89882010-05-06 00:25:39 +00005041 int fd;
5042 if (!PyArg_ParseTuple(args, "i:dup", &fd))
5043 return NULL;
5044 if (!_PyVerify_fd(fd))
5045 return posix_error();
5046 Py_BEGIN_ALLOW_THREADS
5047 fd = dup(fd);
5048 Py_END_ALLOW_THREADS
5049 if (fd < 0)
5050 return posix_error();
5051 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005052}
5053
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005054
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005055PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005056"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005057Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005058
Barry Warsaw53699e91996-12-10 23:23:01 +00005059static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005060posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005061{
Victor Stinner97b89882010-05-06 00:25:39 +00005062 int fd, fd2, res;
5063 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5064 return NULL;
5065 if (!_PyVerify_fd_dup2(fd, fd2))
5066 return posix_error();
5067 Py_BEGIN_ALLOW_THREADS
5068 res = dup2(fd, fd2);
5069 Py_END_ALLOW_THREADS
5070 if (res < 0)
5071 return posix_error();
5072 Py_INCREF(Py_None);
5073 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005074}
5075
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005076
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005077PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005078"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005079Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005080
Barry Warsaw53699e91996-12-10 23:23:01 +00005081static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005082posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005083{
Victor Stinner97b89882010-05-06 00:25:39 +00005084 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005085#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner97b89882010-05-06 00:25:39 +00005086 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005087#else
Victor Stinner97b89882010-05-06 00:25:39 +00005088 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005089#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005090 PyObject *posobj;
5091 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5092 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005093#ifdef SEEK_SET
Victor Stinner97b89882010-05-06 00:25:39 +00005094 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5095 switch (how) {
5096 case 0: how = SEEK_SET; break;
5097 case 1: how = SEEK_CUR; break;
5098 case 2: how = SEEK_END; break;
5099 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005100#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005101
5102#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner97b89882010-05-06 00:25:39 +00005103 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005104#else
Victor Stinner97b89882010-05-06 00:25:39 +00005105 pos = PyLong_Check(posobj) ?
5106 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005107#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005108 if (PyErr_Occurred())
5109 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005110
Victor Stinner97b89882010-05-06 00:25:39 +00005111 if (!_PyVerify_fd(fd))
5112 return posix_error();
5113 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005114#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner97b89882010-05-06 00:25:39 +00005115 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005116#else
Victor Stinner97b89882010-05-06 00:25:39 +00005117 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005118#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005119 Py_END_ALLOW_THREADS
5120 if (res < 0)
5121 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005122
5123#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner97b89882010-05-06 00:25:39 +00005124 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005125#else
Victor Stinner97b89882010-05-06 00:25:39 +00005126 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005127#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005128}
5129
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005130
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005131PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005132"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005133Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005134
Barry Warsaw53699e91996-12-10 23:23:01 +00005135static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005136posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005137{
Victor Stinner97b89882010-05-06 00:25:39 +00005138 int fd, size;
5139 Py_ssize_t n;
5140 PyObject *buffer;
5141 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5142 return NULL;
5143 if (size < 0) {
5144 errno = EINVAL;
5145 return posix_error();
5146 }
5147 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
5148 if (buffer == NULL)
5149 return NULL;
Stefan Krah40b61232010-11-26 15:08:59 +00005150 if (!_PyVerify_fd(fd)) {
5151 Py_DECREF(buffer);
Victor Stinner97b89882010-05-06 00:25:39 +00005152 return posix_error();
Stefan Krah40b61232010-11-26 15:08:59 +00005153 }
Victor Stinner97b89882010-05-06 00:25:39 +00005154 Py_BEGIN_ALLOW_THREADS
5155 n = read(fd, PyBytes_AS_STRING(buffer), size);
5156 Py_END_ALLOW_THREADS
5157 if (n < 0) {
5158 Py_DECREF(buffer);
5159 return posix_error();
5160 }
5161 if (n != size)
5162 _PyBytes_Resize(&buffer, n);
5163 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00005164}
5165
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005166
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005167PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005168"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005169Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005170
Barry Warsaw53699e91996-12-10 23:23:01 +00005171static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005172posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005173{
Victor Stinner97b89882010-05-06 00:25:39 +00005174 Py_buffer pbuf;
5175 int fd;
5176 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005177
Victor Stinner97b89882010-05-06 00:25:39 +00005178 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
5179 return NULL;
Stefan Krah40b61232010-11-26 15:08:59 +00005180 if (!_PyVerify_fd(fd)) {
5181 PyBuffer_Release(&pbuf);
Victor Stinner97b89882010-05-06 00:25:39 +00005182 return posix_error();
Stefan Krah40b61232010-11-26 15:08:59 +00005183 }
Victor Stinner97b89882010-05-06 00:25:39 +00005184 Py_BEGIN_ALLOW_THREADS
5185 size = write(fd, pbuf.buf, (size_t)pbuf.len);
5186 Py_END_ALLOW_THREADS
Stefan Krah40b61232010-11-26 15:08:59 +00005187 PyBuffer_Release(&pbuf);
Victor Stinner97b89882010-05-06 00:25:39 +00005188 if (size < 0)
5189 return posix_error();
5190 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005191}
5192
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005193
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005194PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005195"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005196Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005197
Barry Warsaw53699e91996-12-10 23:23:01 +00005198static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005199posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005200{
Victor Stinner97b89882010-05-06 00:25:39 +00005201 int fd;
5202 STRUCT_STAT st;
5203 int res;
5204 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5205 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005206#ifdef __VMS
Victor Stinner97b89882010-05-06 00:25:39 +00005207 /* on OpenVMS we must ensure that all bytes are written to the file */
5208 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005209#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005210 if (!_PyVerify_fd(fd))
5211 return posix_error();
5212 Py_BEGIN_ALLOW_THREADS
5213 res = FSTAT(fd, &st);
5214 Py_END_ALLOW_THREADS
5215 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00005216#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00005217 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00005218#else
Victor Stinner97b89882010-05-06 00:25:39 +00005219 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005220#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005221 }
Tim Peters5aa91602002-01-30 05:46:57 +00005222
Victor Stinner97b89882010-05-06 00:25:39 +00005223 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005224}
5225
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005226PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005227"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005228Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005229connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005230
5231static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005232posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005233{
Victor Stinner97b89882010-05-06 00:25:39 +00005234 int fd;
5235 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5236 return NULL;
5237 if (!_PyVerify_fd(fd))
5238 return PyBool_FromLong(0);
5239 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005240}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005241
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005242#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005243PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005244"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005245Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005246
Barry Warsaw53699e91996-12-10 23:23:01 +00005247static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005248posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005249{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005250#if defined(PYOS_OS2)
5251 HFILE read, write;
5252 APIRET rc;
5253
Victor Stinner97b89882010-05-06 00:25:39 +00005254 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005255 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinner97b89882010-05-06 00:25:39 +00005256 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005257 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005258 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005259
5260 return Py_BuildValue("(ii)", read, write);
5261#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005262#if !defined(MS_WINDOWS)
Victor Stinner97b89882010-05-06 00:25:39 +00005263 int fds[2];
5264 int res;
5265 Py_BEGIN_ALLOW_THREADS
5266 res = pipe(fds);
5267 Py_END_ALLOW_THREADS
5268 if (res != 0)
5269 return posix_error();
5270 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005271#else /* MS_WINDOWS */
Victor Stinner97b89882010-05-06 00:25:39 +00005272 HANDLE read, write;
5273 int read_fd, write_fd;
5274 BOOL ok;
5275 Py_BEGIN_ALLOW_THREADS
5276 ok = CreatePipe(&read, &write, NULL, 0);
5277 Py_END_ALLOW_THREADS
5278 if (!ok)
5279 return win32_error("CreatePipe", NULL);
5280 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5281 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5282 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005283#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005284#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005285}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005286#endif /* HAVE_PIPE */
5287
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005288
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005289#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005290PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005291"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005292Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005293
Barry Warsaw53699e91996-12-10 23:23:01 +00005294static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005295posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005296{
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005297 PyObject *opath;
Victor Stinner97b89882010-05-06 00:25:39 +00005298 char *filename;
5299 int mode = 0666;
5300 int res;
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005301 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
5302 &mode))
Victor Stinner97b89882010-05-06 00:25:39 +00005303 return NULL;
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005304 filename = PyBytes_AS_STRING(opath);
Victor Stinner97b89882010-05-06 00:25:39 +00005305 Py_BEGIN_ALLOW_THREADS
5306 res = mkfifo(filename, mode);
5307 Py_END_ALLOW_THREADS
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005308 Py_DECREF(opath);
Victor Stinner97b89882010-05-06 00:25:39 +00005309 if (res < 0)
5310 return posix_error();
5311 Py_INCREF(Py_None);
5312 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005313}
5314#endif
5315
5316
Neal Norwitz11690112002-07-30 01:08:28 +00005317#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005318PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005319"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005320Create a filesystem node (file, device special file or named pipe)\n\
5321named filename. mode specifies both the permissions to use and the\n\
5322type of node to be created, being combined (bitwise OR) with one of\n\
5323S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005324device defines the newly created device special file (probably using\n\
5325os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005326
5327
5328static PyObject *
5329posix_mknod(PyObject *self, PyObject *args)
5330{
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005331 PyObject *opath;
Victor Stinner97b89882010-05-06 00:25:39 +00005332 char *filename;
5333 int mode = 0600;
5334 int device = 0;
5335 int res;
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005336 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
5337 &mode, &device))
Victor Stinner97b89882010-05-06 00:25:39 +00005338 return NULL;
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005339 filename = PyBytes_AS_STRING(opath);
Victor Stinner97b89882010-05-06 00:25:39 +00005340 Py_BEGIN_ALLOW_THREADS
5341 res = mknod(filename, mode, device);
5342 Py_END_ALLOW_THREADS
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005343 Py_DECREF(opath);
Victor Stinner97b89882010-05-06 00:25:39 +00005344 if (res < 0)
5345 return posix_error();
5346 Py_INCREF(Py_None);
5347 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005348}
5349#endif
5350
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005351#ifdef HAVE_DEVICE_MACROS
5352PyDoc_STRVAR(posix_major__doc__,
5353"major(device) -> major number\n\
5354Extracts a device major number from a raw device number.");
5355
5356static PyObject *
5357posix_major(PyObject *self, PyObject *args)
5358{
Victor Stinner97b89882010-05-06 00:25:39 +00005359 int device;
5360 if (!PyArg_ParseTuple(args, "i:major", &device))
5361 return NULL;
5362 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005363}
5364
5365PyDoc_STRVAR(posix_minor__doc__,
5366"minor(device) -> minor number\n\
5367Extracts a device minor number from a raw device number.");
5368
5369static PyObject *
5370posix_minor(PyObject *self, PyObject *args)
5371{
Victor Stinner97b89882010-05-06 00:25:39 +00005372 int device;
5373 if (!PyArg_ParseTuple(args, "i:minor", &device))
5374 return NULL;
5375 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005376}
5377
5378PyDoc_STRVAR(posix_makedev__doc__,
5379"makedev(major, minor) -> device number\n\
5380Composes a raw device number from the major and minor device numbers.");
5381
5382static PyObject *
5383posix_makedev(PyObject *self, PyObject *args)
5384{
Victor Stinner97b89882010-05-06 00:25:39 +00005385 int major, minor;
5386 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5387 return NULL;
5388 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005389}
5390#endif /* device macros */
5391
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005392
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005393#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005394PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005395"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005396Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005397
Barry Warsaw53699e91996-12-10 23:23:01 +00005398static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005399posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005400{
Victor Stinner97b89882010-05-06 00:25:39 +00005401 int fd;
5402 off_t length;
5403 int res;
5404 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005405
Victor Stinner97b89882010-05-06 00:25:39 +00005406 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
5407 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005408
5409#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner97b89882010-05-06 00:25:39 +00005410 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005411#else
Victor Stinner97b89882010-05-06 00:25:39 +00005412 length = PyLong_Check(lenobj) ?
5413 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005414#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005415 if (PyErr_Occurred())
5416 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005417
Victor Stinner97b89882010-05-06 00:25:39 +00005418 Py_BEGIN_ALLOW_THREADS
5419 res = ftruncate(fd, length);
5420 Py_END_ALLOW_THREADS
5421 if (res < 0)
5422 return posix_error();
5423 Py_INCREF(Py_None);
5424 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005425}
5426#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005427
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005428#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005429PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005430"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005431Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005432
Fred Drake762e2061999-08-26 17:23:54 +00005433/* Save putenv() parameters as values here, so we can collect them when they
5434 * get re-set with another call for the same key. */
5435static PyObject *posix_putenv_garbage;
5436
Tim Peters5aa91602002-01-30 05:46:57 +00005437static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005438posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005439{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005440#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00005441 wchar_t *s1, *s2;
5442 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005443#else
Victor Stinner97b89882010-05-06 00:25:39 +00005444 PyObject *os1, *os2;
5445 char *s1, *s2;
5446 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005447#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005448 PyObject *newstr;
5449 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005450
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005451#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00005452 if (!PyArg_ParseTuple(args,
5453 "uu:putenv",
5454 &s1, &s2))
5455 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005456#else
Victor Stinner97b89882010-05-06 00:25:39 +00005457 if (!PyArg_ParseTuple(args,
5458 "O&O&:putenv",
5459 PyUnicode_FSConverter, &os1,
5460 PyUnicode_FSConverter, &os2))
5461 return NULL;
5462 s1 = bytes2str(os1, 1);
5463 s2 = bytes2str(os2, 1);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005464#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005465
5466#if defined(PYOS_OS2)
5467 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5468 APIRET rc;
5469
Guido van Rossumd48f2521997-12-05 22:19:34 +00005470 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5471 if (rc != NO_ERROR)
5472 return os2_error(rc);
5473
5474 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5475 APIRET rc;
5476
Guido van Rossumd48f2521997-12-05 22:19:34 +00005477 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5478 if (rc != NO_ERROR)
5479 return os2_error(rc);
5480 } else {
5481#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005482 /* XXX This can leak memory -- not easy to fix :-( */
5483 /* len includes space for a trailing \0; the size arg to
5484 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005485#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00005486 len = wcslen(s1) + wcslen(s2) + 2;
5487 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005488#else
Victor Stinner97b89882010-05-06 00:25:39 +00005489 len = strlen(s1) + strlen(s2) + 2;
5490 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005491#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005492 if (newstr == NULL)
5493 return PyErr_NoMemory();
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005494#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00005495 newenv = PyUnicode_AsUnicode(newstr);
5496 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5497 if (_wputenv(newenv)) {
5498 Py_DECREF(newstr);
5499 posix_error();
5500 return NULL;
5501 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005502#else
Victor Stinner97b89882010-05-06 00:25:39 +00005503 newenv = PyBytes_AS_STRING(newstr);
5504 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5505 if (putenv(newenv)) {
5506 Py_DECREF(newstr);
5507 release_bytes(os1);
5508 release_bytes(os2);
5509 posix_error();
5510 return NULL;
5511 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005512#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005513 /* Install the first arg and newstr in posix_putenv_garbage;
5514 * this will cause previous value to be collected. This has to
5515 * happen after the real putenv() call because the old value
5516 * was still accessible until then. */
5517 if (PyDict_SetItem(posix_putenv_garbage,
5518 PyTuple_GET_ITEM(args, 0), newstr)) {
5519 /* really not much we can do; just leak */
5520 PyErr_Clear();
5521 }
5522 else {
5523 Py_DECREF(newstr);
5524 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005525
5526#if defined(PYOS_OS2)
5527 }
5528#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00005529#ifndef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00005530 release_bytes(os1);
5531 release_bytes(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005532#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005533 Py_INCREF(Py_None);
5534 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005535}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005536#endif /* putenv */
5537
Guido van Rossumc524d952001-10-19 01:31:59 +00005538#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005539PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005540"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005541Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005542
5543static PyObject *
5544posix_unsetenv(PyObject *self, PyObject *args)
5545{
Victor Stinner97b89882010-05-06 00:25:39 +00005546 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00005547
Victor Stinner97b89882010-05-06 00:25:39 +00005548 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5549 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00005550
Victor Stinner97b89882010-05-06 00:25:39 +00005551 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00005552
Victor Stinner97b89882010-05-06 00:25:39 +00005553 /* Remove the key from posix_putenv_garbage;
5554 * this will cause it to be collected. This has to
5555 * happen after the real unsetenv() call because the
5556 * old value was still accessible until then.
5557 */
5558 if (PyDict_DelItem(posix_putenv_garbage,
5559 PyTuple_GET_ITEM(args, 0))) {
5560 /* really not much we can do; just leak */
5561 PyErr_Clear();
5562 }
Guido van Rossumc524d952001-10-19 01:31:59 +00005563
Victor Stinner97b89882010-05-06 00:25:39 +00005564 Py_INCREF(Py_None);
5565 return Py_None;
Guido van Rossumc524d952001-10-19 01:31:59 +00005566}
5567#endif /* unsetenv */
5568
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005569PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005570"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005571Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005572
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005573static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005574posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005575{
Victor Stinner97b89882010-05-06 00:25:39 +00005576 int code;
5577 char *message;
5578 if (!PyArg_ParseTuple(args, "i:strerror", &code))
5579 return NULL;
5580 message = strerror(code);
5581 if (message == NULL) {
5582 PyErr_SetString(PyExc_ValueError,
5583 "strerror() argument out of range");
5584 return NULL;
5585 }
5586 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00005587}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005588
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005589
Guido van Rossumc9641791998-08-04 15:26:23 +00005590#ifdef HAVE_SYS_WAIT_H
5591
Fred Drake106c1a02002-04-23 15:58:02 +00005592#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005593PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005594"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005595Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005596
5597static PyObject *
5598posix_WCOREDUMP(PyObject *self, PyObject *args)
5599{
Victor Stinner97b89882010-05-06 00:25:39 +00005600 WAIT_TYPE status;
5601 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005602
Victor Stinner97b89882010-05-06 00:25:39 +00005603 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
5604 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005605
Victor Stinner97b89882010-05-06 00:25:39 +00005606 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005607}
5608#endif /* WCOREDUMP */
5609
5610#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005611PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005612"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005613Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005614job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005615
5616static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005617posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005618{
Victor Stinner97b89882010-05-06 00:25:39 +00005619 WAIT_TYPE status;
5620 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005621
Victor Stinner97b89882010-05-06 00:25:39 +00005622 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
5623 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005624
Victor Stinner97b89882010-05-06 00:25:39 +00005625 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005626}
5627#endif /* WIFCONTINUED */
5628
Guido van Rossumc9641791998-08-04 15:26:23 +00005629#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005630PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005631"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005632Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005633
5634static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005635posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005636{
Victor Stinner97b89882010-05-06 00:25:39 +00005637 WAIT_TYPE status;
5638 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005639
Victor Stinner97b89882010-05-06 00:25:39 +00005640 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
5641 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005642
Victor Stinner97b89882010-05-06 00:25:39 +00005643 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005644}
5645#endif /* WIFSTOPPED */
5646
5647#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005648PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005649"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005650Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005651
5652static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005653posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005654{
Victor Stinner97b89882010-05-06 00:25:39 +00005655 WAIT_TYPE status;
5656 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005657
Victor Stinner97b89882010-05-06 00:25:39 +00005658 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
5659 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005660
Victor Stinner97b89882010-05-06 00:25:39 +00005661 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005662}
5663#endif /* WIFSIGNALED */
5664
5665#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005666PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005667"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005668Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005669system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005670
5671static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005672posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005673{
Victor Stinner97b89882010-05-06 00:25:39 +00005674 WAIT_TYPE status;
5675 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005676
Victor Stinner97b89882010-05-06 00:25:39 +00005677 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
5678 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005679
Victor Stinner97b89882010-05-06 00:25:39 +00005680 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005681}
5682#endif /* WIFEXITED */
5683
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005684#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005685PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005686"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005687Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005688
5689static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005690posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005691{
Victor Stinner97b89882010-05-06 00:25:39 +00005692 WAIT_TYPE status;
5693 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005694
Victor Stinner97b89882010-05-06 00:25:39 +00005695 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
5696 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005697
Victor Stinner97b89882010-05-06 00:25:39 +00005698 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005699}
5700#endif /* WEXITSTATUS */
5701
5702#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005703PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005704"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005705Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005706value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005707
5708static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005709posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005710{
Victor Stinner97b89882010-05-06 00:25:39 +00005711 WAIT_TYPE status;
5712 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005713
Victor Stinner97b89882010-05-06 00:25:39 +00005714 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
5715 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005716
Victor Stinner97b89882010-05-06 00:25:39 +00005717 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005718}
5719#endif /* WTERMSIG */
5720
5721#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005722PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005723"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005724Return the signal that stopped the process that provided\n\
5725the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005726
5727static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005728posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005729{
Victor Stinner97b89882010-05-06 00:25:39 +00005730 WAIT_TYPE status;
5731 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005732
Victor Stinner97b89882010-05-06 00:25:39 +00005733 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
5734 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005735
Victor Stinner97b89882010-05-06 00:25:39 +00005736 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005737}
5738#endif /* WSTOPSIG */
5739
5740#endif /* HAVE_SYS_WAIT_H */
5741
5742
Thomas Wouters477c8d52006-05-27 19:21:47 +00005743#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005744#ifdef _SCO_DS
5745/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5746 needed definitions in sys/statvfs.h */
5747#define _SVID3
5748#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005749#include <sys/statvfs.h>
5750
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005751static PyObject*
5752_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner97b89882010-05-06 00:25:39 +00005753 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5754 if (v == NULL)
5755 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005756
5757#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner97b89882010-05-06 00:25:39 +00005758 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5759 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
5760 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
5761 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
5762 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
5763 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
5764 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
5765 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
5766 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5767 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005768#else
Victor Stinner97b89882010-05-06 00:25:39 +00005769 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5770 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
5771 PyStructSequence_SET_ITEM(v, 2,
5772 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
5773 PyStructSequence_SET_ITEM(v, 3,
5774 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
5775 PyStructSequence_SET_ITEM(v, 4,
5776 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
5777 PyStructSequence_SET_ITEM(v, 5,
5778 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
5779 PyStructSequence_SET_ITEM(v, 6,
5780 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
5781 PyStructSequence_SET_ITEM(v, 7,
5782 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
5783 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5784 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005785#endif
5786
Victor Stinner97b89882010-05-06 00:25:39 +00005787 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005788}
5789
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005790PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005791"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005792Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005793
5794static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005795posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005796{
Victor Stinner97b89882010-05-06 00:25:39 +00005797 int fd, res;
5798 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005799
Victor Stinner97b89882010-05-06 00:25:39 +00005800 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
5801 return NULL;
5802 Py_BEGIN_ALLOW_THREADS
5803 res = fstatvfs(fd, &st);
5804 Py_END_ALLOW_THREADS
5805 if (res != 0)
5806 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005807
Victor Stinner97b89882010-05-06 00:25:39 +00005808 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005809}
Thomas Wouters477c8d52006-05-27 19:21:47 +00005810#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005811
5812
Thomas Wouters477c8d52006-05-27 19:21:47 +00005813#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005814#include <sys/statvfs.h>
5815
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005816PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005817"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005818Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005819
5820static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005821posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005822{
Victor Stinner97b89882010-05-06 00:25:39 +00005823 char *path;
5824 int res;
5825 struct statvfs st;
5826 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
5827 return NULL;
5828 Py_BEGIN_ALLOW_THREADS
5829 res = statvfs(path, &st);
5830 Py_END_ALLOW_THREADS
5831 if (res != 0)
5832 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005833
Victor Stinner97b89882010-05-06 00:25:39 +00005834 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005835}
5836#endif /* HAVE_STATVFS */
5837
Fred Drakec9680921999-12-13 16:37:25 +00005838/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5839 * It maps strings representing configuration variable names to
5840 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005841 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005842 * rarely-used constants. There are three separate tables that use
5843 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005844 *
5845 * This code is always included, even if none of the interfaces that
5846 * need it are included. The #if hackery needed to avoid it would be
5847 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005848 */
5849struct constdef {
5850 char *name;
5851 long value;
5852};
5853
Fred Drake12c6e2d1999-12-14 21:25:03 +00005854static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005855conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005856 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005857{
Christian Heimes217cfd12007-12-02 14:31:20 +00005858 if (PyLong_Check(arg)) {
Stefan Krah67733312010-11-26 17:04:40 +00005859 *valuep = PyLong_AS_LONG(arg);
5860 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005861 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00005862 else {
Stefan Krah67733312010-11-26 17:04:40 +00005863 /* look up the value in the table using a binary search */
5864 size_t lo = 0;
5865 size_t mid;
5866 size_t hi = tablesize;
5867 int cmp;
5868 const char *confname;
5869 if (!PyUnicode_Check(arg)) {
5870 PyErr_SetString(PyExc_TypeError,
5871 "configuration names must be strings or integers");
5872 return 0;
Victor Stinner97b89882010-05-06 00:25:39 +00005873 }
Stefan Krah67733312010-11-26 17:04:40 +00005874 confname = _PyUnicode_AsString(arg);
5875 if (confname == NULL)
5876 return 0;
5877 while (lo < hi) {
5878 mid = (lo + hi) / 2;
5879 cmp = strcmp(confname, table[mid].name);
5880 if (cmp < 0)
5881 hi = mid;
5882 else if (cmp > 0)
5883 lo = mid + 1;
5884 else {
5885 *valuep = table[mid].value;
5886 return 1;
5887 }
5888 }
5889 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5890 return 0;
Victor Stinner97b89882010-05-06 00:25:39 +00005891 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00005892}
5893
5894
5895#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5896static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005897#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00005898 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00005899#endif
5900#ifdef _PC_ABI_ASYNC_IO
Victor Stinner97b89882010-05-06 00:25:39 +00005901 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00005902#endif
Fred Drakec9680921999-12-13 16:37:25 +00005903#ifdef _PC_ASYNC_IO
Victor Stinner97b89882010-05-06 00:25:39 +00005904 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00005905#endif
5906#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner97b89882010-05-06 00:25:39 +00005907 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00005908#endif
5909#ifdef _PC_FILESIZEBITS
Victor Stinner97b89882010-05-06 00:25:39 +00005910 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00005911#endif
5912#ifdef _PC_LAST
Victor Stinner97b89882010-05-06 00:25:39 +00005913 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00005914#endif
5915#ifdef _PC_LINK_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00005916 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00005917#endif
5918#ifdef _PC_MAX_CANON
Victor Stinner97b89882010-05-06 00:25:39 +00005919 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00005920#endif
5921#ifdef _PC_MAX_INPUT
Victor Stinner97b89882010-05-06 00:25:39 +00005922 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00005923#endif
5924#ifdef _PC_NAME_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00005925 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00005926#endif
5927#ifdef _PC_NO_TRUNC
Victor Stinner97b89882010-05-06 00:25:39 +00005928 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00005929#endif
5930#ifdef _PC_PATH_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00005931 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00005932#endif
5933#ifdef _PC_PIPE_BUF
Victor Stinner97b89882010-05-06 00:25:39 +00005934 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00005935#endif
5936#ifdef _PC_PRIO_IO
Victor Stinner97b89882010-05-06 00:25:39 +00005937 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00005938#endif
5939#ifdef _PC_SOCK_MAXBUF
Victor Stinner97b89882010-05-06 00:25:39 +00005940 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00005941#endif
5942#ifdef _PC_SYNC_IO
Victor Stinner97b89882010-05-06 00:25:39 +00005943 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00005944#endif
5945#ifdef _PC_VDISABLE
Victor Stinner97b89882010-05-06 00:25:39 +00005946 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00005947#endif
5948};
5949
Fred Drakec9680921999-12-13 16:37:25 +00005950static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005951conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005952{
5953 return conv_confname(arg, valuep, posix_constants_pathconf,
5954 sizeof(posix_constants_pathconf)
5955 / sizeof(struct constdef));
5956}
5957#endif
5958
5959#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005960PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005961"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005962Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005963If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005964
5965static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005966posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005967{
5968 PyObject *result = NULL;
5969 int name, fd;
5970
Fred Drake12c6e2d1999-12-14 21:25:03 +00005971 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5972 conv_path_confname, &name)) {
Stefan Krah67733312010-11-26 17:04:40 +00005973 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00005974
Stefan Krah67733312010-11-26 17:04:40 +00005975 errno = 0;
5976 limit = fpathconf(fd, name);
5977 if (limit == -1 && errno != 0)
5978 posix_error();
5979 else
5980 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00005981 }
5982 return result;
5983}
5984#endif
5985
5986
5987#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005988PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005989"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005990Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005991If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005992
5993static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005994posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005995{
5996 PyObject *result = NULL;
5997 int name;
5998 char *path;
5999
6000 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6001 conv_path_confname, &name)) {
Victor Stinner97b89882010-05-06 00:25:39 +00006002 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006003
Victor Stinner97b89882010-05-06 00:25:39 +00006004 errno = 0;
6005 limit = pathconf(path, name);
6006 if (limit == -1 && errno != 0) {
6007 if (errno == EINVAL)
Stefan Krah40b61232010-11-26 15:08:59 +00006008 /* could be a path or name problem */
6009 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00006010 else
Stefan Krah40b61232010-11-26 15:08:59 +00006011 posix_error_with_filename(path);
Victor Stinner97b89882010-05-06 00:25:39 +00006012 }
6013 else
6014 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006015 }
6016 return result;
6017}
6018#endif
6019
6020#ifdef HAVE_CONFSTR
6021static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006022#ifdef _CS_ARCHITECTURE
Victor Stinner97b89882010-05-06 00:25:39 +00006023 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00006024#endif
Mark Dickinson466e9262010-04-16 16:32:49 +00006025#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006026 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson466e9262010-04-16 16:32:49 +00006027#endif
6028#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006029 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson466e9262010-04-16 16:32:49 +00006030#endif
Fred Draked86ed291999-12-15 15:34:33 +00006031#ifdef _CS_HOSTNAME
Victor Stinner97b89882010-05-06 00:25:39 +00006032 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006033#endif
6034#ifdef _CS_HW_PROVIDER
Victor Stinner97b89882010-05-06 00:25:39 +00006035 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006036#endif
6037#ifdef _CS_HW_SERIAL
Victor Stinner97b89882010-05-06 00:25:39 +00006038 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006039#endif
6040#ifdef _CS_INITTAB_NAME
Victor Stinner97b89882010-05-06 00:25:39 +00006041 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006042#endif
Fred Drakec9680921999-12-13 16:37:25 +00006043#ifdef _CS_LFS64_CFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006044 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006045#endif
6046#ifdef _CS_LFS64_LDFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006047 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006048#endif
6049#ifdef _CS_LFS64_LIBS
Victor Stinner97b89882010-05-06 00:25:39 +00006050 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006051#endif
6052#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006053 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006054#endif
6055#ifdef _CS_LFS_CFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006056 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006057#endif
6058#ifdef _CS_LFS_LDFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006059 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006060#endif
6061#ifdef _CS_LFS_LIBS
Victor Stinner97b89882010-05-06 00:25:39 +00006062 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006063#endif
6064#ifdef _CS_LFS_LINTFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006065 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006066#endif
Fred Draked86ed291999-12-15 15:34:33 +00006067#ifdef _CS_MACHINE
Victor Stinner97b89882010-05-06 00:25:39 +00006068 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00006069#endif
Fred Drakec9680921999-12-13 16:37:25 +00006070#ifdef _CS_PATH
Victor Stinner97b89882010-05-06 00:25:39 +00006071 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00006072#endif
Fred Draked86ed291999-12-15 15:34:33 +00006073#ifdef _CS_RELEASE
Victor Stinner97b89882010-05-06 00:25:39 +00006074 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00006075#endif
6076#ifdef _CS_SRPC_DOMAIN
Victor Stinner97b89882010-05-06 00:25:39 +00006077 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00006078#endif
6079#ifdef _CS_SYSNAME
Victor Stinner97b89882010-05-06 00:25:39 +00006080 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006081#endif
6082#ifdef _CS_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006083 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00006084#endif
Fred Drakec9680921999-12-13 16:37:25 +00006085#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006086 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006087#endif
6088#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006089 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006090#endif
6091#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner97b89882010-05-06 00:25:39 +00006092 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006093#endif
6094#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006095 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006096#endif
6097#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006098 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006099#endif
6100#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006101 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006102#endif
6103#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner97b89882010-05-06 00:25:39 +00006104 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006105#endif
6106#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006107 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006108#endif
6109#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006110 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006111#endif
6112#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006113 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006114#endif
6115#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner97b89882010-05-06 00:25:39 +00006116 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006117#endif
6118#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006119 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006120#endif
6121#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006122 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006123#endif
6124#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006125 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006126#endif
6127#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner97b89882010-05-06 00:25:39 +00006128 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006129#endif
6130#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006131 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006132#endif
Fred Draked86ed291999-12-15 15:34:33 +00006133#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner97b89882010-05-06 00:25:39 +00006134 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006135#endif
6136#ifdef _MIPS_CS_BASE
Victor Stinner97b89882010-05-06 00:25:39 +00006137 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00006138#endif
6139#ifdef _MIPS_CS_HOSTID
Victor Stinner97b89882010-05-06 00:25:39 +00006140 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00006141#endif
6142#ifdef _MIPS_CS_HW_NAME
Victor Stinner97b89882010-05-06 00:25:39 +00006143 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006144#endif
6145#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner97b89882010-05-06 00:25:39 +00006146 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006147#endif
6148#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner97b89882010-05-06 00:25:39 +00006149 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00006150#endif
6151#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner97b89882010-05-06 00:25:39 +00006152 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00006153#endif
6154#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner97b89882010-05-06 00:25:39 +00006155 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00006156#endif
6157#ifdef _MIPS_CS_OS_NAME
Victor Stinner97b89882010-05-06 00:25:39 +00006158 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006159#endif
6160#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner97b89882010-05-06 00:25:39 +00006161 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006162#endif
6163#ifdef _MIPS_CS_PROCESSORS
Victor Stinner97b89882010-05-06 00:25:39 +00006164 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006165#endif
6166#ifdef _MIPS_CS_SERIAL
Victor Stinner97b89882010-05-06 00:25:39 +00006167 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006168#endif
6169#ifdef _MIPS_CS_VENDOR
Victor Stinner97b89882010-05-06 00:25:39 +00006170 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00006171#endif
Fred Drakec9680921999-12-13 16:37:25 +00006172};
6173
6174static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006175conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006176{
6177 return conv_confname(arg, valuep, posix_constants_confstr,
6178 sizeof(posix_constants_confstr)
6179 / sizeof(struct constdef));
6180}
6181
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006182PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006183"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006184Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006185
6186static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006187posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006188{
6189 PyObject *result = NULL;
6190 int name;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006191 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00006192
6193 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Stefan Krah40b61232010-11-26 15:08:59 +00006194 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006195
Fred Drakec9680921999-12-13 16:37:25 +00006196 errno = 0;
Victor Stinner97b89882010-05-06 00:25:39 +00006197 len = confstr(name, buffer, sizeof(buffer));
6198 if (len == 0) {
6199 if (errno) {
6200 posix_error();
6201 }
6202 else {
6203 result = Py_None;
6204 Py_INCREF(Py_None);
6205 }
Fred Drakec9680921999-12-13 16:37:25 +00006206 }
6207 else {
Victor Stinner97b89882010-05-06 00:25:39 +00006208 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz93c56822007-08-26 07:10:06 +00006209 result = PyUnicode_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006210 if (result != NULL)
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00006211 confstr(name, _PyUnicode_AsString(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00006212 }
6213 else
Neal Norwitz93c56822007-08-26 07:10:06 +00006214 result = PyUnicode_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006215 }
6216 }
6217 return result;
6218}
6219#endif
6220
6221
6222#ifdef HAVE_SYSCONF
6223static struct constdef posix_constants_sysconf[] = {
6224#ifdef _SC_2_CHAR_TERM
Victor Stinner97b89882010-05-06 00:25:39 +00006225 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00006226#endif
6227#ifdef _SC_2_C_BIND
Victor Stinner97b89882010-05-06 00:25:39 +00006228 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00006229#endif
6230#ifdef _SC_2_C_DEV
Victor Stinner97b89882010-05-06 00:25:39 +00006231 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006232#endif
6233#ifdef _SC_2_C_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006234 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006235#endif
6236#ifdef _SC_2_FORT_DEV
Victor Stinner97b89882010-05-06 00:25:39 +00006237 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006238#endif
6239#ifdef _SC_2_FORT_RUN
Victor Stinner97b89882010-05-06 00:25:39 +00006240 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00006241#endif
6242#ifdef _SC_2_LOCALEDEF
Victor Stinner97b89882010-05-06 00:25:39 +00006243 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00006244#endif
6245#ifdef _SC_2_SW_DEV
Victor Stinner97b89882010-05-06 00:25:39 +00006246 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006247#endif
6248#ifdef _SC_2_UPE
Victor Stinner97b89882010-05-06 00:25:39 +00006249 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00006250#endif
6251#ifdef _SC_2_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006252 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006253#endif
Fred Draked86ed291999-12-15 15:34:33 +00006254#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner97b89882010-05-06 00:25:39 +00006255 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006256#endif
6257#ifdef _SC_ACL
Victor Stinner97b89882010-05-06 00:25:39 +00006258 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00006259#endif
Fred Drakec9680921999-12-13 16:37:25 +00006260#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006261 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006262#endif
Fred Drakec9680921999-12-13 16:37:25 +00006263#ifdef _SC_AIO_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006264 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006265#endif
6266#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006267 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006268#endif
6269#ifdef _SC_ARG_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006270 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006271#endif
6272#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner97b89882010-05-06 00:25:39 +00006273 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006274#endif
6275#ifdef _SC_ATEXIT_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006276 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006277#endif
Fred Draked86ed291999-12-15 15:34:33 +00006278#ifdef _SC_AUDIT
Victor Stinner97b89882010-05-06 00:25:39 +00006279 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00006280#endif
Fred Drakec9680921999-12-13 16:37:25 +00006281#ifdef _SC_AVPHYS_PAGES
Victor Stinner97b89882010-05-06 00:25:39 +00006282 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006283#endif
6284#ifdef _SC_BC_BASE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006285 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006286#endif
6287#ifdef _SC_BC_DIM_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006288 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006289#endif
6290#ifdef _SC_BC_SCALE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006291 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006292#endif
6293#ifdef _SC_BC_STRING_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006294 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006295#endif
Fred Draked86ed291999-12-15 15:34:33 +00006296#ifdef _SC_CAP
Victor Stinner97b89882010-05-06 00:25:39 +00006297 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00006298#endif
Fred Drakec9680921999-12-13 16:37:25 +00006299#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006300 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006301#endif
6302#ifdef _SC_CHAR_BIT
Victor Stinner97b89882010-05-06 00:25:39 +00006303 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006304#endif
6305#ifdef _SC_CHAR_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006306 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006307#endif
6308#ifdef _SC_CHAR_MIN
Victor Stinner97b89882010-05-06 00:25:39 +00006309 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006310#endif
6311#ifdef _SC_CHILD_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006312 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006313#endif
6314#ifdef _SC_CLK_TCK
Victor Stinner97b89882010-05-06 00:25:39 +00006315 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00006316#endif
6317#ifdef _SC_COHER_BLKSZ
Victor Stinner97b89882010-05-06 00:25:39 +00006318 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006319#endif
6320#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006321 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006322#endif
6323#ifdef _SC_DCACHE_ASSOC
Victor Stinner97b89882010-05-06 00:25:39 +00006324 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006325#endif
6326#ifdef _SC_DCACHE_BLKSZ
Victor Stinner97b89882010-05-06 00:25:39 +00006327 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006328#endif
6329#ifdef _SC_DCACHE_LINESZ
Victor Stinner97b89882010-05-06 00:25:39 +00006330 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006331#endif
6332#ifdef _SC_DCACHE_SZ
Victor Stinner97b89882010-05-06 00:25:39 +00006333 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006334#endif
6335#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner97b89882010-05-06 00:25:39 +00006336 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006337#endif
6338#ifdef _SC_DELAYTIMER_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006339 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006340#endif
6341#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006342 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006343#endif
6344#ifdef _SC_EXPR_NEST_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006345 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006346#endif
6347#ifdef _SC_FSYNC
Victor Stinner97b89882010-05-06 00:25:39 +00006348 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00006349#endif
6350#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006351 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006352#endif
6353#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006354 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006355#endif
6356#ifdef _SC_ICACHE_ASSOC
Victor Stinner97b89882010-05-06 00:25:39 +00006357 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006358#endif
6359#ifdef _SC_ICACHE_BLKSZ
Victor Stinner97b89882010-05-06 00:25:39 +00006360 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006361#endif
6362#ifdef _SC_ICACHE_LINESZ
Victor Stinner97b89882010-05-06 00:25:39 +00006363 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006364#endif
6365#ifdef _SC_ICACHE_SZ
Victor Stinner97b89882010-05-06 00:25:39 +00006366 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006367#endif
Fred Draked86ed291999-12-15 15:34:33 +00006368#ifdef _SC_INF
Victor Stinner97b89882010-05-06 00:25:39 +00006369 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00006370#endif
Fred Drakec9680921999-12-13 16:37:25 +00006371#ifdef _SC_INT_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006372 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006373#endif
6374#ifdef _SC_INT_MIN
Victor Stinner97b89882010-05-06 00:25:39 +00006375 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006376#endif
6377#ifdef _SC_IOV_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006378 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006379#endif
Fred Draked86ed291999-12-15 15:34:33 +00006380#ifdef _SC_IP_SECOPTS
Victor Stinner97b89882010-05-06 00:25:39 +00006381 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00006382#endif
Fred Drakec9680921999-12-13 16:37:25 +00006383#ifdef _SC_JOB_CONTROL
Victor Stinner97b89882010-05-06 00:25:39 +00006384 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00006385#endif
Fred Draked86ed291999-12-15 15:34:33 +00006386#ifdef _SC_KERN_POINTERS
Victor Stinner97b89882010-05-06 00:25:39 +00006387 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00006388#endif
6389#ifdef _SC_KERN_SIM
Victor Stinner97b89882010-05-06 00:25:39 +00006390 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00006391#endif
Fred Drakec9680921999-12-13 16:37:25 +00006392#ifdef _SC_LINE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006393 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006394#endif
6395#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006396 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006397#endif
6398#ifdef _SC_LOGNAME_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006399 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006400#endif
6401#ifdef _SC_LONG_BIT
Victor Stinner97b89882010-05-06 00:25:39 +00006402 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006403#endif
Fred Draked86ed291999-12-15 15:34:33 +00006404#ifdef _SC_MAC
Victor Stinner97b89882010-05-06 00:25:39 +00006405 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00006406#endif
Fred Drakec9680921999-12-13 16:37:25 +00006407#ifdef _SC_MAPPED_FILES
Victor Stinner97b89882010-05-06 00:25:39 +00006408 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00006409#endif
6410#ifdef _SC_MAXPID
Victor Stinner97b89882010-05-06 00:25:39 +00006411 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00006412#endif
6413#ifdef _SC_MB_LEN_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006414 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006415#endif
6416#ifdef _SC_MEMLOCK
Victor Stinner97b89882010-05-06 00:25:39 +00006417 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00006418#endif
6419#ifdef _SC_MEMLOCK_RANGE
Victor Stinner97b89882010-05-06 00:25:39 +00006420 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00006421#endif
6422#ifdef _SC_MEMORY_PROTECTION
Victor Stinner97b89882010-05-06 00:25:39 +00006423 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00006424#endif
6425#ifdef _SC_MESSAGE_PASSING
Victor Stinner97b89882010-05-06 00:25:39 +00006426 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00006427#endif
Fred Draked86ed291999-12-15 15:34:33 +00006428#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner97b89882010-05-06 00:25:39 +00006429 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00006430#endif
Fred Drakec9680921999-12-13 16:37:25 +00006431#ifdef _SC_MQ_OPEN_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006432 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006433#endif
6434#ifdef _SC_MQ_PRIO_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006435 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006436#endif
Fred Draked86ed291999-12-15 15:34:33 +00006437#ifdef _SC_NACLS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006438 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006439#endif
Fred Drakec9680921999-12-13 16:37:25 +00006440#ifdef _SC_NGROUPS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006441 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006442#endif
6443#ifdef _SC_NL_ARGMAX
Victor Stinner97b89882010-05-06 00:25:39 +00006444 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006445#endif
6446#ifdef _SC_NL_LANGMAX
Victor Stinner97b89882010-05-06 00:25:39 +00006447 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006448#endif
6449#ifdef _SC_NL_MSGMAX
Victor Stinner97b89882010-05-06 00:25:39 +00006450 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006451#endif
6452#ifdef _SC_NL_NMAX
Victor Stinner97b89882010-05-06 00:25:39 +00006453 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006454#endif
6455#ifdef _SC_NL_SETMAX
Victor Stinner97b89882010-05-06 00:25:39 +00006456 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006457#endif
6458#ifdef _SC_NL_TEXTMAX
Victor Stinner97b89882010-05-06 00:25:39 +00006459 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006460#endif
6461#ifdef _SC_NPROCESSORS_CONF
Victor Stinner97b89882010-05-06 00:25:39 +00006462 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00006463#endif
6464#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner97b89882010-05-06 00:25:39 +00006465 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00006466#endif
Fred Draked86ed291999-12-15 15:34:33 +00006467#ifdef _SC_NPROC_CONF
Victor Stinner97b89882010-05-06 00:25:39 +00006468 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00006469#endif
6470#ifdef _SC_NPROC_ONLN
Victor Stinner97b89882010-05-06 00:25:39 +00006471 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00006472#endif
Fred Drakec9680921999-12-13 16:37:25 +00006473#ifdef _SC_NZERO
Victor Stinner97b89882010-05-06 00:25:39 +00006474 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00006475#endif
6476#ifdef _SC_OPEN_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006477 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006478#endif
6479#ifdef _SC_PAGESIZE
Victor Stinner97b89882010-05-06 00:25:39 +00006480 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006481#endif
6482#ifdef _SC_PAGE_SIZE
Victor Stinner97b89882010-05-06 00:25:39 +00006483 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006484#endif
6485#ifdef _SC_PASS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006486 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006487#endif
6488#ifdef _SC_PHYS_PAGES
Victor Stinner97b89882010-05-06 00:25:39 +00006489 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006490#endif
6491#ifdef _SC_PII
Victor Stinner97b89882010-05-06 00:25:39 +00006492 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00006493#endif
6494#ifdef _SC_PII_INTERNET
Victor Stinner97b89882010-05-06 00:25:39 +00006495 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00006496#endif
6497#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner97b89882010-05-06 00:25:39 +00006498 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00006499#endif
6500#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner97b89882010-05-06 00:25:39 +00006501 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00006502#endif
6503#ifdef _SC_PII_OSI
Victor Stinner97b89882010-05-06 00:25:39 +00006504 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00006505#endif
6506#ifdef _SC_PII_OSI_CLTS
Victor Stinner97b89882010-05-06 00:25:39 +00006507 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00006508#endif
6509#ifdef _SC_PII_OSI_COTS
Victor Stinner97b89882010-05-06 00:25:39 +00006510 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00006511#endif
6512#ifdef _SC_PII_OSI_M
Victor Stinner97b89882010-05-06 00:25:39 +00006513 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00006514#endif
6515#ifdef _SC_PII_SOCKET
Victor Stinner97b89882010-05-06 00:25:39 +00006516 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00006517#endif
6518#ifdef _SC_PII_XTI
Victor Stinner97b89882010-05-06 00:25:39 +00006519 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00006520#endif
6521#ifdef _SC_POLL
Victor Stinner97b89882010-05-06 00:25:39 +00006522 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00006523#endif
6524#ifdef _SC_PRIORITIZED_IO
Victor Stinner97b89882010-05-06 00:25:39 +00006525 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006526#endif
6527#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner97b89882010-05-06 00:25:39 +00006528 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00006529#endif
6530#ifdef _SC_REALTIME_SIGNALS
Victor Stinner97b89882010-05-06 00:25:39 +00006531 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00006532#endif
6533#ifdef _SC_RE_DUP_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006534 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006535#endif
6536#ifdef _SC_RTSIG_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006537 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006538#endif
6539#ifdef _SC_SAVED_IDS
Victor Stinner97b89882010-05-06 00:25:39 +00006540 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00006541#endif
6542#ifdef _SC_SCHAR_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006543 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006544#endif
6545#ifdef _SC_SCHAR_MIN
Victor Stinner97b89882010-05-06 00:25:39 +00006546 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006547#endif
6548#ifdef _SC_SELECT
Victor Stinner97b89882010-05-06 00:25:39 +00006549 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00006550#endif
6551#ifdef _SC_SEMAPHORES
Victor Stinner97b89882010-05-06 00:25:39 +00006552 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00006553#endif
6554#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006555 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006556#endif
6557#ifdef _SC_SEM_VALUE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006558 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006559#endif
6560#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner97b89882010-05-06 00:25:39 +00006561 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00006562#endif
6563#ifdef _SC_SHRT_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006564 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006565#endif
6566#ifdef _SC_SHRT_MIN
Victor Stinner97b89882010-05-06 00:25:39 +00006567 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006568#endif
6569#ifdef _SC_SIGQUEUE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006570 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006571#endif
6572#ifdef _SC_SIGRT_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006573 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006574#endif
6575#ifdef _SC_SIGRT_MIN
Victor Stinner97b89882010-05-06 00:25:39 +00006576 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006577#endif
Fred Draked86ed291999-12-15 15:34:33 +00006578#ifdef _SC_SOFTPOWER
Victor Stinner97b89882010-05-06 00:25:39 +00006579 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00006580#endif
Fred Drakec9680921999-12-13 16:37:25 +00006581#ifdef _SC_SPLIT_CACHE
Victor Stinner97b89882010-05-06 00:25:39 +00006582 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00006583#endif
6584#ifdef _SC_SSIZE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006585 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006586#endif
6587#ifdef _SC_STACK_PROT
Victor Stinner97b89882010-05-06 00:25:39 +00006588 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00006589#endif
6590#ifdef _SC_STREAM_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006591 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006592#endif
6593#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner97b89882010-05-06 00:25:39 +00006594 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006595#endif
6596#ifdef _SC_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00006597 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00006598#endif
6599#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner97b89882010-05-06 00:25:39 +00006600 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00006601#endif
6602#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner97b89882010-05-06 00:25:39 +00006603 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006604#endif
6605#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner97b89882010-05-06 00:25:39 +00006606 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00006607#endif
6608#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006609 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006610#endif
6611#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner97b89882010-05-06 00:25:39 +00006612 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00006613#endif
6614#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner97b89882010-05-06 00:25:39 +00006615 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00006616#endif
6617#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner97b89882010-05-06 00:25:39 +00006618 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00006619#endif
6620#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner97b89882010-05-06 00:25:39 +00006621 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00006622#endif
6623#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner97b89882010-05-06 00:25:39 +00006624 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00006625#endif
6626#ifdef _SC_THREAD_STACK_MIN
Victor Stinner97b89882010-05-06 00:25:39 +00006627 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006628#endif
6629#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006630 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006631#endif
6632#ifdef _SC_TIMERS
Victor Stinner97b89882010-05-06 00:25:39 +00006633 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00006634#endif
6635#ifdef _SC_TIMER_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006636 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006637#endif
6638#ifdef _SC_TTY_NAME_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006639 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006640#endif
6641#ifdef _SC_TZNAME_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006642 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006643#endif
6644#ifdef _SC_T_IOV_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006645 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006646#endif
6647#ifdef _SC_UCHAR_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006648 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006649#endif
6650#ifdef _SC_UINT_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006651 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006652#endif
6653#ifdef _SC_UIO_MAXIOV
Victor Stinner97b89882010-05-06 00:25:39 +00006654 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00006655#endif
6656#ifdef _SC_ULONG_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006657 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006658#endif
6659#ifdef _SC_USHRT_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006660 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006661#endif
6662#ifdef _SC_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006663 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006664#endif
6665#ifdef _SC_WORD_BIT
Victor Stinner97b89882010-05-06 00:25:39 +00006666 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006667#endif
6668#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner97b89882010-05-06 00:25:39 +00006669 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00006670#endif
6671#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner97b89882010-05-06 00:25:39 +00006672 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00006673#endif
6674#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner97b89882010-05-06 00:25:39 +00006675 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00006676#endif
6677#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner97b89882010-05-06 00:25:39 +00006678 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00006679#endif
6680#ifdef _SC_XOPEN_CRYPT
Victor Stinner97b89882010-05-06 00:25:39 +00006681 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00006682#endif
6683#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner97b89882010-05-06 00:25:39 +00006684 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00006685#endif
6686#ifdef _SC_XOPEN_LEGACY
Victor Stinner97b89882010-05-06 00:25:39 +00006687 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00006688#endif
6689#ifdef _SC_XOPEN_REALTIME
Victor Stinner97b89882010-05-06 00:25:39 +00006690 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00006691#endif
6692#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00006693 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00006694#endif
6695#ifdef _SC_XOPEN_SHM
Victor Stinner97b89882010-05-06 00:25:39 +00006696 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00006697#endif
6698#ifdef _SC_XOPEN_UNIX
Victor Stinner97b89882010-05-06 00:25:39 +00006699 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00006700#endif
6701#ifdef _SC_XOPEN_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006702 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006703#endif
6704#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006705 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006706#endif
6707#ifdef _SC_XOPEN_XPG2
Victor Stinner97b89882010-05-06 00:25:39 +00006708 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00006709#endif
6710#ifdef _SC_XOPEN_XPG3
Victor Stinner97b89882010-05-06 00:25:39 +00006711 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00006712#endif
6713#ifdef _SC_XOPEN_XPG4
Victor Stinner97b89882010-05-06 00:25:39 +00006714 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00006715#endif
6716};
6717
6718static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006719conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006720{
6721 return conv_confname(arg, valuep, posix_constants_sysconf,
6722 sizeof(posix_constants_sysconf)
6723 / sizeof(struct constdef));
6724}
6725
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006726PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006727"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006728Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006729
6730static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006731posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006732{
6733 PyObject *result = NULL;
6734 int name;
6735
6736 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6737 int value;
6738
6739 errno = 0;
6740 value = sysconf(name);
6741 if (value == -1 && errno != 0)
6742 posix_error();
6743 else
Christian Heimes217cfd12007-12-02 14:31:20 +00006744 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00006745 }
6746 return result;
6747}
6748#endif
6749
6750
Fred Drakebec628d1999-12-15 18:31:10 +00006751/* This code is used to ensure that the tables of configuration value names
6752 * are in sorted order as required by conv_confname(), and also to build the
6753 * the exported dictionaries that are used to publish information about the
6754 * names available on the host platform.
6755 *
6756 * Sorting the table at runtime ensures that the table is properly ordered
6757 * when used, even for platforms we're not able to test on. It also makes
6758 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006759 */
Fred Drakebec628d1999-12-15 18:31:10 +00006760
6761static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006762cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006763{
6764 const struct constdef *c1 =
Victor Stinner97b89882010-05-06 00:25:39 +00006765 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00006766 const struct constdef *c2 =
Victor Stinner97b89882010-05-06 00:25:39 +00006767 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00006768
6769 return strcmp(c1->name, c2->name);
6770}
6771
6772static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006773setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner97b89882010-05-06 00:25:39 +00006774 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006775{
Fred Drakebec628d1999-12-15 18:31:10 +00006776 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006777 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006778
6779 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6780 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006781 if (d == NULL)
Victor Stinner97b89882010-05-06 00:25:39 +00006782 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006783
Barry Warsaw3155db32000-04-13 15:20:40 +00006784 for (i=0; i < tablesize; ++i) {
Victor Stinner97b89882010-05-06 00:25:39 +00006785 PyObject *o = PyLong_FromLong(table[i].value);
6786 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6787 Py_XDECREF(o);
6788 Py_DECREF(d);
6789 return -1;
6790 }
6791 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006792 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006793 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006794}
6795
Fred Drakebec628d1999-12-15 18:31:10 +00006796/* Return -1 on failure, 0 on success. */
6797static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006798setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006799{
6800#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006801 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006802 sizeof(posix_constants_pathconf)
6803 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006804 "pathconf_names", module))
Stefan Krah67733312010-11-26 17:04:40 +00006805 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006806#endif
6807#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006808 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006809 sizeof(posix_constants_confstr)
6810 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006811 "confstr_names", module))
Stefan Krah67733312010-11-26 17:04:40 +00006812 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006813#endif
6814#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006815 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006816 sizeof(posix_constants_sysconf)
6817 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006818 "sysconf_names", module))
Stefan Krah67733312010-11-26 17:04:40 +00006819 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006820#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006821 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006822}
Fred Draked86ed291999-12-15 15:34:33 +00006823
6824
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006825PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006826"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006827Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006828in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006829
6830static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006831posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006832{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006833 abort();
6834 /*NOTREACHED*/
6835 Py_FatalError("abort() called from Python code didn't abort!");
6836 return NULL;
6837}
Fred Drakebec628d1999-12-15 18:31:10 +00006838
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006839#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006840PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00006841"startfile(filepath [, operation]) - Start a file with its associated\n\
6842application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006843\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00006844When \"operation\" is not specified or \"open\", this acts like\n\
6845double-clicking the file in Explorer, or giving the file name as an\n\
6846argument to the DOS \"start\" command: the file is opened with whatever\n\
6847application (if any) its extension is associated.\n\
6848When another \"operation\" is given, it specifies what should be done with\n\
6849the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006850\n\
6851startfile returns as soon as the associated application is launched.\n\
6852There is no option to wait for the application to close, and no way\n\
6853to retrieve the application's exit status.\n\
6854\n\
6855The filepath is relative to the current directory. If you want to use\n\
6856an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006857the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006858
6859static PyObject *
6860win32_startfile(PyObject *self, PyObject *args)
6861{
Victor Stinner97b89882010-05-06 00:25:39 +00006862 PyObject *ofilepath;
6863 char *filepath;
6864 char *operation = NULL;
6865 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00006866
Victor Stinner97b89882010-05-06 00:25:39 +00006867 if (unicode_file_names()) {
6868 PyObject *unipath, *woperation = NULL;
6869 if (!PyArg_ParseTuple(args, "U|s:startfile",
6870 &unipath, &operation)) {
6871 PyErr_Clear();
6872 goto normal;
6873 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006874
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006875
Victor Stinner97b89882010-05-06 00:25:39 +00006876 if (operation) {
6877 woperation = PyUnicode_DecodeASCII(operation,
6878 strlen(operation), NULL);
6879 if (!woperation) {
6880 PyErr_Clear();
6881 operation = NULL;
6882 goto normal;
6883 }
6884 }
6885
6886 Py_BEGIN_ALLOW_THREADS
6887 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
6888 PyUnicode_AS_UNICODE(unipath),
6889 NULL, NULL, SW_SHOWNORMAL);
6890 Py_END_ALLOW_THREADS
6891
6892 Py_XDECREF(woperation);
6893 if (rc <= (HINSTANCE)32) {
6894 PyObject *errval = win32_error_unicode("startfile",
6895 PyUnicode_AS_UNICODE(unipath));
6896 return errval;
6897 }
6898 Py_INCREF(Py_None);
6899 return Py_None;
6900 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006901
6902normal:
Victor Stinner97b89882010-05-06 00:25:39 +00006903 if (!PyArg_ParseTuple(args, "O&|s:startfile",
6904 PyUnicode_FSConverter, &ofilepath,
6905 &operation))
6906 return NULL;
6907 filepath = bytes2str(ofilepath, 1);
6908 Py_BEGIN_ALLOW_THREADS
6909 rc = ShellExecute((HWND)0, operation, filepath,
6910 NULL, NULL, SW_SHOWNORMAL);
6911 Py_END_ALLOW_THREADS
6912 if (rc <= (HINSTANCE)32) {
6913 PyObject *errval = win32_error("startfile", filepath);
6914 release_bytes(ofilepath);
6915 return errval;
6916 }
6917 release_bytes(ofilepath);
6918 Py_INCREF(Py_None);
6919 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00006920}
6921#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006922
Martin v. Löwis438b5342002-12-27 10:16:42 +00006923#ifdef HAVE_GETLOADAVG
6924PyDoc_STRVAR(posix_getloadavg__doc__,
6925"getloadavg() -> (float, float, float)\n\n\
6926Return the number of processes in the system run queue averaged over\n\
6927the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6928was unobtainable");
6929
6930static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006931posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006932{
6933 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006934 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah67733312010-11-26 17:04:40 +00006935 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6936 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00006937 } else
Stefan Krah67733312010-11-26 17:04:40 +00006938 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00006939}
6940#endif
6941
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006942#ifdef MS_WINDOWS
6943
6944PyDoc_STRVAR(win32_urandom__doc__,
6945"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006946Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006947
6948typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
6949 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
6950 DWORD dwFlags );
6951typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
6952 BYTE *pbBuffer );
6953
6954static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00006955/* This handle is never explicitly released. Instead, the operating
6956 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006957static HCRYPTPROV hCryptProv = 0;
6958
Tim Peters4ad82172004-08-30 17:02:04 +00006959static PyObject*
6960win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006961{
Victor Stinner97b89882010-05-06 00:25:39 +00006962 int howMany;
6963 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006964
Victor Stinner97b89882010-05-06 00:25:39 +00006965 /* Read arguments */
6966 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
6967 return NULL;
6968 if (howMany < 0)
6969 return PyErr_Format(PyExc_ValueError,
6970 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006971
Victor Stinner97b89882010-05-06 00:25:39 +00006972 if (hCryptProv == 0) {
6973 HINSTANCE hAdvAPI32 = NULL;
6974 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006975
Victor Stinner97b89882010-05-06 00:25:39 +00006976 /* Obtain handle to the DLL containing CryptoAPI
6977 This should not fail */
6978 hAdvAPI32 = GetModuleHandle("advapi32.dll");
6979 if(hAdvAPI32 == NULL)
6980 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006981
Victor Stinner97b89882010-05-06 00:25:39 +00006982 /* Obtain pointers to the CryptoAPI functions
6983 This will fail on some early versions of Win95 */
6984 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
6985 hAdvAPI32,
6986 "CryptAcquireContextA");
6987 if (pCryptAcquireContext == NULL)
6988 return PyErr_Format(PyExc_NotImplementedError,
6989 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006990
Victor Stinner97b89882010-05-06 00:25:39 +00006991 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
6992 hAdvAPI32, "CryptGenRandom");
6993 if (pCryptGenRandom == NULL)
6994 return PyErr_Format(PyExc_NotImplementedError,
6995 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006996
Victor Stinner97b89882010-05-06 00:25:39 +00006997 /* Acquire context */
6998 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
6999 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7000 return win32_error("CryptAcquireContext", NULL);
7001 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007002
Victor Stinner97b89882010-05-06 00:25:39 +00007003 /* Allocate bytes */
7004 result = PyBytes_FromStringAndSize(NULL, howMany);
7005 if (result != NULL) {
7006 /* Get random data */
7007 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
7008 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7009 PyBytes_AS_STRING(result))) {
7010 Py_DECREF(result);
7011 return win32_error("CryptGenRandom", NULL);
7012 }
7013 }
7014 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007015}
7016#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007017
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007018PyDoc_STRVAR(device_encoding__doc__,
7019"device_encoding(fd) -> str\n\n\
7020Return a string describing the encoding of the device\n\
7021if the output is a terminal; else return None.");
7022
7023static PyObject *
7024device_encoding(PyObject *self, PyObject *args)
7025{
Victor Stinner97b89882010-05-06 00:25:39 +00007026 int fd;
7027 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
7028 return NULL;
7029 if (!_PyVerify_fd(fd) || !isatty(fd)) {
7030 Py_INCREF(Py_None);
7031 return Py_None;
7032 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007033#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner97b89882010-05-06 00:25:39 +00007034 if (fd == 0) {
7035 char buf[100];
7036 sprintf(buf, "cp%d", GetConsoleCP());
7037 return PyUnicode_FromString(buf);
7038 }
7039 if (fd == 1 || fd == 2) {
7040 char buf[100];
7041 sprintf(buf, "cp%d", GetConsoleOutputCP());
7042 return PyUnicode_FromString(buf);
7043 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007044#elif defined(CODESET)
Victor Stinner97b89882010-05-06 00:25:39 +00007045 {
7046 char *codeset = nl_langinfo(CODESET);
7047 if (codeset != NULL && codeset[0] != 0)
7048 return PyUnicode_FromString(codeset);
7049 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007050#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007051 Py_INCREF(Py_None);
7052 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007053}
7054
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007055#ifdef __VMS
7056/* Use openssl random routine */
7057#include <openssl/rand.h>
7058PyDoc_STRVAR(vms_urandom__doc__,
7059"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007060Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007061
7062static PyObject*
7063vms_urandom(PyObject *self, PyObject *args)
7064{
Victor Stinner97b89882010-05-06 00:25:39 +00007065 int howMany;
7066 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007067
Victor Stinner97b89882010-05-06 00:25:39 +00007068 /* Read arguments */
7069 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7070 return NULL;
7071 if (howMany < 0)
7072 return PyErr_Format(PyExc_ValueError,
7073 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007074
Victor Stinner97b89882010-05-06 00:25:39 +00007075 /* Allocate bytes */
7076 result = PyBytes_FromStringAndSize(NULL, howMany);
7077 if (result != NULL) {
7078 /* Get random data */
7079 if (RAND_pseudo_bytes((unsigned char*)
7080 PyBytes_AS_STRING(result),
7081 howMany) < 0) {
7082 Py_DECREF(result);
7083 return PyErr_Format(PyExc_ValueError,
7084 "RAND_pseudo_bytes");
7085 }
7086 }
7087 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007088}
7089#endif
7090
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007091static PyMethodDef posix_methods[] = {
Victor Stinner97b89882010-05-06 00:25:39 +00007092 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007093#ifdef HAVE_TTYNAME
Victor Stinner97b89882010-05-06 00:25:39 +00007094 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007095#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007096 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007097#ifdef HAVE_CHFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00007098 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007099#endif /* HAVE_CHFLAGS */
Victor Stinner97b89882010-05-06 00:25:39 +00007100 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007101#ifdef HAVE_FCHMOD
Victor Stinner97b89882010-05-06 00:25:39 +00007102 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007103#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007104#ifdef HAVE_CHOWN
Victor Stinner97b89882010-05-06 00:25:39 +00007105 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007106#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00007107#ifdef HAVE_LCHMOD
Victor Stinner97b89882010-05-06 00:25:39 +00007108 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007109#endif /* HAVE_LCHMOD */
7110#ifdef HAVE_FCHOWN
Victor Stinner97b89882010-05-06 00:25:39 +00007111 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007112#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00007113#ifdef HAVE_LCHFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00007114 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007115#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007116#ifdef HAVE_LCHOWN
Victor Stinner97b89882010-05-06 00:25:39 +00007117 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007118#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007119#ifdef HAVE_CHROOT
Victor Stinner97b89882010-05-06 00:25:39 +00007120 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00007121#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007122#ifdef HAVE_CTERMID
Victor Stinner97b89882010-05-06 00:25:39 +00007123 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007124#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007125#ifdef HAVE_GETCWD
Victor Stinner97b89882010-05-06 00:25:39 +00007126 {"getcwd", (PyCFunction)posix_getcwd_unicode,
7127 METH_NOARGS, posix_getcwd__doc__},
7128 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
7129 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007130#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007131#ifdef HAVE_LINK
Victor Stinner97b89882010-05-06 00:25:39 +00007132 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007133#endif /* HAVE_LINK */
Victor Stinner97b89882010-05-06 00:25:39 +00007134 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7135 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7136 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007137#ifdef HAVE_NICE
Victor Stinner97b89882010-05-06 00:25:39 +00007138 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007139#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007140#ifdef HAVE_READLINK
Victor Stinner97b89882010-05-06 00:25:39 +00007141 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007142#endif /* HAVE_READLINK */
Victor Stinner97b89882010-05-06 00:25:39 +00007143 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7144 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7145 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
7146 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007147#ifdef HAVE_SYMLINK
Victor Stinner97b89882010-05-06 00:25:39 +00007148 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007149#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007150#ifdef HAVE_SYSTEM
Victor Stinner97b89882010-05-06 00:25:39 +00007151 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007152#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007153 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007154#ifdef HAVE_UNAME
Victor Stinner97b89882010-05-06 00:25:39 +00007155 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007156#endif /* HAVE_UNAME */
Victor Stinner97b89882010-05-06 00:25:39 +00007157 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7158 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7159 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007160#ifdef HAVE_TIMES
Victor Stinner97b89882010-05-06 00:25:39 +00007161 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007162#endif /* HAVE_TIMES */
Victor Stinner97b89882010-05-06 00:25:39 +00007163 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007164#ifdef HAVE_EXECV
Victor Stinner97b89882010-05-06 00:25:39 +00007165 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7166 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007167#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007168#ifdef HAVE_SPAWNV
Victor Stinner97b89882010-05-06 00:25:39 +00007169 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7170 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007171#if defined(PYOS_OS2)
Victor Stinner97b89882010-05-06 00:25:39 +00007172 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7173 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007174#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007175#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007176#ifdef HAVE_FORK1
Victor Stinner97b89882010-05-06 00:25:39 +00007177 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007178#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007179#ifdef HAVE_FORK
Victor Stinner97b89882010-05-06 00:25:39 +00007180 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007181#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007182#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner97b89882010-05-06 00:25:39 +00007183 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007184#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007185#ifdef HAVE_FORKPTY
Victor Stinner97b89882010-05-06 00:25:39 +00007186 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007187#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007188#ifdef HAVE_GETEGID
Victor Stinner97b89882010-05-06 00:25:39 +00007189 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007190#endif /* HAVE_GETEGID */
7191#ifdef HAVE_GETEUID
Victor Stinner97b89882010-05-06 00:25:39 +00007192 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007193#endif /* HAVE_GETEUID */
7194#ifdef HAVE_GETGID
Victor Stinner97b89882010-05-06 00:25:39 +00007195 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007196#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007197#ifdef HAVE_GETGROUPS
Victor Stinner97b89882010-05-06 00:25:39 +00007198 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007199#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007200 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007201#ifdef HAVE_GETPGRP
Victor Stinner97b89882010-05-06 00:25:39 +00007202 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007203#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007204#ifdef HAVE_GETPPID
Victor Stinner97b89882010-05-06 00:25:39 +00007205 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007206#endif /* HAVE_GETPPID */
7207#ifdef HAVE_GETUID
Victor Stinner97b89882010-05-06 00:25:39 +00007208 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007209#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007210#ifdef HAVE_GETLOGIN
Victor Stinner97b89882010-05-06 00:25:39 +00007211 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007212#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007213#ifdef HAVE_KILL
Victor Stinner97b89882010-05-06 00:25:39 +00007214 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007215#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007216#ifdef HAVE_KILLPG
Victor Stinner97b89882010-05-06 00:25:39 +00007217 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007218#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007219#ifdef HAVE_PLOCK
Victor Stinner97b89882010-05-06 00:25:39 +00007220 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007221#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007222#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00007223 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +00007224#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007225#ifdef HAVE_SETUID
Victor Stinner97b89882010-05-06 00:25:39 +00007226 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007227#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007228#ifdef HAVE_SETEUID
Victor Stinner97b89882010-05-06 00:25:39 +00007229 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007230#endif /* HAVE_SETEUID */
7231#ifdef HAVE_SETEGID
Victor Stinner97b89882010-05-06 00:25:39 +00007232 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007233#endif /* HAVE_SETEGID */
7234#ifdef HAVE_SETREUID
Victor Stinner97b89882010-05-06 00:25:39 +00007235 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007236#endif /* HAVE_SETREUID */
7237#ifdef HAVE_SETREGID
Victor Stinner97b89882010-05-06 00:25:39 +00007238 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007239#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007240#ifdef HAVE_SETGID
Victor Stinner97b89882010-05-06 00:25:39 +00007241 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007242#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007243#ifdef HAVE_SETGROUPS
Victor Stinner97b89882010-05-06 00:25:39 +00007244 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007245#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007246#ifdef HAVE_GETPGID
Victor Stinner97b89882010-05-06 00:25:39 +00007247 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00007248#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007249#ifdef HAVE_SETPGRP
Victor Stinner97b89882010-05-06 00:25:39 +00007250 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007251#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007252#ifdef HAVE_WAIT
Victor Stinner97b89882010-05-06 00:25:39 +00007253 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007254#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007255#ifdef HAVE_WAIT3
Victor Stinner97b89882010-05-06 00:25:39 +00007256 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007257#endif /* HAVE_WAIT3 */
7258#ifdef HAVE_WAIT4
Victor Stinner97b89882010-05-06 00:25:39 +00007259 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007260#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007261#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner97b89882010-05-06 00:25:39 +00007262 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007263#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007264#ifdef HAVE_GETSID
Victor Stinner97b89882010-05-06 00:25:39 +00007265 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007266#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007267#ifdef HAVE_SETSID
Victor Stinner97b89882010-05-06 00:25:39 +00007268 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007269#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007270#ifdef HAVE_SETPGID
Victor Stinner97b89882010-05-06 00:25:39 +00007271 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007272#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007273#ifdef HAVE_TCGETPGRP
Victor Stinner97b89882010-05-06 00:25:39 +00007274 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007275#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007276#ifdef HAVE_TCSETPGRP
Victor Stinner97b89882010-05-06 00:25:39 +00007277 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007278#endif /* HAVE_TCSETPGRP */
Victor Stinner97b89882010-05-06 00:25:39 +00007279 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7280 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7281 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
7282 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
7283 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7284 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7285 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7286 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7287 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7288 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7289 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007290#ifdef HAVE_PIPE
Victor Stinner97b89882010-05-06 00:25:39 +00007291 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007292#endif
7293#ifdef HAVE_MKFIFO
Victor Stinner97b89882010-05-06 00:25:39 +00007294 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007295#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007296#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner97b89882010-05-06 00:25:39 +00007297 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007298#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007299#ifdef HAVE_DEVICE_MACROS
Victor Stinner97b89882010-05-06 00:25:39 +00007300 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7301 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7302 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007303#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007304#ifdef HAVE_FTRUNCATE
Victor Stinner97b89882010-05-06 00:25:39 +00007305 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007306#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007307#ifdef HAVE_PUTENV
Victor Stinner97b89882010-05-06 00:25:39 +00007308 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007309#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007310#ifdef HAVE_UNSETENV
Victor Stinner97b89882010-05-06 00:25:39 +00007311 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00007312#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007313 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007314#ifdef HAVE_FCHDIR
Victor Stinner97b89882010-05-06 00:25:39 +00007315 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007316#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007317#ifdef HAVE_FSYNC
Victor Stinner97b89882010-05-06 00:25:39 +00007318 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007319#endif
7320#ifdef HAVE_FDATASYNC
Victor Stinner97b89882010-05-06 00:25:39 +00007321 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007322#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007323#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007324#ifdef WCOREDUMP
Victor Stinner97b89882010-05-06 00:25:39 +00007325 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00007326#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007327#ifdef WIFCONTINUED
Victor Stinner97b89882010-05-06 00:25:39 +00007328 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007329#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007330#ifdef WIFSTOPPED
Victor Stinner97b89882010-05-06 00:25:39 +00007331 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007332#endif /* WIFSTOPPED */
7333#ifdef WIFSIGNALED
Victor Stinner97b89882010-05-06 00:25:39 +00007334 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007335#endif /* WIFSIGNALED */
7336#ifdef WIFEXITED
Victor Stinner97b89882010-05-06 00:25:39 +00007337 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007338#endif /* WIFEXITED */
7339#ifdef WEXITSTATUS
Victor Stinner97b89882010-05-06 00:25:39 +00007340 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007341#endif /* WEXITSTATUS */
7342#ifdef WTERMSIG
Victor Stinner97b89882010-05-06 00:25:39 +00007343 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007344#endif /* WTERMSIG */
7345#ifdef WSTOPSIG
Victor Stinner97b89882010-05-06 00:25:39 +00007346 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007347#endif /* WSTOPSIG */
7348#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007349#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner97b89882010-05-06 00:25:39 +00007350 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007351#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007352#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner97b89882010-05-06 00:25:39 +00007353 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007354#endif
Fred Drakec9680921999-12-13 16:37:25 +00007355#ifdef HAVE_CONFSTR
Victor Stinner97b89882010-05-06 00:25:39 +00007356 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007357#endif
7358#ifdef HAVE_SYSCONF
Victor Stinner97b89882010-05-06 00:25:39 +00007359 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007360#endif
7361#ifdef HAVE_FPATHCONF
Victor Stinner97b89882010-05-06 00:25:39 +00007362 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007363#endif
7364#ifdef HAVE_PATHCONF
Victor Stinner97b89882010-05-06 00:25:39 +00007365 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007366#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007367 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007368#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00007369 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Mark Hammondef8b6542001-05-13 08:04:26 +00007370#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007371#ifdef HAVE_GETLOADAVG
Victor Stinner97b89882010-05-06 00:25:39 +00007372 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007373#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007374 #ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00007375 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007376 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007377 #ifdef __VMS
Victor Stinner97b89882010-05-06 00:25:39 +00007378 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007379 #endif
Victor Stinner97b89882010-05-06 00:25:39 +00007380 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007381};
7382
7383
Barry Warsaw4a342091996-12-19 23:50:02 +00007384static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007385ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007386{
Victor Stinner97b89882010-05-06 00:25:39 +00007387 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007388}
7389
Guido van Rossumd48f2521997-12-05 22:19:34 +00007390#if defined(PYOS_OS2)
7391/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007392static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007393{
7394 APIRET rc;
7395 ULONG values[QSV_MAX+1];
7396 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007397 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007398
7399 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007400 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007401 Py_END_ALLOW_THREADS
7402
7403 if (rc != NO_ERROR) {
7404 os2_error(rc);
7405 return -1;
7406 }
7407
Fred Drake4d1e64b2002-04-15 19:40:07 +00007408 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7409 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7410 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7411 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7412 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7413 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7414 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007415
7416 switch (values[QSV_VERSION_MINOR]) {
7417 case 0: ver = "2.00"; break;
7418 case 10: ver = "2.10"; break;
7419 case 11: ver = "2.11"; break;
7420 case 30: ver = "3.00"; break;
7421 case 40: ver = "4.00"; break;
7422 case 50: ver = "5.00"; break;
7423 default:
Tim Peters885d4572001-11-28 20:27:42 +00007424 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner97b89882010-05-06 00:25:39 +00007425 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00007426 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007427 ver = &tmp[0];
7428 }
7429
7430 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007431 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007432 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007433
7434 /* Add Indicator of Which Drive was Used to Boot the System */
7435 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7436 tmp[1] = ':';
7437 tmp[2] = '\0';
7438
Fred Drake4d1e64b2002-04-15 19:40:07 +00007439 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007440}
7441#endif
7442
Barry Warsaw4a342091996-12-19 23:50:02 +00007443static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007444all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007445{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007446#ifdef F_OK
Victor Stinner97b89882010-05-06 00:25:39 +00007447 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007448#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007449#ifdef R_OK
Victor Stinner97b89882010-05-06 00:25:39 +00007450 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007451#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007452#ifdef W_OK
Victor Stinner97b89882010-05-06 00:25:39 +00007453 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007454#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007455#ifdef X_OK
Victor Stinner97b89882010-05-06 00:25:39 +00007456 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007457#endif
Fred Drakec9680921999-12-13 16:37:25 +00007458#ifdef NGROUPS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00007459 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00007460#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007461#ifdef TMP_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00007462 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007463#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007464#ifdef WCONTINUED
Victor Stinner97b89882010-05-06 00:25:39 +00007465 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00007466#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007467#ifdef WNOHANG
Victor Stinner97b89882010-05-06 00:25:39 +00007468 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007469#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007470#ifdef WUNTRACED
Victor Stinner97b89882010-05-06 00:25:39 +00007471 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00007472#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007473#ifdef O_RDONLY
Victor Stinner97b89882010-05-06 00:25:39 +00007474 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007475#endif
7476#ifdef O_WRONLY
Victor Stinner97b89882010-05-06 00:25:39 +00007477 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007478#endif
7479#ifdef O_RDWR
Victor Stinner97b89882010-05-06 00:25:39 +00007480 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007481#endif
7482#ifdef O_NDELAY
Victor Stinner97b89882010-05-06 00:25:39 +00007483 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007484#endif
7485#ifdef O_NONBLOCK
Victor Stinner97b89882010-05-06 00:25:39 +00007486 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007487#endif
7488#ifdef O_APPEND
Victor Stinner97b89882010-05-06 00:25:39 +00007489 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007490#endif
7491#ifdef O_DSYNC
Victor Stinner97b89882010-05-06 00:25:39 +00007492 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007493#endif
7494#ifdef O_RSYNC
Victor Stinner97b89882010-05-06 00:25:39 +00007495 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007496#endif
7497#ifdef O_SYNC
Victor Stinner97b89882010-05-06 00:25:39 +00007498 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007499#endif
7500#ifdef O_NOCTTY
Victor Stinner97b89882010-05-06 00:25:39 +00007501 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007502#endif
7503#ifdef O_CREAT
Victor Stinner97b89882010-05-06 00:25:39 +00007504 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007505#endif
7506#ifdef O_EXCL
Victor Stinner97b89882010-05-06 00:25:39 +00007507 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007508#endif
7509#ifdef O_TRUNC
Victor Stinner97b89882010-05-06 00:25:39 +00007510 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007511#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007512#ifdef O_BINARY
Victor Stinner97b89882010-05-06 00:25:39 +00007513 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00007514#endif
7515#ifdef O_TEXT
Victor Stinner97b89882010-05-06 00:25:39 +00007516 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00007517#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007518#ifdef O_LARGEFILE
Victor Stinner97b89882010-05-06 00:25:39 +00007519 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007520#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007521#ifdef O_SHLOCK
Victor Stinner97b89882010-05-06 00:25:39 +00007522 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00007523#endif
7524#ifdef O_EXLOCK
Victor Stinner97b89882010-05-06 00:25:39 +00007525 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00007526#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007527
Tim Peters5aa91602002-01-30 05:46:57 +00007528/* MS Windows */
7529#ifdef O_NOINHERIT
Victor Stinner97b89882010-05-06 00:25:39 +00007530 /* Don't inherit in child processes. */
7531 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007532#endif
7533#ifdef _O_SHORT_LIVED
Victor Stinner97b89882010-05-06 00:25:39 +00007534 /* Optimize for short life (keep in memory). */
7535 /* MS forgot to define this one with a non-underscore form too. */
7536 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007537#endif
7538#ifdef O_TEMPORARY
Victor Stinner97b89882010-05-06 00:25:39 +00007539 /* Automatically delete when last handle is closed. */
7540 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007541#endif
7542#ifdef O_RANDOM
Victor Stinner97b89882010-05-06 00:25:39 +00007543 /* Optimize for random access. */
7544 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007545#endif
7546#ifdef O_SEQUENTIAL
Victor Stinner97b89882010-05-06 00:25:39 +00007547 /* Optimize for sequential access. */
7548 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007549#endif
7550
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007551/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00007552#ifdef O_ASYNC
Victor Stinner97b89882010-05-06 00:25:39 +00007553 /* Send a SIGIO signal whenever input or output
7554 becomes available on file descriptor */
7555 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +00007556#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007557#ifdef O_DIRECT
Victor Stinner97b89882010-05-06 00:25:39 +00007558 /* Direct disk access. */
7559 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007560#endif
7561#ifdef O_DIRECTORY
Victor Stinner97b89882010-05-06 00:25:39 +00007562 /* Must be a directory. */
7563 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007564#endif
7565#ifdef O_NOFOLLOW
Victor Stinner97b89882010-05-06 00:25:39 +00007566 /* Do not follow links. */
7567 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007568#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00007569#ifdef O_NOATIME
Victor Stinner97b89882010-05-06 00:25:39 +00007570 /* Do not update the access time. */
7571 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00007572#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007573
Victor Stinner97b89882010-05-06 00:25:39 +00007574 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007575#ifdef EX_OK
Victor Stinner97b89882010-05-06 00:25:39 +00007576 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007577#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007578#ifdef EX_USAGE
Victor Stinner97b89882010-05-06 00:25:39 +00007579 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007580#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007581#ifdef EX_DATAERR
Victor Stinner97b89882010-05-06 00:25:39 +00007582 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007583#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007584#ifdef EX_NOINPUT
Victor Stinner97b89882010-05-06 00:25:39 +00007585 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007586#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007587#ifdef EX_NOUSER
Victor Stinner97b89882010-05-06 00:25:39 +00007588 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007589#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007590#ifdef EX_NOHOST
Victor Stinner97b89882010-05-06 00:25:39 +00007591 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007592#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007593#ifdef EX_UNAVAILABLE
Victor Stinner97b89882010-05-06 00:25:39 +00007594 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007595#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007596#ifdef EX_SOFTWARE
Victor Stinner97b89882010-05-06 00:25:39 +00007597 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007598#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007599#ifdef EX_OSERR
Victor Stinner97b89882010-05-06 00:25:39 +00007600 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007601#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007602#ifdef EX_OSFILE
Victor Stinner97b89882010-05-06 00:25:39 +00007603 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007604#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007605#ifdef EX_CANTCREAT
Victor Stinner97b89882010-05-06 00:25:39 +00007606 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007607#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007608#ifdef EX_IOERR
Victor Stinner97b89882010-05-06 00:25:39 +00007609 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007610#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007611#ifdef EX_TEMPFAIL
Victor Stinner97b89882010-05-06 00:25:39 +00007612 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007613#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007614#ifdef EX_PROTOCOL
Victor Stinner97b89882010-05-06 00:25:39 +00007615 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007616#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007617#ifdef EX_NOPERM
Victor Stinner97b89882010-05-06 00:25:39 +00007618 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007619#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007620#ifdef EX_CONFIG
Victor Stinner97b89882010-05-06 00:25:39 +00007621 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007622#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007623#ifdef EX_NOTFOUND
Victor Stinner97b89882010-05-06 00:25:39 +00007624 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007625#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007626
Guido van Rossum246bc171999-02-01 23:54:31 +00007627#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007628#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner97b89882010-05-06 00:25:39 +00007629 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7630 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7631 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7632 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7633 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7634 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7635 if (ins(d, "P_PM", (long)P_PM)) return -1;
7636 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7637 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7638 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7639 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7640 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7641 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7642 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7643 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7644 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7645 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7646 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7647 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7648 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007649#else
Victor Stinner97b89882010-05-06 00:25:39 +00007650 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7651 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7652 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7653 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7654 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007655#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007656#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007657
Guido van Rossumd48f2521997-12-05 22:19:34 +00007658#if defined(PYOS_OS2)
Victor Stinner97b89882010-05-06 00:25:39 +00007659 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007660#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007661 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00007662}
7663
7664
Tim Peters5aa91602002-01-30 05:46:57 +00007665#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007666#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007667#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007668
7669#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007670#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007671#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007672
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007673#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00007674#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007675#define MODNAME "posix"
7676#endif
7677
Martin v. Löwis1a214512008-06-11 05:26:20 +00007678static struct PyModuleDef posixmodule = {
Victor Stinner97b89882010-05-06 00:25:39 +00007679 PyModuleDef_HEAD_INIT,
7680 MODNAME,
7681 posix__doc__,
7682 -1,
7683 posix_methods,
7684 NULL,
7685 NULL,
7686 NULL,
7687 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00007688};
7689
7690
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007691PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007692INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007693{
Victor Stinner97b89882010-05-06 00:25:39 +00007694 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007695
Victor Stinner97b89882010-05-06 00:25:39 +00007696 m = PyModule_Create(&posixmodule);
7697 if (m == NULL)
7698 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007699
Victor Stinner97b89882010-05-06 00:25:39 +00007700 /* Initialize environ dictionary */
7701 v = convertenviron();
7702 Py_XINCREF(v);
7703 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
7704 return NULL;
7705 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007706
Victor Stinner97b89882010-05-06 00:25:39 +00007707 if (all_ins(m))
7708 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00007709
Victor Stinner97b89882010-05-06 00:25:39 +00007710 if (setup_confname_tables(m))
7711 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00007712
Victor Stinner97b89882010-05-06 00:25:39 +00007713 Py_INCREF(PyExc_OSError);
7714 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007715
Guido van Rossumb3d39562000-01-31 18:41:26 +00007716#ifdef HAVE_PUTENV
Victor Stinner97b89882010-05-06 00:25:39 +00007717 if (posix_putenv_garbage == NULL)
7718 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007719#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007720
Victor Stinner97b89882010-05-06 00:25:39 +00007721 if (!initialized) {
7722 stat_result_desc.name = MODNAME ".stat_result";
7723 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7724 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7725 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
7726 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
7727 structseq_new = StatResultType.tp_new;
7728 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007729
Victor Stinner97b89882010-05-06 00:25:39 +00007730 statvfs_result_desc.name = MODNAME ".statvfs_result";
7731 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007732#ifdef NEED_TICKS_PER_SECOND
7733# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner97b89882010-05-06 00:25:39 +00007734 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007735# elif defined(HZ)
Victor Stinner97b89882010-05-06 00:25:39 +00007736 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007737# else
Victor Stinner97b89882010-05-06 00:25:39 +00007738 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007739# endif
7740#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007741 }
7742 Py_INCREF((PyObject*) &StatResultType);
7743 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
7744 Py_INCREF((PyObject*) &StatVFSResultType);
7745 PyModule_AddObject(m, "statvfs_result",
7746 (PyObject*) &StatVFSResultType);
7747 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007748
7749#ifdef __APPLE__
Victor Stinner97b89882010-05-06 00:25:39 +00007750 /*
7751 * Step 2 of weak-linking support on Mac OS X.
7752 *
7753 * The code below removes functions that are not available on the
7754 * currently active platform.
7755 *
7756 * This block allow one to use a python binary that was build on
7757 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
7758 * OSX 10.4.
7759 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007760#ifdef HAVE_FSTATVFS
Victor Stinner97b89882010-05-06 00:25:39 +00007761 if (fstatvfs == NULL) {
7762 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
7763 return NULL;
7764 }
7765 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00007766#endif /* HAVE_FSTATVFS */
7767
7768#ifdef HAVE_STATVFS
Victor Stinner97b89882010-05-06 00:25:39 +00007769 if (statvfs == NULL) {
7770 if (PyObject_DelAttrString(m, "statvfs") == -1) {
7771 return NULL;
7772 }
7773 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00007774#endif /* HAVE_STATVFS */
7775
7776# ifdef HAVE_LCHOWN
Victor Stinner97b89882010-05-06 00:25:39 +00007777 if (lchown == NULL) {
7778 if (PyObject_DelAttrString(m, "lchown") == -1) {
7779 return NULL;
7780 }
7781 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00007782#endif /* HAVE_LCHOWN */
7783
7784
7785#endif /* __APPLE__ */
Victor Stinner97b89882010-05-06 00:25:39 +00007786 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007787
Guido van Rossumb6775db1994-08-01 11:34:53 +00007788}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007789
7790#ifdef __cplusplus
7791}
7792#endif