blob: a836af6cd05d272f2125a220c1edd0d44978bac2 [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
Antoine Pitrou710e9662011-01-19 15:26:37 +0000331#undef FSTAT
332#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000333#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner97b89882010-05-06 00:25:39 +0000334# define STAT win32_stat
335# define FSTAT win32_fstat
336# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000337#else
Victor Stinner97b89882010-05-06 00:25:39 +0000338# define STAT stat
339# define FSTAT fstat
340# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000341#endif
342
Tim Peters11b23062003-04-23 02:39:17 +0000343#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000344#include <sys/mkdev.h>
345#else
346#if defined(MAJOR_IN_SYSMACROS)
347#include <sys/sysmacros.h>
348#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000349#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
350#include <sys/mkdev.h>
351#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000352#endif
Fred Drake699f3522000-06-29 21:12:41 +0000353
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000354#if defined _MSC_VER && _MSC_VER >= 1400
355/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
356 * valid and throw an assertion if it isn't.
357 * Normally, an invalid fd is likely to be a C program error and therefore
358 * an assertion can be useful, but it does contradict the POSIX standard
359 * which for write(2) states:
360 * "Otherwise, -1 shall be returned and errno set to indicate the error."
361 * "[EBADF] The fildes argument is not a valid file descriptor open for
362 * writing."
363 * Furthermore, python allows the user to enter any old integer
364 * as a fd and should merely raise a python exception on error.
365 * The Microsoft CRT doesn't provide an official way to check for the
366 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner97b89882010-05-06 00:25:39 +0000367 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000368 * internal structures involved.
369 * The structures below must be updated for each version of visual studio
370 * according to the file internal.h in the CRT source, until MS comes
371 * up with a less hacky way to do this.
372 * (all of this is to avoid globally modifying the CRT behaviour using
373 * _set_invalid_parameter_handler() and _CrtSetReportMode())
374 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000375/* The actual size of the structure is determined at runtime.
376 * Only the first items must be present.
377 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000378typedef struct {
Victor Stinner97b89882010-05-06 00:25:39 +0000379 intptr_t osfhnd;
380 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000381} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000382
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000383extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000384#define IOINFO_L2E 5
385#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
386#define IOINFO_ARRAYS 64
387#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
388#define FOPEN 0x01
389#define _NO_CONSOLE_FILENO (intptr_t)-2
390
391/* This function emulates what the windows CRT does to validate file handles */
392int
393_PyVerify_fd(int fd)
394{
Victor Stinner97b89882010-05-06 00:25:39 +0000395 const int i1 = fd >> IOINFO_L2E;
396 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000397
Antoine Pitrou835b4452010-08-15 18:32:16 +0000398 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000399
Victor Stinner97b89882010-05-06 00:25:39 +0000400 /* Determine the actual size of the ioinfo structure,
401 * as used by the CRT loaded in memory
402 */
403 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
404 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
405 }
406 if (sizeof_ioinfo == 0) {
407 /* This should not happen... */
408 goto fail;
409 }
410
411 /* See that it isn't a special CLEAR fileno */
412 if (fd != _NO_CONSOLE_FILENO) {
413 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
414 * we check pointer validity and other info
415 */
416 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
417 /* finally, check that the file is open */
418 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
419 if (info->osfile & FOPEN) {
420 return 1;
421 }
422 }
423 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000424 fail:
Victor Stinner97b89882010-05-06 00:25:39 +0000425 errno = EBADF;
426 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000427}
428
429/* the special case of checking dup2. The target fd must be in a sensible range */
430static int
431_PyVerify_fd_dup2(int fd1, int fd2)
432{
Victor Stinner97b89882010-05-06 00:25:39 +0000433 if (!_PyVerify_fd(fd1))
434 return 0;
435 if (fd2 == _NO_CONSOLE_FILENO)
436 return 0;
437 if ((unsigned)fd2 < _NHANDLE_)
438 return 1;
439 else
440 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000441}
442#else
443/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
444#define _PyVerify_fd_dup2(A, B) (1)
445#endif
446
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000447/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000448#ifdef WITH_NEXT_FRAMEWORK
449/* On Darwin/MacOSX a shared library or framework has no access to
450** environ directly, we must obtain it with _NSGetEnviron().
451*/
452#include <crt_externs.h>
453static char **environ;
454#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000455extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000456#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000457
Barry Warsaw53699e91996-12-10 23:23:01 +0000458static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000459convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000460{
Victor Stinner97b89882010-05-06 00:25:39 +0000461 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000462#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +0000463 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000464#else
Victor Stinner97b89882010-05-06 00:25:39 +0000465 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000466#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000467#if defined(PYOS_OS2)
Victor Stinner97b89882010-05-06 00:25:39 +0000468 APIRET rc;
469 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
470#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000471
Victor Stinner97b89882010-05-06 00:25:39 +0000472 d = PyDict_New();
473 if (d == NULL)
474 return NULL;
475#ifdef WITH_NEXT_FRAMEWORK
476 if (environ == NULL)
477 environ = *_NSGetEnviron();
478#endif
479#ifdef MS_WINDOWS
480 /* _wenviron must be initialized in this way if the program is started
481 through main() instead of wmain(). */
482 _wgetenv(L"");
483 if (_wenviron == NULL)
484 return d;
485 /* This part ignores errors */
486 for (e = _wenviron; *e != NULL; e++) {
487 PyObject *k;
488 PyObject *v;
489 wchar_t *p = wcschr(*e, L'=');
490 if (p == NULL)
491 continue;
492 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
493 if (k == NULL) {
494 PyErr_Clear();
495 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000496 }
Victor Stinner97b89882010-05-06 00:25:39 +0000497 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
498 if (v == NULL) {
499 PyErr_Clear();
500 Py_DECREF(k);
501 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000502 }
Victor Stinner97b89882010-05-06 00:25:39 +0000503 if (PyDict_GetItem(d, k) == NULL) {
504 if (PyDict_SetItem(d, k, v) != 0)
505 PyErr_Clear();
506 }
507 Py_DECREF(k);
508 Py_DECREF(v);
509 }
510#else
511 if (environ == NULL)
512 return d;
513 /* This part ignores errors */
514 for (e = environ; *e != NULL; e++) {
515 PyObject *k;
516 PyObject *v;
517 char *p = strchr(*e, '=');
518 if (p == NULL)
519 continue;
520 k = PyUnicode_Decode(*e, (int)(p-*e),
521 Py_FileSystemDefaultEncoding, "surrogateescape");
522 if (k == NULL) {
523 PyErr_Clear();
524 continue;
525 }
526 v = PyUnicode_Decode(p+1, strlen(p+1),
527 Py_FileSystemDefaultEncoding, "surrogateescape");
528 if (v == NULL) {
529 PyErr_Clear();
530 Py_DECREF(k);
531 continue;
532 }
533 if (PyDict_GetItem(d, k) == NULL) {
534 if (PyDict_SetItem(d, k, v) != 0)
535 PyErr_Clear();
536 }
537 Py_DECREF(k);
538 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000539 }
540#endif
Victor Stinner97b89882010-05-06 00:25:39 +0000541#if defined(PYOS_OS2)
542 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
543 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
544 PyObject *v = PyBytes_FromString(buffer);
545 PyDict_SetItemString(d, "BEGINLIBPATH", v);
546 Py_DECREF(v);
547 }
548 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
549 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
550 PyObject *v = PyBytes_FromString(buffer);
551 PyDict_SetItemString(d, "ENDLIBPATH", v);
552 Py_DECREF(v);
553 }
554#endif
555 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000556}
557
Martin v. Löwis011e8422009-05-05 04:43:17 +0000558/* Convert a bytes object to a char*. Optionally lock the buffer if it is a
559 bytes array. */
560
561static char*
562bytes2str(PyObject* o, int lock)
563{
Victor Stinner97b89882010-05-06 00:25:39 +0000564 if(PyBytes_Check(o))
565 return PyBytes_AsString(o);
566 else if(PyByteArray_Check(o)) {
567 if (lock && PyObject_GetBuffer(o, NULL, 0) < 0)
568 /* On a bytearray, this should not fail. */
569 PyErr_BadInternalCall();
570 return PyByteArray_AsString(o);
571 } else {
572 /* The FS converter should have verified that this
573 is either bytes or bytearray. */
574 Py_FatalError("bad object passed to bytes2str");
575 /* not reached. */
576 return "";
577 }
Martin v. Löwis011e8422009-05-05 04:43:17 +0000578}
579
580/* Release the lock, decref the object. */
581static void
582release_bytes(PyObject* o)
583{
Victor Stinner97b89882010-05-06 00:25:39 +0000584 if (PyByteArray_Check(o))
585 o->ob_type->tp_as_buffer->bf_releasebuffer(o, 0);
586 Py_DECREF(o);
Martin v. Löwis011e8422009-05-05 04:43:17 +0000587}
588
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000589
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000590/* Set a POSIX-specific error from errno, and return NULL */
591
Barry Warsawd58d7641998-07-23 16:14:40 +0000592static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000593posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000594{
Victor Stinner97b89882010-05-06 00:25:39 +0000595 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000596}
Barry Warsawd58d7641998-07-23 16:14:40 +0000597static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000598posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000599{
Victor Stinner97b89882010-05-06 00:25:39 +0000600 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000601}
602
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000603#ifdef MS_WINDOWS
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000604static PyObject *
605posix_error_with_unicode_filename(Py_UNICODE* name)
606{
Victor Stinner97b89882010-05-06 00:25:39 +0000607 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000608}
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000609#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000610
611
Mark Hammondef8b6542001-05-13 08:04:26 +0000612static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000613posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000614{
Victor Stinner97b89882010-05-06 00:25:39 +0000615 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError,
616 bytes2str(name, 0));
617 release_bytes(name);
618 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000619}
620
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000621#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000622static PyObject *
623win32_error(char* function, char* filename)
624{
Victor Stinner97b89882010-05-06 00:25:39 +0000625 /* XXX We should pass the function name along in the future.
626 (winreg.c also wants to pass the function name.)
627 This would however require an additional param to the
628 Windows error object, which is non-trivial.
629 */
630 errno = GetLastError();
631 if (filename)
632 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
633 else
634 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000635}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000636
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000637static PyObject *
638win32_error_unicode(char* function, Py_UNICODE* filename)
639{
Victor Stinner97b89882010-05-06 00:25:39 +0000640 /* XXX - see win32_error for comments on 'function' */
641 errno = GetLastError();
642 if (filename)
643 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
644 else
645 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000646}
647
Thomas Wouters477c8d52006-05-27 19:21:47 +0000648static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000649convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000650{
Victor Stinner97b89882010-05-06 00:25:39 +0000651 if (PyUnicode_CheckExact(*param))
652 Py_INCREF(*param);
653 else if (PyUnicode_Check(*param))
654 /* For a Unicode subtype that's not a Unicode object,
655 return a true Unicode object with the same data. */
656 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
657 PyUnicode_GET_SIZE(*param));
658 else
659 *param = PyUnicode_FromEncodedObject(*param,
660 Py_FileSystemDefaultEncoding,
661 "strict");
662 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000663}
664
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000665#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000666
Guido van Rossumd48f2521997-12-05 22:19:34 +0000667#if defined(PYOS_OS2)
668/**********************************************************************
669 * Helper Function to Trim and Format OS/2 Messages
670 **********************************************************************/
Victor Stinner97b89882010-05-06 00:25:39 +0000671static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000672os2_formatmsg(char *msgbuf, int msglen, char *reason)
673{
674 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
675
676 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
677 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
678
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000679 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000680 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
681 }
682
683 /* Add Optional Reason Text */
684 if (reason) {
685 strcat(msgbuf, " : ");
686 strcat(msgbuf, reason);
687 }
688}
689
690/**********************************************************************
691 * Decode an OS/2 Operating System Error Code
692 *
693 * A convenience function to lookup an OS/2 error code and return a
694 * text message we can use to raise a Python exception.
695 *
696 * Notes:
697 * The messages for errors returned from the OS/2 kernel reside in
698 * the file OSO001.MSG in the \OS2 directory hierarchy.
699 *
700 **********************************************************************/
Victor Stinner97b89882010-05-06 00:25:39 +0000701static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000702os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
703{
704 APIRET rc;
705 ULONG msglen;
706
707 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
708 Py_BEGIN_ALLOW_THREADS
709 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
710 errorcode, "oso001.msg", &msglen);
711 Py_END_ALLOW_THREADS
712
713 if (rc == NO_ERROR)
714 os2_formatmsg(msgbuf, msglen, reason);
715 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000716 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner97b89882010-05-06 00:25:39 +0000717 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000718
719 return msgbuf;
720}
721
722/* Set an OS/2-specific error and return NULL. OS/2 kernel
723 errors are not in a global variable e.g. 'errno' nor are
724 they congruent with posix error numbers. */
725
Victor Stinner97b89882010-05-06 00:25:39 +0000726static PyObject *
727os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000728{
729 char text[1024];
730 PyObject *v;
731
732 os2_strerror(text, sizeof(text), code, "");
733
734 v = Py_BuildValue("(is)", code, text);
735 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000736 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000737 Py_DECREF(v);
738 }
739 return NULL; /* Signal to Python that an Exception is Pending */
740}
741
742#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000743
744/* POSIX generic methods */
745
Barry Warsaw53699e91996-12-10 23:23:01 +0000746static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000747posix_fildes(PyObject *fdobj, int (*func)(int))
748{
Victor Stinner97b89882010-05-06 00:25:39 +0000749 int fd;
750 int res;
751 fd = PyObject_AsFileDescriptor(fdobj);
752 if (fd < 0)
753 return NULL;
754 if (!_PyVerify_fd(fd))
755 return posix_error();
756 Py_BEGIN_ALLOW_THREADS
757 res = (*func)(fd);
758 Py_END_ALLOW_THREADS
759 if (res < 0)
760 return posix_error();
761 Py_INCREF(Py_None);
762 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000763}
Guido van Rossum21142a01999-01-08 21:05:37 +0000764
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000765#ifdef MS_WINDOWS
Tim Peters11b23062003-04-23 02:39:17 +0000766static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000767unicode_file_names(void)
768{
Victor Stinner97b89882010-05-06 00:25:39 +0000769 static int canusewide = -1;
770 if (canusewide == -1) {
771 /* As per doc for ::GetVersion(), this is the correct test for
772 the Windows NT family. */
773 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
774 }
775 return canusewide;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000776}
777#endif
Tim Peters11b23062003-04-23 02:39:17 +0000778
Guido van Rossum21142a01999-01-08 21:05:37 +0000779static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000780posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000781{
Victor Stinner97b89882010-05-06 00:25:39 +0000782 PyObject *opath1 = NULL;
783 char *path1;
784 int res;
785 if (!PyArg_ParseTuple(args, format,
786 PyUnicode_FSConverter, &opath1))
787 return NULL;
788 path1 = bytes2str(opath1, 1);
789 Py_BEGIN_ALLOW_THREADS
790 res = (*func)(path1);
791 Py_END_ALLOW_THREADS
792 if (res < 0)
793 return posix_error_with_allocated_filename(opath1);
794 release_bytes(opath1);
795 Py_INCREF(Py_None);
796 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000797}
798
Barry Warsaw53699e91996-12-10 23:23:01 +0000799static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000800posix_2str(PyObject *args,
Victor Stinner97b89882010-05-06 00:25:39 +0000801 char *format,
802 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000803{
Victor Stinner97b89882010-05-06 00:25:39 +0000804 PyObject *opath1 = NULL, *opath2 = NULL;
805 char *path1, *path2;
806 int res;
807 if (!PyArg_ParseTuple(args, format,
808 PyUnicode_FSConverter, &opath1,
809 PyUnicode_FSConverter, &opath2)) {
810 return NULL;
811 }
812 path1 = bytes2str(opath1, 1);
813 path2 = bytes2str(opath2, 1);
814 Py_BEGIN_ALLOW_THREADS
815 res = (*func)(path1, path2);
816 Py_END_ALLOW_THREADS
817 release_bytes(opath1);
818 release_bytes(opath2);
819 if (res != 0)
820 /* XXX how to report both path1 and path2??? */
821 return posix_error();
822 Py_INCREF(Py_None);
823 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000824}
825
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000826#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000827static PyObject*
Victor Stinner97b89882010-05-06 00:25:39 +0000828win32_1str(PyObject* args, char* func,
829 char* format, BOOL (__stdcall *funcA)(LPCSTR),
830 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000831{
Victor Stinner97b89882010-05-06 00:25:39 +0000832 PyObject *uni;
833 char *ansi;
834 BOOL result;
835 if (unicode_file_names()) {
836 if (!PyArg_ParseTuple(args, wformat, &uni))
837 PyErr_Clear();
838 else {
839 Py_BEGIN_ALLOW_THREADS
840 result = funcW(PyUnicode_AsUnicode(uni));
841 Py_END_ALLOW_THREADS
842 if (!result)
843 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
844 Py_INCREF(Py_None);
845 return Py_None;
846 }
847 }
848 if (!PyArg_ParseTuple(args, format, &ansi))
849 return NULL;
850 Py_BEGIN_ALLOW_THREADS
851 result = funcA(ansi);
852 Py_END_ALLOW_THREADS
853 if (!result)
854 return win32_error(func, ansi);
855 Py_INCREF(Py_None);
856 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000857
858}
859
860/* This is a reimplementation of the C library's chdir function,
861 but one that produces Win32 errors instead of DOS error codes.
862 chdir is essentially a wrapper around SetCurrentDirectory; however,
863 it also needs to set "magic" environment variables indicating
864 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000865static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000866win32_chdir(LPCSTR path)
867{
Victor Stinner97b89882010-05-06 00:25:39 +0000868 char new_path[MAX_PATH+1];
869 int result;
870 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000871
Victor Stinner97b89882010-05-06 00:25:39 +0000872 if(!SetCurrentDirectoryA(path))
873 return FALSE;
874 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
875 if (!result)
876 return FALSE;
877 /* In the ANSI API, there should not be any paths longer
878 than MAX_PATH. */
879 assert(result <= MAX_PATH+1);
880 if (strncmp(new_path, "\\\\", 2) == 0 ||
881 strncmp(new_path, "//", 2) == 0)
882 /* UNC path, nothing to do. */
883 return TRUE;
884 env[1] = new_path[0];
885 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000886}
887
888/* The Unicode version differs from the ANSI version
889 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000890static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000891win32_wchdir(LPCWSTR path)
892{
Victor Stinner97b89882010-05-06 00:25:39 +0000893 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
894 int result;
895 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000896
Victor Stinner97b89882010-05-06 00:25:39 +0000897 if(!SetCurrentDirectoryW(path))
898 return FALSE;
899 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
900 if (!result)
901 return FALSE;
902 if (result > MAX_PATH+1) {
903 new_path = malloc(result * sizeof(wchar_t));
904 if (!new_path) {
905 SetLastError(ERROR_OUTOFMEMORY);
906 return FALSE;
907 }
908 result = GetCurrentDirectoryW(result, new_path);
909 if (!result) {
910 free(new_path);
911 return FALSE;
912 }
913 }
914 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
915 wcsncmp(new_path, L"//", 2) == 0)
916 /* UNC path, nothing to do. */
917 return TRUE;
918 env[1] = new_path[0];
919 result = SetEnvironmentVariableW(env, new_path);
920 if (new_path != _new_path)
921 free(new_path);
922 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000923}
924#endif
925
Martin v. Löwis14694662006-02-03 12:54:16 +0000926#ifdef MS_WINDOWS
927/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
928 - time stamps are restricted to second resolution
929 - file modification times suffer from forth-and-back conversions between
930 UTC and local time
931 Therefore, we implement our own stat, based on the Win32 API directly.
932*/
Victor Stinner97b89882010-05-06 00:25:39 +0000933#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +0000934
935struct win32_stat{
936 int st_dev;
937 __int64 st_ino;
938 unsigned short st_mode;
939 int st_nlink;
940 int st_uid;
941 int st_gid;
942 int st_rdev;
943 __int64 st_size;
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +0000944 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000945 int st_atime_nsec;
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +0000946 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000947 int st_mtime_nsec;
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +0000948 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000949 int st_ctime_nsec;
950};
951
952static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
953
954static void
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +0000955FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +0000956{
Victor Stinner97b89882010-05-06 00:25:39 +0000957 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
958 /* Cannot simply cast and dereference in_ptr,
959 since it might not be aligned properly */
960 __int64 in;
961 memcpy(&in, in_ptr, sizeof(in));
962 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +0000963 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +0000964}
965
Thomas Wouters477c8d52006-05-27 19:21:47 +0000966static void
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +0000967time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000968{
Victor Stinner97b89882010-05-06 00:25:39 +0000969 /* XXX endianness */
970 __int64 out;
971 out = time_in + secs_between_epochs;
972 out = out * 10000000 + nsec_in / 100;
973 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000974}
975
Martin v. Löwis14694662006-02-03 12:54:16 +0000976/* Below, we *know* that ugo+r is 0444 */
977#if _S_IREAD != 0400
978#error Unsupported C library
979#endif
980static int
981attributes_to_mode(DWORD attr)
982{
Victor Stinner97b89882010-05-06 00:25:39 +0000983 int m = 0;
984 if (attr & FILE_ATTRIBUTE_DIRECTORY)
985 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
986 else
987 m |= _S_IFREG;
988 if (attr & FILE_ATTRIBUTE_READONLY)
989 m |= 0444;
990 else
991 m |= 0666;
992 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +0000993}
994
995static int
996attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
997{
Victor Stinner97b89882010-05-06 00:25:39 +0000998 memset(result, 0, sizeof(*result));
999 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1000 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1001 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1002 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1003 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Martin v. Löwis14694662006-02-03 12:54:16 +00001004
Victor Stinner97b89882010-05-06 00:25:39 +00001005 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001006}
1007
Thomas Wouters89f507f2006-12-13 04:49:30 +00001008/* Emulate GetFileAttributesEx[AW] on Windows 95 */
1009static int checked = 0;
1010static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
1011static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
1012static void
1013check_gfax()
1014{
Victor Stinner97b89882010-05-06 00:25:39 +00001015 HINSTANCE hKernel32;
1016 if (checked)
1017 return;
1018 checked = 1;
1019 hKernel32 = GetModuleHandle("KERNEL32");
1020 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
1021 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
Thomas Wouters89f507f2006-12-13 04:49:30 +00001022}
1023
Guido van Rossumd8faa362007-04-27 19:54:29 +00001024static BOOL
1025attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1026{
Victor Stinner97b89882010-05-06 00:25:39 +00001027 HANDLE hFindFile;
1028 WIN32_FIND_DATAA FileData;
1029 hFindFile = FindFirstFileA(pszFile, &FileData);
1030 if (hFindFile == INVALID_HANDLE_VALUE)
1031 return FALSE;
1032 FindClose(hFindFile);
1033 pfad->dwFileAttributes = FileData.dwFileAttributes;
1034 pfad->ftCreationTime = FileData.ftCreationTime;
1035 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1036 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1037 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1038 pfad->nFileSizeLow = FileData.nFileSizeLow;
1039 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001040}
1041
1042static BOOL
1043attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1044{
Victor Stinner97b89882010-05-06 00:25:39 +00001045 HANDLE hFindFile;
1046 WIN32_FIND_DATAW FileData;
1047 hFindFile = FindFirstFileW(pszFile, &FileData);
1048 if (hFindFile == INVALID_HANDLE_VALUE)
1049 return FALSE;
1050 FindClose(hFindFile);
1051 pfad->dwFileAttributes = FileData.dwFileAttributes;
1052 pfad->ftCreationTime = FileData.ftCreationTime;
1053 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1054 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1055 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1056 pfad->nFileSizeLow = FileData.nFileSizeLow;
1057 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001058}
1059
Thomas Wouters89f507f2006-12-13 04:49:30 +00001060static BOOL WINAPI
Victor Stinner97b89882010-05-06 00:25:39 +00001061Py_GetFileAttributesExA(LPCSTR pszFile,
1062 GET_FILEEX_INFO_LEVELS level,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001063 LPVOID pv)
1064{
Victor Stinner97b89882010-05-06 00:25:39 +00001065 BOOL result;
1066 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1067 /* First try to use the system's implementation, if that is
1068 available and either succeeds to gives an error other than
1069 that it isn't implemented. */
1070 check_gfax();
1071 if (gfaxa) {
1072 result = gfaxa(pszFile, level, pv);
1073 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1074 return result;
1075 }
1076 /* It's either not present, or not implemented.
1077 Emulate using FindFirstFile. */
1078 if (level != GetFileExInfoStandard) {
1079 SetLastError(ERROR_INVALID_PARAMETER);
1080 return FALSE;
1081 }
1082 /* Use GetFileAttributes to validate that the file name
1083 does not contain wildcards (which FindFirstFile would
1084 accept). */
1085 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
1086 return FALSE;
1087 return attributes_from_dir(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001088}
1089
1090static BOOL WINAPI
Victor Stinner97b89882010-05-06 00:25:39 +00001091Py_GetFileAttributesExW(LPCWSTR pszFile,
1092 GET_FILEEX_INFO_LEVELS level,
Thomas Wouters89f507f2006-12-13 04:49:30 +00001093 LPVOID pv)
1094{
Victor Stinner97b89882010-05-06 00:25:39 +00001095 BOOL result;
1096 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1097 /* First try to use the system's implementation, if that is
1098 available and either succeeds to gives an error other than
1099 that it isn't implemented. */
1100 check_gfax();
1101 if (gfaxa) {
1102 result = gfaxw(pszFile, level, pv);
1103 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1104 return result;
1105 }
1106 /* It's either not present, or not implemented.
1107 Emulate using FindFirstFile. */
1108 if (level != GetFileExInfoStandard) {
1109 SetLastError(ERROR_INVALID_PARAMETER);
1110 return FALSE;
1111 }
1112 /* Use GetFileAttributes to validate that the file name
1113 does not contain wildcards (which FindFirstFile would
1114 accept). */
1115 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
1116 return FALSE;
1117 return attributes_from_dir_w(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001118}
1119
Victor Stinner97b89882010-05-06 00:25:39 +00001120static int
Martin v. Löwis14694662006-02-03 12:54:16 +00001121win32_stat(const char* path, struct win32_stat *result)
1122{
Victor Stinner97b89882010-05-06 00:25:39 +00001123 WIN32_FILE_ATTRIBUTE_DATA info;
1124 int code;
1125 char *dot;
1126 /* XXX not supported on Win95 and NT 3.x */
1127 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
1128 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1129 /* Protocol violation: we explicitly clear errno, instead of
1130 setting it to a POSIX error. Callers should use GetLastError. */
1131 errno = 0;
1132 return -1;
1133 } else {
1134 /* Could not get attributes on open file. Fall back to
1135 reading the directory. */
1136 if (!attributes_from_dir(path, &info)) {
1137 /* Very strange. This should not fail now */
1138 errno = 0;
1139 return -1;
1140 }
1141 }
1142 }
1143 code = attribute_data_to_stat(&info, result);
1144 if (code != 0)
1145 return code;
1146 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1147 dot = strrchr(path, '.');
1148 if (dot) {
1149 if (stricmp(dot, ".bat") == 0 ||
1150 stricmp(dot, ".cmd") == 0 ||
1151 stricmp(dot, ".exe") == 0 ||
1152 stricmp(dot, ".com") == 0)
1153 result->st_mode |= 0111;
1154 }
1155 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001156}
1157
Victor Stinner97b89882010-05-06 00:25:39 +00001158static int
Martin v. Löwis14694662006-02-03 12:54:16 +00001159win32_wstat(const wchar_t* path, struct win32_stat *result)
1160{
Victor Stinner97b89882010-05-06 00:25:39 +00001161 int code;
1162 const wchar_t *dot;
1163 WIN32_FILE_ATTRIBUTE_DATA info;
1164 /* XXX not supported on Win95 and NT 3.x */
1165 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
1166 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1167 /* Protocol violation: we explicitly clear errno, instead of
1168 setting it to a POSIX error. Callers should use GetLastError. */
1169 errno = 0;
1170 return -1;
1171 } else {
1172 /* Could not get attributes on open file. Fall back to
1173 reading the directory. */
1174 if (!attributes_from_dir_w(path, &info)) {
1175 /* Very strange. This should not fail now */
1176 errno = 0;
1177 return -1;
1178 }
1179 }
1180 }
1181 code = attribute_data_to_stat(&info, result);
1182 if (code < 0)
1183 return code;
1184 /* Set IFEXEC if it is an .exe, .bat, ... */
1185 dot = wcsrchr(path, '.');
1186 if (dot) {
1187 if (_wcsicmp(dot, L".bat") == 0 ||
1188 _wcsicmp(dot, L".cmd") == 0 ||
1189 _wcsicmp(dot, L".exe") == 0 ||
1190 _wcsicmp(dot, L".com") == 0)
1191 result->st_mode |= 0111;
1192 }
1193 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001194}
1195
1196static int
1197win32_fstat(int file_number, struct win32_stat *result)
1198{
Victor Stinner97b89882010-05-06 00:25:39 +00001199 BY_HANDLE_FILE_INFORMATION info;
1200 HANDLE h;
1201 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001202
Victor Stinner97b89882010-05-06 00:25:39 +00001203 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001204
Victor Stinner97b89882010-05-06 00:25:39 +00001205 /* Protocol violation: we explicitly clear errno, instead of
1206 setting it to a POSIX error. Callers should use GetLastError. */
1207 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001208
Victor Stinner97b89882010-05-06 00:25:39 +00001209 if (h == INVALID_HANDLE_VALUE) {
1210 /* This is really a C library error (invalid file handle).
1211 We set the Win32 error to the closes one matching. */
1212 SetLastError(ERROR_INVALID_HANDLE);
1213 return -1;
1214 }
1215 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001216
Victor Stinner97b89882010-05-06 00:25:39 +00001217 type = GetFileType(h);
1218 if (type == FILE_TYPE_UNKNOWN) {
1219 DWORD error = GetLastError();
1220 if (error != 0) {
1221 return -1;
1222 }
1223 /* else: valid but unknown file */
1224 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001225
Victor Stinner97b89882010-05-06 00:25:39 +00001226 if (type != FILE_TYPE_DISK) {
1227 if (type == FILE_TYPE_CHAR)
1228 result->st_mode = _S_IFCHR;
1229 else if (type == FILE_TYPE_PIPE)
1230 result->st_mode = _S_IFIFO;
1231 return 0;
1232 }
1233
1234 if (!GetFileInformationByHandle(h, &info)) {
1235 return -1;
1236 }
1237
1238 /* similar to stat() */
1239 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1240 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1241 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1242 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1243 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1244 /* specific to fstat() */
1245 result->st_nlink = info.nNumberOfLinks;
1246 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1247 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001248}
1249
1250#endif /* MS_WINDOWS */
1251
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001252PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001253"stat_result: Result from stat or lstat.\n\n\
1254This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001255 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001256or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1257\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001258Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1259or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001260\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001261See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001262
1263static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner97b89882010-05-06 00:25:39 +00001264 {"st_mode", "protection bits"},
1265 {"st_ino", "inode"},
1266 {"st_dev", "device"},
1267 {"st_nlink", "number of hard links"},
1268 {"st_uid", "user ID of owner"},
1269 {"st_gid", "group ID of owner"},
1270 {"st_size", "total size, in bytes"},
1271 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1272 {NULL, "integer time of last access"},
1273 {NULL, "integer time of last modification"},
1274 {NULL, "integer time of last change"},
1275 {"st_atime", "time of last access"},
1276 {"st_mtime", "time of last modification"},
1277 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001278#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner97b89882010-05-06 00:25:39 +00001279 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001280#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001281#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner97b89882010-05-06 00:25:39 +00001282 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001283#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001284#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner97b89882010-05-06 00:25:39 +00001285 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001286#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001287#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00001288 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001289#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001290#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner97b89882010-05-06 00:25:39 +00001291 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001292#endif
1293#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner97b89882010-05-06 00:25:39 +00001294 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001295#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001296 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001297};
1298
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001299#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001300#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001301#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001302#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001303#endif
1304
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001305#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001306#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1307#else
1308#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1309#endif
1310
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001311#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001312#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1313#else
1314#define ST_RDEV_IDX ST_BLOCKS_IDX
1315#endif
1316
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001317#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1318#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1319#else
1320#define ST_FLAGS_IDX ST_RDEV_IDX
1321#endif
1322
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001323#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001324#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001325#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001326#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001327#endif
1328
1329#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1330#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1331#else
1332#define ST_BIRTHTIME_IDX ST_GEN_IDX
1333#endif
1334
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001335static PyStructSequence_Desc stat_result_desc = {
Victor Stinner97b89882010-05-06 00:25:39 +00001336 "stat_result", /* name */
1337 stat_result__doc__, /* doc */
1338 stat_result_fields,
1339 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001340};
1341
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001342PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001343"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1344This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001345 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001346or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001347\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001348See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001349
1350static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner97b89882010-05-06 00:25:39 +00001351 {"f_bsize", },
1352 {"f_frsize", },
1353 {"f_blocks", },
1354 {"f_bfree", },
1355 {"f_bavail", },
1356 {"f_files", },
1357 {"f_ffree", },
1358 {"f_favail", },
1359 {"f_flag", },
1360 {"f_namemax",},
1361 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001362};
1363
1364static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner97b89882010-05-06 00:25:39 +00001365 "statvfs_result", /* name */
1366 statvfs_result__doc__, /* doc */
1367 statvfs_result_fields,
1368 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001369};
1370
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001371static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001372static PyTypeObject StatResultType;
1373static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001374static newfunc structseq_new;
1375
1376static PyObject *
1377statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1378{
Victor Stinner97b89882010-05-06 00:25:39 +00001379 PyStructSequence *result;
1380 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001381
Victor Stinner97b89882010-05-06 00:25:39 +00001382 result = (PyStructSequence*)structseq_new(type, args, kwds);
1383 if (!result)
1384 return NULL;
1385 /* If we have been initialized from a tuple,
1386 st_?time might be set to None. Initialize it
1387 from the int slots. */
1388 for (i = 7; i <= 9; i++) {
1389 if (result->ob_item[i+3] == Py_None) {
1390 Py_DECREF(Py_None);
1391 Py_INCREF(result->ob_item[i]);
1392 result->ob_item[i+3] = result->ob_item[i];
1393 }
1394 }
1395 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001396}
1397
1398
1399
1400/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001401static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001402
1403PyDoc_STRVAR(stat_float_times__doc__,
1404"stat_float_times([newval]) -> oldval\n\n\
1405Determine whether os.[lf]stat represents time stamps as float objects.\n\
1406If newval is True, future calls to stat() return floats, if it is False,\n\
1407future calls return ints. \n\
1408If newval is omitted, return the current setting.\n");
1409
1410static PyObject*
1411stat_float_times(PyObject* self, PyObject *args)
1412{
Victor Stinner97b89882010-05-06 00:25:39 +00001413 int newval = -1;
1414 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1415 return NULL;
1416 if (newval == -1)
1417 /* Return old value */
1418 return PyBool_FromLong(_stat_float_times);
1419 _stat_float_times = newval;
1420 Py_INCREF(Py_None);
1421 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001422}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001423
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001424static void
1425fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1426{
Victor Stinner97b89882010-05-06 00:25:39 +00001427 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001428#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner97b89882010-05-06 00:25:39 +00001429 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001430#else
Victor Stinner97b89882010-05-06 00:25:39 +00001431 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001432#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001433 if (!ival)
1434 return;
1435 if (_stat_float_times) {
1436 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1437 } else {
1438 fval = ival;
1439 Py_INCREF(fval);
1440 }
1441 PyStructSequence_SET_ITEM(v, index, ival);
1442 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001443}
1444
Tim Peters5aa91602002-01-30 05:46:57 +00001445/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001446 (used by posix_stat() and posix_fstat()) */
1447static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001448_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001449{
Victor Stinner97b89882010-05-06 00:25:39 +00001450 unsigned long ansec, mnsec, cnsec;
1451 PyObject *v = PyStructSequence_New(&StatResultType);
1452 if (v == NULL)
1453 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001454
Victor Stinner97b89882010-05-06 00:25:39 +00001455 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001456#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner97b89882010-05-06 00:25:39 +00001457 PyStructSequence_SET_ITEM(v, 1,
1458 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001459#else
Victor Stinner97b89882010-05-06 00:25:39 +00001460 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001461#endif
1462#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner97b89882010-05-06 00:25:39 +00001463 PyStructSequence_SET_ITEM(v, 2,
1464 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001465#else
Victor Stinner97b89882010-05-06 00:25:39 +00001466 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001467#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001468 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1469 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1470 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001471#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner97b89882010-05-06 00:25:39 +00001472 PyStructSequence_SET_ITEM(v, 6,
1473 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001474#else
Victor Stinner97b89882010-05-06 00:25:39 +00001475 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001476#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001477
Martin v. Löwis14694662006-02-03 12:54:16 +00001478#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner97b89882010-05-06 00:25:39 +00001479 ansec = st->st_atim.tv_nsec;
1480 mnsec = st->st_mtim.tv_nsec;
1481 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001482#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner97b89882010-05-06 00:25:39 +00001483 ansec = st->st_atimespec.tv_nsec;
1484 mnsec = st->st_mtimespec.tv_nsec;
1485 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001486#elif defined(HAVE_STAT_NSEC)
Victor Stinner97b89882010-05-06 00:25:39 +00001487 ansec = st->st_atime_nsec;
1488 mnsec = st->st_mtime_nsec;
1489 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001490#else
Victor Stinner97b89882010-05-06 00:25:39 +00001491 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001492#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001493 fill_time(v, 7, st->st_atime, ansec);
1494 fill_time(v, 8, st->st_mtime, mnsec);
1495 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001496
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001497#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner97b89882010-05-06 00:25:39 +00001498 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1499 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001500#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001501#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner97b89882010-05-06 00:25:39 +00001502 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1503 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001504#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001505#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner97b89882010-05-06 00:25:39 +00001506 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1507 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001508#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001509#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner97b89882010-05-06 00:25:39 +00001510 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1511 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001512#endif
1513#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner97b89882010-05-06 00:25:39 +00001514 {
1515 PyObject *val;
1516 unsigned long bsec,bnsec;
1517 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001518#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner97b89882010-05-06 00:25:39 +00001519 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001520#else
Victor Stinner97b89882010-05-06 00:25:39 +00001521 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001522#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001523 if (_stat_float_times) {
1524 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1525 } else {
1526 val = PyLong_FromLong((long)bsec);
1527 }
1528 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1529 val);
1530 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001531#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001532#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00001533 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1534 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001535#endif
Fred Drake699f3522000-06-29 21:12:41 +00001536
Victor Stinner97b89882010-05-06 00:25:39 +00001537 if (PyErr_Occurred()) {
1538 Py_DECREF(v);
1539 return NULL;
1540 }
Fred Drake699f3522000-06-29 21:12:41 +00001541
Victor Stinner97b89882010-05-06 00:25:39 +00001542 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001543}
1544
Martin v. Löwisd8948722004-06-02 09:57:56 +00001545#ifdef MS_WINDOWS
1546
1547/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1548 where / can be used in place of \ and the trailing slash is optional.
1549 Both SERVER and SHARE must have at least one character.
1550*/
1551
1552#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1553#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001554#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001555#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001556#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001557
Tim Peters4ad82172004-08-30 17:02:04 +00001558static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001559IsUNCRootA(char *path, int pathlen)
1560{
Victor Stinner97b89882010-05-06 00:25:39 +00001561 #define ISSLASH ISSLASHA
Martin v. Löwisd8948722004-06-02 09:57:56 +00001562
Victor Stinner97b89882010-05-06 00:25:39 +00001563 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001564
Victor Stinner97b89882010-05-06 00:25:39 +00001565 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1566 /* minimum UNCRoot is \\x\y */
1567 return FALSE;
1568 for (i = 2; i < pathlen ; i++)
1569 if (ISSLASH(path[i])) break;
1570 if (i == 2 || i == pathlen)
1571 /* do not allow \\\SHARE or \\SERVER */
1572 return FALSE;
1573 share = i+1;
1574 for (i = share; i < pathlen; i++)
1575 if (ISSLASH(path[i])) break;
1576 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001577
Victor Stinner97b89882010-05-06 00:25:39 +00001578 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001579}
1580
Tim Peters4ad82172004-08-30 17:02:04 +00001581static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001582IsUNCRootW(Py_UNICODE *path, int pathlen)
1583{
Victor Stinner97b89882010-05-06 00:25:39 +00001584 #define ISSLASH ISSLASHW
Martin v. Löwisd8948722004-06-02 09:57:56 +00001585
Victor Stinner97b89882010-05-06 00:25:39 +00001586 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001587
Victor Stinner97b89882010-05-06 00:25:39 +00001588 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1589 /* minimum UNCRoot is \\x\y */
1590 return FALSE;
1591 for (i = 2; i < pathlen ; i++)
1592 if (ISSLASH(path[i])) break;
1593 if (i == 2 || i == pathlen)
1594 /* do not allow \\\SHARE or \\SERVER */
1595 return FALSE;
1596 share = i+1;
1597 for (i = share; i < pathlen; i++)
1598 if (ISSLASH(path[i])) break;
1599 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001600
Victor Stinner97b89882010-05-06 00:25:39 +00001601 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001602}
Martin v. Löwisd8948722004-06-02 09:57:56 +00001603#endif /* MS_WINDOWS */
1604
Barry Warsaw53699e91996-12-10 23:23:01 +00001605static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001606posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner97b89882010-05-06 00:25:39 +00001607 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001608#ifdef __VMS
Victor Stinner97b89882010-05-06 00:25:39 +00001609 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001610#else
Victor Stinner97b89882010-05-06 00:25:39 +00001611 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001612#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001613 char *wformat,
1614 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001615{
Victor Stinner97b89882010-05-06 00:25:39 +00001616 STRUCT_STAT st;
1617 PyObject *opath;
1618 char *path;
1619 int res;
1620 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001621
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001622#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00001623 /* If on wide-character-capable OS see if argument
1624 is Unicode and if so use wide API. */
1625 if (unicode_file_names()) {
1626 PyUnicodeObject *po;
1627 if (PyArg_ParseTuple(args, wformat, &po)) {
1628 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001629
Victor Stinner97b89882010-05-06 00:25:39 +00001630 Py_BEGIN_ALLOW_THREADS
1631 /* PyUnicode_AS_UNICODE result OK without
1632 thread lock as it is a simple dereference. */
1633 res = wstatfunc(wpath, &st);
1634 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001635
Victor Stinner97b89882010-05-06 00:25:39 +00001636 if (res != 0)
1637 return win32_error_unicode("stat", wpath);
1638 return _pystat_fromstructstat(&st);
1639 }
1640 /* Drop the argument parsing error as narrow strings
1641 are also valid. */
1642 PyErr_Clear();
1643 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001644#endif
1645
Victor Stinner97b89882010-05-06 00:25:39 +00001646 if (!PyArg_ParseTuple(args, format,
1647 PyUnicode_FSConverter, &opath))
1648 return NULL;
1649 path = bytes2str(opath, 1);
1650 Py_BEGIN_ALLOW_THREADS
1651 res = (*statfunc)(path, &st);
1652 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001653
Victor Stinner97b89882010-05-06 00:25:39 +00001654 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001655#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00001656 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001657#else
Victor Stinner97b89882010-05-06 00:25:39 +00001658 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001659#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001660 }
1661 else
1662 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001663
Victor Stinner97b89882010-05-06 00:25:39 +00001664 release_bytes(opath);
1665 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001666}
1667
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001668/* POSIX methods */
1669
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001670PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001671"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001672Use the real uid/gid to test for access to a path. Note that most\n\
1673operations will use the effective uid/gid, therefore this routine can\n\
1674be used in a suid/sgid environment to test if the invoking user has the\n\
1675specified access to the path. The mode argument can be F_OK to test\n\
1676existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001677
1678static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001679posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001680{
Victor Stinner97b89882010-05-06 00:25:39 +00001681 PyObject *opath;
1682 char *path;
1683 int mode;
1684
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001685#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00001686 DWORD attr;
1687 if (unicode_file_names()) {
1688 PyUnicodeObject *po;
1689 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1690 Py_BEGIN_ALLOW_THREADS
1691 /* PyUnicode_AS_UNICODE OK without thread lock as
1692 it is a simple dereference. */
1693 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1694 Py_END_ALLOW_THREADS
1695 goto finish;
1696 }
1697 /* Drop the argument parsing error as narrow strings
1698 are also valid. */
1699 PyErr_Clear();
1700 }
1701 if (!PyArg_ParseTuple(args, "O&i:access",
1702 PyUnicode_FSConverter, &opath, &mode))
1703 return 0;
1704 path = bytes2str(opath, 1);
1705 Py_BEGIN_ALLOW_THREADS
1706 attr = GetFileAttributesA(path);
1707 Py_END_ALLOW_THREADS
1708 release_bytes(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001709finish:
Victor Stinner97b89882010-05-06 00:25:39 +00001710 if (attr == 0xFFFFFFFF)
1711 /* File does not exist, or cannot read attributes */
1712 return PyBool_FromLong(0);
1713 /* Access is possible if either write access wasn't requested, or
1714 the file isn't read-only, or if it's a directory, as there are
1715 no read-only directories on Windows. */
1716 return PyBool_FromLong(!(mode & 2)
1717 || !(attr & FILE_ATTRIBUTE_READONLY)
1718 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001719#else
Victor Stinner97b89882010-05-06 00:25:39 +00001720 int res;
1721 if (!PyArg_ParseTuple(args, "O&i:access",
1722 PyUnicode_FSConverter, &opath, &mode))
1723 return NULL;
1724 path = bytes2str(opath, 1);
1725 Py_BEGIN_ALLOW_THREADS
1726 res = access(path, mode);
1727 Py_END_ALLOW_THREADS
1728 release_bytes(opath);
1729 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001730#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001731}
1732
Guido van Rossumd371ff11999-01-25 16:12:23 +00001733#ifndef F_OK
1734#define F_OK 0
1735#endif
1736#ifndef R_OK
1737#define R_OK 4
1738#endif
1739#ifndef W_OK
1740#define W_OK 2
1741#endif
1742#ifndef X_OK
1743#define X_OK 1
1744#endif
1745
1746#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001747PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001748"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001749Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001750
1751static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001752posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001753{
Victor Stinner97b89882010-05-06 00:25:39 +00001754 int id;
1755 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001756
Victor Stinner97b89882010-05-06 00:25:39 +00001757 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1758 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001759
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001760#if defined(__VMS)
Victor Stinner97b89882010-05-06 00:25:39 +00001761 /* file descriptor 0 only, the default input device (stdin) */
1762 if (id == 0) {
1763 ret = ttyname();
1764 }
1765 else {
1766 ret = NULL;
1767 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001768#else
Victor Stinner97b89882010-05-06 00:25:39 +00001769 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001770#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001771 if (ret == NULL)
1772 return posix_error();
Victor Stinnerbae0e622010-08-15 09:15:02 +00001773 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001774}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001775#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001776
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001777#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001778PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001779"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001780Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001781
1782static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001783posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001784{
Victor Stinner97b89882010-05-06 00:25:39 +00001785 char *ret;
1786 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001787
Greg Wardb48bc172000-03-01 21:51:56 +00001788#ifdef USE_CTERMID_R
Victor Stinner97b89882010-05-06 00:25:39 +00001789 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001790#else
Victor Stinner97b89882010-05-06 00:25:39 +00001791 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001792#endif
Victor Stinner97b89882010-05-06 00:25:39 +00001793 if (ret == NULL)
1794 return posix_error();
Victor Stinnerbae0e622010-08-15 09:15:02 +00001795 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001796}
1797#endif
1798
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001799PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001800"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001801Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001802
Barry Warsaw53699e91996-12-10 23:23:01 +00001803static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001804posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001805{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001806#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00001807 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001808#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner97b89882010-05-06 00:25:39 +00001809 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001810#elif defined(__VMS)
Victor Stinner97b89882010-05-06 00:25:39 +00001811 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001812#else
Victor Stinner97b89882010-05-06 00:25:39 +00001813 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001814#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001815}
1816
Fred Drake4d1e64b2002-04-15 19:40:07 +00001817#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001818PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001819"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001820Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001821opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001822
1823static PyObject *
1824posix_fchdir(PyObject *self, PyObject *fdobj)
1825{
Victor Stinner97b89882010-05-06 00:25:39 +00001826 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001827}
1828#endif /* HAVE_FCHDIR */
1829
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001830
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001831PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001832"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001833Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001834
Barry Warsaw53699e91996-12-10 23:23:01 +00001835static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001836posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001837{
Victor Stinner97b89882010-05-06 00:25:39 +00001838 PyObject *opath = NULL;
1839 char *path = NULL;
1840 int i;
1841 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001842#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00001843 DWORD attr;
1844 if (unicode_file_names()) {
1845 PyUnicodeObject *po;
1846 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1847 Py_BEGIN_ALLOW_THREADS
1848 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1849 if (attr != 0xFFFFFFFF) {
1850 if (i & _S_IWRITE)
1851 attr &= ~FILE_ATTRIBUTE_READONLY;
1852 else
1853 attr |= FILE_ATTRIBUTE_READONLY;
1854 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1855 }
1856 else
1857 res = 0;
1858 Py_END_ALLOW_THREADS
1859 if (!res)
1860 return win32_error_unicode("chmod",
1861 PyUnicode_AS_UNICODE(po));
1862 Py_INCREF(Py_None);
1863 return Py_None;
1864 }
1865 /* Drop the argument parsing error as narrow strings
1866 are also valid. */
1867 PyErr_Clear();
1868 }
1869 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1870 &opath, &i))
1871 return NULL;
1872 path = bytes2str(opath, 1);
1873 Py_BEGIN_ALLOW_THREADS
1874 attr = GetFileAttributesA(path);
1875 if (attr != 0xFFFFFFFF) {
1876 if (i & _S_IWRITE)
1877 attr &= ~FILE_ATTRIBUTE_READONLY;
1878 else
1879 attr |= FILE_ATTRIBUTE_READONLY;
1880 res = SetFileAttributesA(path, attr);
1881 }
1882 else
1883 res = 0;
1884 Py_END_ALLOW_THREADS
1885 if (!res) {
1886 win32_error("chmod", path);
1887 release_bytes(opath);
1888 return NULL;
1889 }
1890 release_bytes(opath);
1891 Py_INCREF(Py_None);
1892 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001893#else /* MS_WINDOWS */
Victor Stinner97b89882010-05-06 00:25:39 +00001894 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1895 &opath, &i))
1896 return NULL;
1897 path = bytes2str(opath, 1);
1898 Py_BEGIN_ALLOW_THREADS
1899 res = chmod(path, i);
1900 Py_END_ALLOW_THREADS
1901 if (res < 0)
1902 return posix_error_with_allocated_filename(opath);
1903 release_bytes(opath);
1904 Py_INCREF(Py_None);
1905 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001906#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001907}
1908
Christian Heimes4e30a842007-11-30 22:12:06 +00001909#ifdef HAVE_FCHMOD
1910PyDoc_STRVAR(posix_fchmod__doc__,
1911"fchmod(fd, mode)\n\n\
1912Change the access permissions of the file given by file\n\
1913descriptor fd.");
1914
1915static PyObject *
1916posix_fchmod(PyObject *self, PyObject *args)
1917{
Victor Stinner97b89882010-05-06 00:25:39 +00001918 int fd, mode, res;
1919 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1920 return NULL;
1921 Py_BEGIN_ALLOW_THREADS
1922 res = fchmod(fd, mode);
1923 Py_END_ALLOW_THREADS
1924 if (res < 0)
1925 return posix_error();
1926 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001927}
1928#endif /* HAVE_FCHMOD */
1929
1930#ifdef HAVE_LCHMOD
1931PyDoc_STRVAR(posix_lchmod__doc__,
1932"lchmod(path, mode)\n\n\
1933Change the access permissions of a file. If path is a symlink, this\n\
1934affects the link itself rather than the target.");
1935
1936static PyObject *
1937posix_lchmod(PyObject *self, PyObject *args)
1938{
Victor Stinner97b89882010-05-06 00:25:39 +00001939 PyObject *opath;
1940 char *path;
1941 int i;
1942 int res;
1943 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
1944 &opath, &i))
1945 return NULL;
1946 path = bytes2str(opath, 1);
1947 Py_BEGIN_ALLOW_THREADS
1948 res = lchmod(path, i);
1949 Py_END_ALLOW_THREADS
1950 if (res < 0)
1951 return posix_error_with_allocated_filename(opath);
1952 release_bytes(opath);
1953 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001954}
1955#endif /* HAVE_LCHMOD */
1956
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001957
Thomas Wouterscf297e42007-02-23 15:07:44 +00001958#ifdef HAVE_CHFLAGS
1959PyDoc_STRVAR(posix_chflags__doc__,
1960"chflags(path, flags)\n\n\
1961Set file flags.");
1962
1963static PyObject *
1964posix_chflags(PyObject *self, PyObject *args)
1965{
Victor Stinner97b89882010-05-06 00:25:39 +00001966 PyObject *opath;
1967 char *path;
1968 unsigned long flags;
1969 int res;
1970 if (!PyArg_ParseTuple(args, "O&k:chflags",
1971 PyUnicode_FSConverter, &opath, &flags))
1972 return NULL;
1973 path = bytes2str(opath, 1);
1974 Py_BEGIN_ALLOW_THREADS
1975 res = chflags(path, flags);
1976 Py_END_ALLOW_THREADS
1977 if (res < 0)
1978 return posix_error_with_allocated_filename(opath);
1979 release_bytes(opath);
1980 Py_INCREF(Py_None);
1981 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00001982}
1983#endif /* HAVE_CHFLAGS */
1984
1985#ifdef HAVE_LCHFLAGS
1986PyDoc_STRVAR(posix_lchflags__doc__,
1987"lchflags(path, flags)\n\n\
1988Set file flags.\n\
1989This function will not follow symbolic links.");
1990
1991static PyObject *
1992posix_lchflags(PyObject *self, PyObject *args)
1993{
Victor Stinner97b89882010-05-06 00:25:39 +00001994 PyObject *opath;
1995 char *path;
1996 unsigned long flags;
1997 int res;
1998 if (!PyArg_ParseTuple(args, "O&k:lchflags",
1999 PyUnicode_FSConverter, &opath, &flags))
2000 return NULL;
2001 path = bytes2str(opath, 1);
2002 Py_BEGIN_ALLOW_THREADS
2003 res = lchflags(path, flags);
2004 Py_END_ALLOW_THREADS
2005 if (res < 0)
2006 return posix_error_with_allocated_filename(opath);
2007 release_bytes(opath);
2008 Py_INCREF(Py_None);
2009 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002010}
2011#endif /* HAVE_LCHFLAGS */
2012
Martin v. Löwis244edc82001-10-04 22:44:26 +00002013#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002014PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002015"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002016Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002017
2018static PyObject *
2019posix_chroot(PyObject *self, PyObject *args)
2020{
Victor Stinner97b89882010-05-06 00:25:39 +00002021 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002022}
2023#endif
2024
Guido van Rossum21142a01999-01-08 21:05:37 +00002025#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002026PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002027"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002028force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002029
2030static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002031posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002032{
Stefan Krah67733312010-11-26 17:04:40 +00002033 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002034}
2035#endif /* HAVE_FSYNC */
2036
2037#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002038
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002039#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002040extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2041#endif
2042
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002043PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002044"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002045force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002046 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002047
2048static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002049posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002050{
Stefan Krah67733312010-11-26 17:04:40 +00002051 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002052}
2053#endif /* HAVE_FDATASYNC */
2054
2055
Fredrik Lundh10723342000-07-10 16:38:09 +00002056#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002057PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002058"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002059Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002060
Barry Warsaw53699e91996-12-10 23:23:01 +00002061static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002062posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002063{
Victor Stinner97b89882010-05-06 00:25:39 +00002064 PyObject *opath;
2065 char *path;
2066 long uid, gid;
2067 int res;
2068 if (!PyArg_ParseTuple(args, "O&ll:chown",
2069 PyUnicode_FSConverter, &opath,
2070 &uid, &gid))
2071 return NULL;
2072 path = bytes2str(opath, 1);
2073 Py_BEGIN_ALLOW_THREADS
2074 res = chown(path, (uid_t) uid, (gid_t) gid);
2075 Py_END_ALLOW_THREADS
2076 if (res < 0)
2077 return posix_error_with_allocated_filename(opath);
2078 release_bytes(opath);
2079 Py_INCREF(Py_None);
2080 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002081}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002082#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002083
Christian Heimes4e30a842007-11-30 22:12:06 +00002084#ifdef HAVE_FCHOWN
2085PyDoc_STRVAR(posix_fchown__doc__,
2086"fchown(fd, uid, gid)\n\n\
2087Change the owner and group id of the file given by file descriptor\n\
2088fd to the numeric uid and gid.");
2089
2090static PyObject *
2091posix_fchown(PyObject *self, PyObject *args)
2092{
Victor Stinner97b89882010-05-06 00:25:39 +00002093 int fd;
2094 long uid, gid;
2095 int res;
2096 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
2097 return NULL;
2098 Py_BEGIN_ALLOW_THREADS
2099 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2100 Py_END_ALLOW_THREADS
2101 if (res < 0)
2102 return posix_error();
2103 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002104}
2105#endif /* HAVE_FCHOWN */
2106
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002107#ifdef HAVE_LCHOWN
2108PyDoc_STRVAR(posix_lchown__doc__,
2109"lchown(path, uid, gid)\n\n\
2110Change the owner and group id of path to the numeric uid and gid.\n\
2111This function will not follow symbolic links.");
2112
2113static PyObject *
2114posix_lchown(PyObject *self, PyObject *args)
2115{
Victor Stinner97b89882010-05-06 00:25:39 +00002116 PyObject *opath;
2117 char *path;
2118 long uid, gid;
2119 int res;
2120 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2121 PyUnicode_FSConverter, &opath,
2122 &uid, &gid))
2123 return NULL;
2124 path = bytes2str(opath, 1);
2125 Py_BEGIN_ALLOW_THREADS
2126 res = lchown(path, (uid_t) uid, (gid_t) gid);
2127 Py_END_ALLOW_THREADS
2128 if (res < 0)
2129 return posix_error_with_allocated_filename(opath);
2130 release_bytes(opath);
2131 Py_INCREF(Py_None);
2132 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002133}
2134#endif /* HAVE_LCHOWN */
2135
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002136
Guido van Rossum36bc6801995-06-14 22:54:23 +00002137#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002138static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002139posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002140{
Victor Stinner97b89882010-05-06 00:25:39 +00002141 char buf[1026];
2142 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002143
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002144#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002145 if (!use_bytes && unicode_file_names()) {
2146 wchar_t wbuf[1026];
2147 wchar_t *wbuf2 = wbuf;
2148 PyObject *resobj;
2149 DWORD len;
2150 Py_BEGIN_ALLOW_THREADS
2151 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2152 /* If the buffer is large enough, len does not include the
2153 terminating \0. If the buffer is too small, len includes
2154 the space needed for the terminator. */
2155 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2156 wbuf2 = malloc(len * sizeof(wchar_t));
2157 if (wbuf2)
2158 len = GetCurrentDirectoryW(len, wbuf2);
2159 }
2160 Py_END_ALLOW_THREADS
2161 if (!wbuf2) {
2162 PyErr_NoMemory();
2163 return NULL;
2164 }
2165 if (!len) {
2166 if (wbuf2 != wbuf) free(wbuf2);
2167 return win32_error("getcwdu", NULL);
2168 }
2169 resobj = PyUnicode_FromWideChar(wbuf2, len);
2170 if (wbuf2 != wbuf) free(wbuf2);
2171 return resobj;
2172 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002173#endif
2174
Victor Stinner97b89882010-05-06 00:25:39 +00002175 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002176#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner97b89882010-05-06 00:25:39 +00002177 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002178#else
Victor Stinner97b89882010-05-06 00:25:39 +00002179 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002180#endif
Victor Stinner97b89882010-05-06 00:25:39 +00002181 Py_END_ALLOW_THREADS
2182 if (res == NULL)
2183 return posix_error();
2184 if (use_bytes)
2185 return PyBytes_FromStringAndSize(buf, strlen(buf));
2186 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"surrogateescape");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002187}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002188
2189PyDoc_STRVAR(posix_getcwd__doc__,
2190"getcwd() -> path\n\n\
2191Return a unicode string representing the current working directory.");
2192
2193static PyObject *
2194posix_getcwd_unicode(PyObject *self)
2195{
2196 return posix_getcwd(0);
2197}
2198
2199PyDoc_STRVAR(posix_getcwdb__doc__,
2200"getcwdb() -> path\n\n\
2201Return a bytes string representing the current working directory.");
2202
2203static PyObject *
2204posix_getcwd_bytes(PyObject *self)
2205{
2206 return posix_getcwd(1);
2207}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002208#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002209
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002210
Guido van Rossumb6775db1994-08-01 11:34:53 +00002211#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002212PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002213"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002214Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002215
Barry Warsaw53699e91996-12-10 23:23:01 +00002216static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002217posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002218{
Victor Stinner97b89882010-05-06 00:25:39 +00002219 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002220}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002221#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002222
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002223
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002224PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002225"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002226Return a list containing the names of the entries in the directory.\n\
2227\n\
Victor Stinner97b89882010-05-06 00:25:39 +00002228 path: path of directory to list\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002229\n\
2230The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002231entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002232
Barry Warsaw53699e91996-12-10 23:23:01 +00002233static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002234posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002235{
Victor Stinner97b89882010-05-06 00:25:39 +00002236 /* XXX Should redo this putting the (now four) versions of opendir
2237 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002238#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002239
Victor Stinner97b89882010-05-06 00:25:39 +00002240 PyObject *d, *v;
2241 HANDLE hFindFile;
2242 BOOL result;
2243 WIN32_FIND_DATA FileData;
2244 PyObject *opath;
2245 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2246 char *bufptr = namebuf;
2247 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002248
Victor Stinner97b89882010-05-06 00:25:39 +00002249 /* If on wide-character-capable OS see if argument
2250 is Unicode and if so use wide API. */
2251 if (unicode_file_names()) {
2252 PyObject *po;
2253 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2254 WIN32_FIND_DATAW wFileData;
2255 Py_UNICODE *wnamebuf;
2256 /* Overallocate for \\*.*\0 */
2257 len = PyUnicode_GET_SIZE(po);
2258 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2259 if (!wnamebuf) {
2260 PyErr_NoMemory();
2261 return NULL;
2262 }
2263 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2264 if (len > 0) {
2265 Py_UNICODE wch = wnamebuf[len-1];
2266 if (wch != L'/' && wch != L'\\' && wch != L':')
2267 wnamebuf[len++] = L'\\';
2268 wcscpy(wnamebuf + len, L"*.*");
2269 }
2270 if ((d = PyList_New(0)) == NULL) {
2271 free(wnamebuf);
2272 return NULL;
2273 }
Antoine Pitroubd25d592010-08-09 23:47:57 +00002274 Py_BEGIN_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002275 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroubd25d592010-08-09 23:47:57 +00002276 Py_END_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002277 if (hFindFile == INVALID_HANDLE_VALUE) {
2278 int error = GetLastError();
2279 if (error == ERROR_FILE_NOT_FOUND) {
2280 free(wnamebuf);
2281 return d;
2282 }
2283 Py_DECREF(d);
2284 win32_error_unicode("FindFirstFileW", wnamebuf);
2285 free(wnamebuf);
2286 return NULL;
2287 }
2288 do {
2289 /* Skip over . and .. */
2290 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2291 wcscmp(wFileData.cFileName, L"..") != 0) {
2292 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2293 if (v == NULL) {
2294 Py_DECREF(d);
2295 d = NULL;
2296 break;
2297 }
2298 if (PyList_Append(d, v) != 0) {
2299 Py_DECREF(v);
2300 Py_DECREF(d);
2301 d = NULL;
2302 break;
2303 }
2304 Py_DECREF(v);
2305 }
2306 Py_BEGIN_ALLOW_THREADS
2307 result = FindNextFileW(hFindFile, &wFileData);
2308 Py_END_ALLOW_THREADS
2309 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2310 it got to the end of the directory. */
2311 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2312 Py_DECREF(d);
2313 win32_error_unicode("FindNextFileW", wnamebuf);
2314 FindClose(hFindFile);
2315 free(wnamebuf);
2316 return NULL;
2317 }
2318 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002319
Victor Stinner97b89882010-05-06 00:25:39 +00002320 if (FindClose(hFindFile) == FALSE) {
2321 Py_DECREF(d);
2322 win32_error_unicode("FindClose", wnamebuf);
2323 free(wnamebuf);
2324 return NULL;
2325 }
2326 free(wnamebuf);
2327 return d;
2328 }
2329 /* Drop the argument parsing error as narrow strings
2330 are also valid. */
2331 PyErr_Clear();
2332 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002333
Victor Stinner97b89882010-05-06 00:25:39 +00002334 if (!PyArg_ParseTuple(args, "O&:listdir",
2335 PyUnicode_FSConverter, &opath))
2336 return NULL;
2337 if (PyObject_Size(opath)+1 > MAX_PATH) {
2338 PyErr_SetString(PyExc_ValueError, "path too long");
2339 Py_DECREF(opath);
2340 return NULL;
2341 }
2342 strcpy(namebuf, bytes2str(opath, 0));
2343 len = PyObject_Size(opath);
2344 if (len > 0) {
2345 char ch = namebuf[len-1];
2346 if (ch != SEP && ch != ALTSEP && ch != ':')
2347 namebuf[len++] = '/';
2348 strcpy(namebuf + len, "*.*");
2349 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002350
Victor Stinner97b89882010-05-06 00:25:39 +00002351 if ((d = PyList_New(0)) == NULL)
2352 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002353
Antoine Pitroubd25d592010-08-09 23:47:57 +00002354 Py_BEGIN_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002355 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroubd25d592010-08-09 23:47:57 +00002356 Py_END_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002357 if (hFindFile == INVALID_HANDLE_VALUE) {
2358 int error = GetLastError();
2359 if (error == ERROR_FILE_NOT_FOUND)
2360 return d;
2361 Py_DECREF(d);
2362 return win32_error("FindFirstFile", namebuf);
2363 }
2364 do {
2365 /* Skip over . and .. */
2366 if (strcmp(FileData.cFileName, ".") != 0 &&
2367 strcmp(FileData.cFileName, "..") != 0) {
2368 v = PyBytes_FromString(FileData.cFileName);
2369 if (v == NULL) {
2370 Py_DECREF(d);
2371 d = NULL;
2372 break;
2373 }
2374 if (PyList_Append(d, v) != 0) {
2375 Py_DECREF(v);
2376 Py_DECREF(d);
2377 d = NULL;
2378 break;
2379 }
2380 Py_DECREF(v);
2381 }
2382 Py_BEGIN_ALLOW_THREADS
2383 result = FindNextFile(hFindFile, &FileData);
2384 Py_END_ALLOW_THREADS
2385 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2386 it got to the end of the directory. */
2387 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2388 Py_DECREF(d);
2389 win32_error("FindNextFile", namebuf);
2390 FindClose(hFindFile);
2391 return NULL;
2392 }
2393 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002394
Victor Stinner97b89882010-05-06 00:25:39 +00002395 if (FindClose(hFindFile) == FALSE) {
2396 Py_DECREF(d);
2397 return win32_error("FindClose", namebuf);
2398 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002399
Victor Stinner97b89882010-05-06 00:25:39 +00002400 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002401
Tim Peters0bb44a42000-09-15 07:44:49 +00002402#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002403
2404#ifndef MAX_PATH
2405#define MAX_PATH CCHMAXPATH
2406#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002407 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002408 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002409 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002410 PyObject *d, *v;
2411 char namebuf[MAX_PATH+5];
2412 HDIR hdir = 1;
2413 ULONG srchcnt = 1;
2414 FILEFINDBUF3 ep;
2415 APIRET rc;
2416
Victor Stinner97b89882010-05-06 00:25:39 +00002417 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002418 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002419 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002420 name = bytes2str(oname);
2421 len = PyObject_Size(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002422 if (len >= MAX_PATH) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00002423 release_bytes(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002424 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002425 return NULL;
2426 }
2427 strcpy(namebuf, name);
2428 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002429 if (*pt == ALTSEP)
2430 *pt = SEP;
2431 if (namebuf[len-1] != SEP)
2432 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002433 strcpy(namebuf + len, "*.*");
2434
Neal Norwitz6c913782007-10-14 03:23:09 +00002435 if ((d = PyList_New(0)) == NULL) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00002436 release_bytes(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002437 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002438 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002439
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002440 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2441 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002442 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002443 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2444 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2445 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002446
2447 if (rc != NO_ERROR) {
2448 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002449 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002450 }
2451
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002452 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002453 do {
2454 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002455 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002456 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002457
2458 strcpy(namebuf, ep.achName);
2459
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002460 /* Leave Case of Name Alone -- In Native Form */
2461 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002462
Christian Heimes72b710a2008-05-26 13:28:38 +00002463 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002464 if (v == NULL) {
2465 Py_DECREF(d);
2466 d = NULL;
2467 break;
2468 }
2469 if (PyList_Append(d, v) != 0) {
2470 Py_DECREF(v);
2471 Py_DECREF(d);
2472 d = NULL;
2473 break;
2474 }
2475 Py_DECREF(v);
2476 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2477 }
2478
Martin v. Löwis011e8422009-05-05 04:43:17 +00002479 release_bytes(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002480 return d;
2481#else
Victor Stinner97b89882010-05-06 00:25:39 +00002482 PyObject *oname;
2483 char *name;
2484 PyObject *d, *v;
2485 DIR *dirp;
2486 struct dirent *ep;
2487 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002488
Victor Stinner97b89882010-05-06 00:25:39 +00002489 errno = 0;
2490 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2491 arg_is_unicode = 0;
2492 PyErr_Clear();
2493 }
2494 if (!PyArg_ParseTuple(args, "O&:listdir", PyUnicode_FSConverter, &oname))
2495 return NULL;
2496 name = bytes2str(oname, 1);
Antoine Pitrou037077f2010-09-04 17:26:01 +00002497 Py_BEGIN_ALLOW_THREADS
2498 dirp = opendir(name);
2499 Py_END_ALLOW_THREADS
2500 if (dirp == NULL) {
Victor Stinner97b89882010-05-06 00:25:39 +00002501 return posix_error_with_allocated_filename(oname);
2502 }
2503 if ((d = PyList_New(0)) == NULL) {
Antoine Pitrou037077f2010-09-04 17:26:01 +00002504 Py_BEGIN_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002505 closedir(dirp);
Antoine Pitrou037077f2010-09-04 17:26:01 +00002506 Py_END_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002507 release_bytes(oname);
2508 return NULL;
2509 }
2510 for (;;) {
2511 errno = 0;
2512 Py_BEGIN_ALLOW_THREADS
2513 ep = readdir(dirp);
2514 Py_END_ALLOW_THREADS
2515 if (ep == NULL) {
2516 if (errno == 0) {
2517 break;
2518 } else {
Antoine Pitrou037077f2010-09-04 17:26:01 +00002519 Py_BEGIN_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002520 closedir(dirp);
Antoine Pitrou037077f2010-09-04 17:26:01 +00002521 Py_END_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002522 Py_DECREF(d);
2523 return posix_error_with_allocated_filename(oname);
2524 }
2525 }
2526 if (ep->d_name[0] == '.' &&
2527 (NAMLEN(ep) == 1 ||
2528 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2529 continue;
Victor Stinner203406c2010-05-14 18:07:39 +00002530 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner97b89882010-05-06 00:25:39 +00002531 if (v == NULL) {
Victor Stinner203406c2010-05-14 18:07:39 +00002532 Py_DECREF(d);
2533 d = NULL;
Victor Stinner97b89882010-05-06 00:25:39 +00002534 break;
2535 }
Victor Stinner203406c2010-05-14 18:07:39 +00002536 if (arg_is_unicode) {
2537 PyObject *w;
2538
2539 w = PyUnicode_FromEncodedObject(v,
2540 Py_FileSystemDefaultEncoding,
2541 "surrogateescape");
2542 Py_DECREF(v);
2543 if (w != NULL)
2544 v = w;
2545 else {
2546 /* Encoding failed to decode ASCII bytes.
2547 Raise exception. */
2548 Py_DECREF(d);
2549 d = NULL;
2550 break;
2551 }
2552 }
Victor Stinner97b89882010-05-06 00:25:39 +00002553 if (PyList_Append(d, v) != 0) {
2554 Py_DECREF(v);
Victor Stinner203406c2010-05-14 18:07:39 +00002555 Py_DECREF(d);
2556 d = NULL;
Victor Stinner97b89882010-05-06 00:25:39 +00002557 break;
2558 }
2559 Py_DECREF(v);
2560 }
Antoine Pitrou037077f2010-09-04 17:26:01 +00002561 Py_BEGIN_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002562 closedir(dirp);
Antoine Pitrou037077f2010-09-04 17:26:01 +00002563 Py_END_ALLOW_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00002564 release_bytes(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002565
Victor Stinner97b89882010-05-06 00:25:39 +00002566 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002567
Tim Peters0bb44a42000-09-15 07:44:49 +00002568#endif /* which OS */
2569} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002570
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002571#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002572/* A helper function for abspath on win32 */
2573static PyObject *
2574posix__getfullpathname(PyObject *self, PyObject *args)
2575{
Victor Stinner97b89882010-05-06 00:25:39 +00002576 PyObject *opath;
2577 char *path;
2578 char outbuf[MAX_PATH*2];
2579 char *temp;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002580#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002581 if (unicode_file_names()) {
2582 PyUnicodeObject *po;
2583 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2584 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2585 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2586 Py_UNICODE *wtemp;
2587 DWORD result;
2588 PyObject *v;
2589 result = GetFullPathNameW(wpath,
2590 sizeof(woutbuf)/sizeof(woutbuf[0]),
2591 woutbuf, &wtemp);
2592 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2593 woutbufp = malloc(result * sizeof(Py_UNICODE));
2594 if (!woutbufp)
2595 return PyErr_NoMemory();
2596 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2597 }
2598 if (result)
2599 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2600 else
2601 v = win32_error_unicode("GetFullPathNameW", wpath);
2602 if (woutbufp != woutbuf)
2603 free(woutbufp);
2604 return v;
2605 }
2606 /* Drop the argument parsing error as narrow strings
2607 are also valid. */
2608 PyErr_Clear();
2609 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002610#endif
Victor Stinner97b89882010-05-06 00:25:39 +00002611 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2612 PyUnicode_FSConverter, &opath))
2613 return NULL;
2614 path = bytes2str(opath, 1);
2615 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2616 outbuf, &temp)) {
2617 win32_error("GetFullPathName", path);
2618 release_bytes(opath);
2619 return NULL;
2620 }
2621 release_bytes(opath);
2622 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2623 return PyUnicode_Decode(outbuf, strlen(outbuf),
2624 Py_FileSystemDefaultEncoding, NULL);
2625 }
2626 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002627} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002628#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002629
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002630PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002631"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002632Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002633
Barry Warsaw53699e91996-12-10 23:23:01 +00002634static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002635posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002636{
Victor Stinner97b89882010-05-06 00:25:39 +00002637 int res;
2638 PyObject *opath;
2639 char *path;
2640 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002641
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002642#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002643 if (unicode_file_names()) {
2644 PyUnicodeObject *po;
2645 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2646 Py_BEGIN_ALLOW_THREADS
2647 /* PyUnicode_AS_UNICODE OK without thread lock as
2648 it is a simple dereference. */
2649 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2650 Py_END_ALLOW_THREADS
2651 if (!res)
2652 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2653 Py_INCREF(Py_None);
2654 return Py_None;
2655 }
2656 /* Drop the argument parsing error as narrow strings
2657 are also valid. */
2658 PyErr_Clear();
2659 }
2660 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2661 PyUnicode_FSConverter, &opath, &mode))
2662 return NULL;
2663 path = bytes2str(opath, 1);
2664 Py_BEGIN_ALLOW_THREADS
2665 /* PyUnicode_AS_UNICODE OK without thread lock as
2666 it is a simple dereference. */
2667 res = CreateDirectoryA(path, NULL);
2668 Py_END_ALLOW_THREADS
2669 if (!res) {
2670 win32_error("mkdir", path);
2671 release_bytes(opath);
2672 return NULL;
2673 }
2674 release_bytes(opath);
2675 Py_INCREF(Py_None);
2676 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002677#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002678
Victor Stinner97b89882010-05-06 00:25:39 +00002679 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2680 PyUnicode_FSConverter, &opath, &mode))
2681 return NULL;
2682 path = bytes2str(opath, 1);
2683 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002684#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner97b89882010-05-06 00:25:39 +00002685 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002686#else
Victor Stinner97b89882010-05-06 00:25:39 +00002687 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002688#endif
Victor Stinner97b89882010-05-06 00:25:39 +00002689 Py_END_ALLOW_THREADS
2690 if (res < 0)
2691 return posix_error_with_allocated_filename(opath);
2692 release_bytes(opath);
2693 Py_INCREF(Py_None);
2694 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002695#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002696}
2697
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002698
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002699/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2700#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002701#include <sys/resource.h>
2702#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002703
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002704
2705#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002706PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002707"nice(inc) -> new_priority\n\n\
2708Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002709
Barry Warsaw53699e91996-12-10 23:23:01 +00002710static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002711posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002712{
Victor Stinner97b89882010-05-06 00:25:39 +00002713 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002714
Victor Stinner97b89882010-05-06 00:25:39 +00002715 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2716 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002717
Victor Stinner97b89882010-05-06 00:25:39 +00002718 /* There are two flavours of 'nice': one that returns the new
2719 priority (as required by almost all standards out there) and the
2720 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2721 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002722
Victor Stinner97b89882010-05-06 00:25:39 +00002723 If we are of the nice family that returns the new priority, we
2724 need to clear errno before the call, and check if errno is filled
2725 before calling posix_error() on a returnvalue of -1, because the
2726 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002727
Victor Stinner97b89882010-05-06 00:25:39 +00002728 errno = 0;
2729 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002730#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner97b89882010-05-06 00:25:39 +00002731 if (value == 0)
2732 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002733#endif
Victor Stinner97b89882010-05-06 00:25:39 +00002734 if (value == -1 && errno != 0)
2735 /* either nice() or getpriority() returned an error */
2736 return posix_error();
2737 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002738}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002739#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002740
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002741PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002742"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002743Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002744
Barry Warsaw53699e91996-12-10 23:23:01 +00002745static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002746posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002747{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002748#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002749 PyObject *o1, *o2;
2750 char *p1, *p2;
2751 BOOL result;
2752 if (unicode_file_names()) {
2753 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2754 goto error;
2755 if (!convert_to_unicode(&o1))
2756 goto error;
2757 if (!convert_to_unicode(&o2)) {
2758 Py_DECREF(o1);
2759 goto error;
2760 }
2761 Py_BEGIN_ALLOW_THREADS
2762 result = MoveFileW(PyUnicode_AsUnicode(o1),
2763 PyUnicode_AsUnicode(o2));
2764 Py_END_ALLOW_THREADS
2765 Py_DECREF(o1);
2766 Py_DECREF(o2);
2767 if (!result)
2768 return win32_error("rename", NULL);
2769 Py_INCREF(Py_None);
2770 return Py_None;
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +00002771error:
Victor Stinner97b89882010-05-06 00:25:39 +00002772 PyErr_Clear();
2773 }
2774 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2775 return NULL;
2776 Py_BEGIN_ALLOW_THREADS
2777 result = MoveFileA(p1, p2);
2778 Py_END_ALLOW_THREADS
2779 if (!result)
2780 return win32_error("rename", NULL);
2781 Py_INCREF(Py_None);
2782 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002783#else
Victor Stinner97b89882010-05-06 00:25:39 +00002784 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002785#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002786}
2787
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002788
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002789PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002790"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002791Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002792
Barry Warsaw53699e91996-12-10 23:23:01 +00002793static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002794posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002795{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002796#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002797 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002798#else
Victor Stinner97b89882010-05-06 00:25:39 +00002799 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002800#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002801}
2802
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002803
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002804PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002805"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002806Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002807
Barry Warsaw53699e91996-12-10 23:23:01 +00002808static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002809posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002810{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002811#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002812 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002813#else
Victor Stinner97b89882010-05-06 00:25:39 +00002814 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002815#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002816}
2817
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002818
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002819#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002820PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002821"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002822Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002823
Barry Warsaw53699e91996-12-10 23:23:01 +00002824static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002825posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002826{
Victor Stinner97b89882010-05-06 00:25:39 +00002827 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002828#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002829 wchar_t *command;
2830 if (!PyArg_ParseTuple(args, "u:system", &command))
2831 return NULL;
Victor Stinnera5ab4fc2010-04-16 12:47:52 +00002832
Victor Stinner97b89882010-05-06 00:25:39 +00002833 Py_BEGIN_ALLOW_THREADS
2834 sts = _wsystem(command);
2835 Py_END_ALLOW_THREADS
Victor Stinnera5ab4fc2010-04-16 12:47:52 +00002836#else
Victor Stinner97b89882010-05-06 00:25:39 +00002837 PyObject *command_obj;
2838 char *command;
2839 if (!PyArg_ParseTuple(args, "O&:system",
2840 PyUnicode_FSConverter, &command_obj))
2841 return NULL;
Victor Stinnera5ab4fc2010-04-16 12:47:52 +00002842
Victor Stinner97b89882010-05-06 00:25:39 +00002843 command = bytes2str(command_obj, 1);
2844 Py_BEGIN_ALLOW_THREADS
2845 sts = system(command);
2846 Py_END_ALLOW_THREADS
2847 release_bytes(command_obj);
Victor Stinnera5ab4fc2010-04-16 12:47:52 +00002848#endif
Victor Stinner97b89882010-05-06 00:25:39 +00002849 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002850}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002851#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002852
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002853
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002854PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002855"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002856Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002857
Barry Warsaw53699e91996-12-10 23:23:01 +00002858static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002859posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002860{
Victor Stinner97b89882010-05-06 00:25:39 +00002861 int i;
2862 if (!PyArg_ParseTuple(args, "i:umask", &i))
2863 return NULL;
2864 i = (int)umask(i);
2865 if (i < 0)
2866 return posix_error();
2867 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002868}
2869
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002870
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002871PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002872"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002873Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002874
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002875PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002876"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002877Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002878
Barry Warsaw53699e91996-12-10 23:23:01 +00002879static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002880posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002881{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002882#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002883 return win32_1str(args, "remove", "y:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002884#else
Victor Stinner97b89882010-05-06 00:25:39 +00002885 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002886#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002887}
2888
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002889
Guido van Rossumb6775db1994-08-01 11:34:53 +00002890#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002891PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002892"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002893Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002894
Barry Warsaw53699e91996-12-10 23:23:01 +00002895static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002896posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002897{
Victor Stinner97b89882010-05-06 00:25:39 +00002898 struct utsname u;
2899 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002900
Victor Stinner97b89882010-05-06 00:25:39 +00002901 Py_BEGIN_ALLOW_THREADS
2902 res = uname(&u);
2903 Py_END_ALLOW_THREADS
2904 if (res < 0)
2905 return posix_error();
2906 return Py_BuildValue("(sssss)",
2907 u.sysname,
2908 u.nodename,
2909 u.release,
2910 u.version,
2911 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002912}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002913#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002914
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002915static int
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002916extract_time(PyObject *t, time_t* sec, long* usec)
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002917{
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002918 time_t intval;
Victor Stinner97b89882010-05-06 00:25:39 +00002919 if (PyFloat_Check(t)) {
2920 double tval = PyFloat_AsDouble(t);
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002921 PyObject *intobj = PyNumber_Long(t);
Victor Stinner97b89882010-05-06 00:25:39 +00002922 if (!intobj)
2923 return -1;
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002924#if SIZEOF_TIME_T > SIZEOF_LONG
2925 intval = PyLong_AsUnsignedLongLongMask(intobj);
2926#else
Victor Stinner97b89882010-05-06 00:25:39 +00002927 intval = PyLong_AsLong(intobj);
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002928#endif
Victor Stinner97b89882010-05-06 00:25:39 +00002929 Py_DECREF(intobj);
2930 if (intval == -1 && PyErr_Occurred())
2931 return -1;
2932 *sec = intval;
2933 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
2934 if (*usec < 0)
2935 /* If rounding gave us a negative number,
2936 truncate. */
2937 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002938 return 0;
Victor Stinner97b89882010-05-06 00:25:39 +00002939 }
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002940#if SIZEOF_TIME_T > SIZEOF_LONG
2941 intval = PyLong_AsUnsignedLongLongMask(t);
2942#else
Victor Stinner97b89882010-05-06 00:25:39 +00002943 intval = PyLong_AsLong(t);
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002944#endif
Victor Stinner97b89882010-05-06 00:25:39 +00002945 if (intval == -1 && PyErr_Occurred())
2946 return -1;
2947 *sec = intval;
2948 *usec = 0;
2949 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002950}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002951
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002952PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002953"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002954utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002955Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002956second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002957
Barry Warsaw53699e91996-12-10 23:23:01 +00002958static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002959posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002960{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002961#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00002962 PyObject *arg;
2963 PyUnicodeObject *obwpath;
2964 wchar_t *wpath = NULL;
2965 PyObject *oapath;
2966 char *apath;
2967 HANDLE hFile;
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00002968 time_t atimesec, mtimesec;
2969 long ausec, musec;
Victor Stinner97b89882010-05-06 00:25:39 +00002970 FILETIME atime, mtime;
2971 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002972
Victor Stinner97b89882010-05-06 00:25:39 +00002973 if (unicode_file_names()) {
2974 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2975 wpath = PyUnicode_AS_UNICODE(obwpath);
2976 Py_BEGIN_ALLOW_THREADS
2977 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2978 NULL, OPEN_EXISTING,
2979 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2980 Py_END_ALLOW_THREADS
2981 if (hFile == INVALID_HANDLE_VALUE)
2982 return win32_error_unicode("utime", wpath);
2983 } else
2984 /* Drop the argument parsing error as narrow strings
2985 are also valid. */
2986 PyErr_Clear();
2987 }
2988 if (!wpath) {
2989 if (!PyArg_ParseTuple(args, "O&O:utime",
2990 PyUnicode_FSConverter, &oapath, &arg))
2991 return NULL;
2992 apath = bytes2str(oapath, 1);
2993 Py_BEGIN_ALLOW_THREADS
2994 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2995 NULL, OPEN_EXISTING,
2996 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2997 Py_END_ALLOW_THREADS
2998 if (hFile == INVALID_HANDLE_VALUE) {
2999 win32_error("utime", apath);
3000 release_bytes(oapath);
3001 return NULL;
3002 }
3003 release_bytes(oapath);
3004 }
3005
3006 if (arg == Py_None) {
3007 SYSTEMTIME now;
3008 GetSystemTime(&now);
3009 if (!SystemTimeToFileTime(&now, &mtime) ||
3010 !SystemTimeToFileTime(&now, &atime)) {
3011 win32_error("utime", NULL);
3012 goto done;
Stefan Krah67733312010-11-26 17:04:40 +00003013 }
Victor Stinner97b89882010-05-06 00:25:39 +00003014 }
3015 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3016 PyErr_SetString(PyExc_TypeError,
3017 "utime() arg 2 must be a tuple (atime, mtime)");
3018 goto done;
3019 }
3020 else {
3021 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3022 &atimesec, &ausec) == -1)
3023 goto done;
3024 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3025 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3026 &mtimesec, &musec) == -1)
3027 goto done;
3028 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3029 }
3030 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3031 /* Avoid putting the file name into the error here,
3032 as that may confuse the user into believing that
3033 something is wrong with the file, when it also
3034 could be the time stamp that gives a problem. */
3035 win32_error("utime", NULL);
Antoine Pitrouff173852011-01-06 18:29:05 +00003036 goto done;
Victor Stinner97b89882010-05-06 00:25:39 +00003037 }
3038 Py_INCREF(Py_None);
3039 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003040done:
Victor Stinner97b89882010-05-06 00:25:39 +00003041 CloseHandle(hFile);
3042 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003043#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003044
Victor Stinner97b89882010-05-06 00:25:39 +00003045 PyObject *opath;
3046 char *path;
Amaury Forgeot d'Arc32e8aab2011-01-03 00:40:04 +00003047 time_t atime, mtime;
3048 long ausec, musec;
Victor Stinner97b89882010-05-06 00:25:39 +00003049 int res;
3050 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003051
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003052#if defined(HAVE_UTIMES)
Victor Stinner97b89882010-05-06 00:25:39 +00003053 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003054#define ATIME buf[0].tv_sec
3055#define MTIME buf[1].tv_sec
3056#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003057/* XXX should define struct utimbuf instead, above */
Victor Stinner97b89882010-05-06 00:25:39 +00003058 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003059#define ATIME buf.actime
3060#define MTIME buf.modtime
3061#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003062#else /* HAVE_UTIMES */
Victor Stinner97b89882010-05-06 00:25:39 +00003063 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003064#define ATIME buf[0]
3065#define MTIME buf[1]
3066#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003067#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003068
Mark Hammond817c9292003-12-03 01:22:38 +00003069
Victor Stinner97b89882010-05-06 00:25:39 +00003070 if (!PyArg_ParseTuple(args, "O&O:utime",
3071 PyUnicode_FSConverter, &opath, &arg))
3072 return NULL;
3073 path = bytes2str(opath, 1);
3074 if (arg == Py_None) {
3075 /* optional time values not given */
3076 Py_BEGIN_ALLOW_THREADS
3077 res = utime(path, NULL);
3078 Py_END_ALLOW_THREADS
3079 }
3080 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3081 PyErr_SetString(PyExc_TypeError,
3082 "utime() arg 2 must be a tuple (atime, mtime)");
3083 release_bytes(opath);
3084 return NULL;
3085 }
3086 else {
3087 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3088 &atime, &ausec) == -1) {
3089 release_bytes(opath);
3090 return NULL;
3091 }
3092 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3093 &mtime, &musec) == -1) {
3094 release_bytes(opath);
3095 return NULL;
3096 }
3097 ATIME = atime;
3098 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003099#ifdef HAVE_UTIMES
Victor Stinner97b89882010-05-06 00:25:39 +00003100 buf[0].tv_usec = ausec;
3101 buf[1].tv_usec = musec;
3102 Py_BEGIN_ALLOW_THREADS
3103 res = utimes(path, buf);
3104 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003105#else
Victor Stinner97b89882010-05-06 00:25:39 +00003106 Py_BEGIN_ALLOW_THREADS
3107 res = utime(path, UTIME_ARG);
3108 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003109#endif /* HAVE_UTIMES */
Victor Stinner97b89882010-05-06 00:25:39 +00003110 }
3111 if (res < 0) {
3112 return posix_error_with_allocated_filename(opath);
3113 }
3114 release_bytes(opath);
3115 Py_INCREF(Py_None);
3116 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003117#undef UTIME_ARG
3118#undef ATIME
3119#undef MTIME
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003120#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003121}
3122
Guido van Rossum85e3b011991-06-03 12:42:10 +00003123
Guido van Rossum3b066191991-06-04 19:40:25 +00003124/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003125
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003126PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003127"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003128Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003129
Barry Warsaw53699e91996-12-10 23:23:01 +00003130static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003131posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003132{
Victor Stinner97b89882010-05-06 00:25:39 +00003133 int sts;
3134 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3135 return NULL;
3136 _exit(sts);
3137 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003138}
3139
Martin v. Löwis114619e2002-10-07 06:44:21 +00003140#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3141static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003142free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003143{
Victor Stinner97b89882010-05-06 00:25:39 +00003144 Py_ssize_t i;
3145 for (i = 0; i < count; i++)
3146 PyMem_Free(array[i]);
3147 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003148}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003149
Antoine Pitrou69f71142009-05-24 21:25:49 +00003150static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003151int fsconvert_strdup(PyObject *o, char**out)
3152{
Victor Stinner97b89882010-05-06 00:25:39 +00003153 PyObject *bytes;
3154 Py_ssize_t size;
3155 if (!PyUnicode_FSConverter(o, &bytes))
3156 return 0;
3157 size = PyObject_Size(bytes);
3158 *out = PyMem_Malloc(size+1);
3159 if (!*out)
3160 return 0;
3161 /* Don't lock bytes, as we hold the GIL */
3162 memcpy(*out, bytes2str(bytes, 0), size+1);
3163 Py_DECREF(bytes);
3164 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003165}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003166#endif
3167
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003168
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003169#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003170PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003171"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003172Execute an executable path with arguments, replacing current process.\n\
3173\n\
Victor Stinner97b89882010-05-06 00:25:39 +00003174 path: path of executable file\n\
3175 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003176
Barry Warsaw53699e91996-12-10 23:23:01 +00003177static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003178posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003179{
Victor Stinner97b89882010-05-06 00:25:39 +00003180 PyObject *opath;
3181 char *path;
3182 PyObject *argv;
3183 char **argvlist;
3184 Py_ssize_t i, argc;
3185 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003186
Victor Stinner97b89882010-05-06 00:25:39 +00003187 /* execv has two arguments: (path, argv), where
3188 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003189
Victor Stinner97b89882010-05-06 00:25:39 +00003190 if (!PyArg_ParseTuple(args, "O&O:execv",
3191 PyUnicode_FSConverter,
3192 &opath, &argv))
3193 return NULL;
3194 path = bytes2str(opath, 1);
3195 if (PyList_Check(argv)) {
3196 argc = PyList_Size(argv);
3197 getitem = PyList_GetItem;
3198 }
3199 else if (PyTuple_Check(argv)) {
3200 argc = PyTuple_Size(argv);
3201 getitem = PyTuple_GetItem;
3202 }
3203 else {
3204 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3205 release_bytes(opath);
3206 return NULL;
3207 }
3208 if (argc < 1) {
3209 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3210 release_bytes(opath);
3211 return NULL;
3212 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003213
Victor Stinner97b89882010-05-06 00:25:39 +00003214 argvlist = PyMem_NEW(char *, argc+1);
3215 if (argvlist == NULL) {
3216 release_bytes(opath);
3217 return PyErr_NoMemory();
3218 }
3219 for (i = 0; i < argc; i++) {
3220 if (!fsconvert_strdup((*getitem)(argv, i),
3221 &argvlist[i])) {
3222 free_string_array(argvlist, i);
3223 PyErr_SetString(PyExc_TypeError,
3224 "execv() arg 2 must contain only strings");
3225 release_bytes(opath);
3226 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003227
Victor Stinner97b89882010-05-06 00:25:39 +00003228 }
3229 }
3230 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003231
Victor Stinner97b89882010-05-06 00:25:39 +00003232 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003233
Victor Stinner97b89882010-05-06 00:25:39 +00003234 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003235
Victor Stinner97b89882010-05-06 00:25:39 +00003236 free_string_array(argvlist, argc);
3237 release_bytes(opath);
3238 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003239}
3240
Victor Stinnera27dcb72010-04-25 22:39:07 +00003241static char**
3242parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3243{
Victor Stinner97b89882010-05-06 00:25:39 +00003244 char **envlist;
3245 Py_ssize_t i, pos, envc;
3246 PyObject *keys=NULL, *vals=NULL;
3247 PyObject *key, *val, *key2, *val2;
3248 char *p, *k, *v;
3249 size_t len;
Victor Stinnera27dcb72010-04-25 22:39:07 +00003250
Victor Stinner97b89882010-05-06 00:25:39 +00003251 i = PyMapping_Size(env);
3252 if (i < 0)
3253 return NULL;
3254 envlist = PyMem_NEW(char *, i + 1);
3255 if (envlist == NULL) {
3256 PyErr_NoMemory();
3257 return NULL;
3258 }
3259 envc = 0;
3260 keys = PyMapping_Keys(env);
3261 vals = PyMapping_Values(env);
3262 if (!keys || !vals)
3263 goto error;
3264 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3265 PyErr_Format(PyExc_TypeError,
3266 "env.keys() or env.values() is not a list");
3267 goto error;
3268 }
Victor Stinnera27dcb72010-04-25 22:39:07 +00003269
Victor Stinner97b89882010-05-06 00:25:39 +00003270 for (pos = 0; pos < i; pos++) {
3271 key = PyList_GetItem(keys, pos);
3272 val = PyList_GetItem(vals, pos);
3273 if (!key || !val)
3274 goto error;
Victor Stinnera27dcb72010-04-25 22:39:07 +00003275
Victor Stinner97b89882010-05-06 00:25:39 +00003276 if (PyUnicode_FSConverter(key, &key2) == 0)
3277 goto error;
3278 if (PyUnicode_FSConverter(val, &val2) == 0) {
3279 Py_DECREF(key2);
3280 goto error;
3281 }
Victor Stinnera27dcb72010-04-25 22:39:07 +00003282
3283#if defined(PYOS_OS2)
Victor Stinner97b89882010-05-06 00:25:39 +00003284 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3285 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinnera27dcb72010-04-25 22:39:07 +00003286#endif
Victor Stinner97b89882010-05-06 00:25:39 +00003287 k = PyBytes_AsString(key2);
3288 v = PyBytes_AsString(val2);
3289 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinnera27dcb72010-04-25 22:39:07 +00003290
Victor Stinner97b89882010-05-06 00:25:39 +00003291 p = PyMem_NEW(char, len);
3292 if (p == NULL) {
3293 PyErr_NoMemory();
3294 Py_DECREF(key2);
3295 Py_DECREF(val2);
3296 goto error;
3297 }
3298 PyOS_snprintf(p, len, "%s=%s", k, v);
3299 envlist[envc++] = p;
3300 Py_DECREF(key2);
3301 Py_DECREF(val2);
Victor Stinnera27dcb72010-04-25 22:39:07 +00003302#if defined(PYOS_OS2)
Victor Stinner97b89882010-05-06 00:25:39 +00003303 }
Victor Stinnera27dcb72010-04-25 22:39:07 +00003304#endif
Victor Stinner97b89882010-05-06 00:25:39 +00003305 }
3306 Py_DECREF(vals);
3307 Py_DECREF(keys);
Victor Stinnera27dcb72010-04-25 22:39:07 +00003308
Victor Stinner97b89882010-05-06 00:25:39 +00003309 envlist[envc] = 0;
3310 *envc_ptr = envc;
3311 return envlist;
Victor Stinnera27dcb72010-04-25 22:39:07 +00003312
3313error:
Victor Stinner97b89882010-05-06 00:25:39 +00003314 Py_XDECREF(keys);
3315 Py_XDECREF(vals);
3316 while (--envc >= 0)
3317 PyMem_DEL(envlist[envc]);
3318 PyMem_DEL(envlist);
3319 return NULL;
Victor Stinnera27dcb72010-04-25 22:39:07 +00003320}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003321
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003322PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003323"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003324Execute a path with arguments and environment, replacing current process.\n\
3325\n\
Victor Stinner97b89882010-05-06 00:25:39 +00003326 path: path of executable file\n\
3327 args: tuple or list of arguments\n\
3328 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003329
Barry Warsaw53699e91996-12-10 23:23:01 +00003330static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003331posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003332{
Victor Stinner97b89882010-05-06 00:25:39 +00003333 PyObject *opath;
3334 char *path;
3335 PyObject *argv, *env;
3336 char **argvlist;
3337 char **envlist;
3338 Py_ssize_t i, argc, envc;
3339 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3340 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003341
Victor Stinner97b89882010-05-06 00:25:39 +00003342 /* execve has three arguments: (path, argv, env), where
3343 argv is a list or tuple of strings and env is a dictionary
3344 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003345
Victor Stinner97b89882010-05-06 00:25:39 +00003346 if (!PyArg_ParseTuple(args, "O&OO:execve",
3347 PyUnicode_FSConverter,
3348 &opath, &argv, &env))
3349 return NULL;
3350 path = bytes2str(opath, 1);
3351 if (PyList_Check(argv)) {
3352 argc = PyList_Size(argv);
3353 getitem = PyList_GetItem;
3354 }
3355 else if (PyTuple_Check(argv)) {
3356 argc = PyTuple_Size(argv);
3357 getitem = PyTuple_GetItem;
3358 }
3359 else {
3360 PyErr_SetString(PyExc_TypeError,
3361 "execve() arg 2 must be a tuple or list");
3362 goto fail_0;
3363 }
3364 if (!PyMapping_Check(env)) {
3365 PyErr_SetString(PyExc_TypeError,
3366 "execve() arg 3 must be a mapping object");
3367 goto fail_0;
3368 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003369
Victor Stinner97b89882010-05-06 00:25:39 +00003370 argvlist = PyMem_NEW(char *, argc+1);
3371 if (argvlist == NULL) {
3372 PyErr_NoMemory();
3373 goto fail_0;
3374 }
3375 for (i = 0; i < argc; i++) {
3376 if (!fsconvert_strdup((*getitem)(argv, i),
3377 &argvlist[i]))
3378 {
3379 lastarg = i;
3380 goto fail_1;
3381 }
3382 }
3383 lastarg = argc;
3384 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003385
Victor Stinner97b89882010-05-06 00:25:39 +00003386 envlist = parse_envlist(env, &envc);
3387 if (envlist == NULL)
3388 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003389
Victor Stinner97b89882010-05-06 00:25:39 +00003390 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003391
Victor Stinner97b89882010-05-06 00:25:39 +00003392 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003393
Victor Stinner97b89882010-05-06 00:25:39 +00003394 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003395
Victor Stinner97b89882010-05-06 00:25:39 +00003396 while (--envc >= 0)
3397 PyMem_DEL(envlist[envc]);
3398 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003399 fail_1:
Victor Stinner97b89882010-05-06 00:25:39 +00003400 free_string_array(argvlist, lastarg);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003401 fail_0:
Victor Stinner97b89882010-05-06 00:25:39 +00003402 release_bytes(opath);
3403 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003404}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003405#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003406
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003407
Guido van Rossuma1065681999-01-25 23:20:23 +00003408#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003409PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003410"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003411Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003412\n\
Victor Stinner97b89882010-05-06 00:25:39 +00003413 mode: mode of process creation\n\
3414 path: path of executable file\n\
3415 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003416
3417static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003418posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003419{
Victor Stinner97b89882010-05-06 00:25:39 +00003420 PyObject *opath;
3421 char *path;
3422 PyObject *argv;
3423 char **argvlist;
3424 int mode, i;
3425 Py_ssize_t argc;
3426 Py_intptr_t spawnval;
3427 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003428
Victor Stinner97b89882010-05-06 00:25:39 +00003429 /* spawnv has three arguments: (mode, path, argv), where
3430 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003431
Victor Stinner97b89882010-05-06 00:25:39 +00003432 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3433 PyUnicode_FSConverter,
3434 &opath, &argv))
3435 return NULL;
3436 path = bytes2str(opath, 1);
3437 if (PyList_Check(argv)) {
3438 argc = PyList_Size(argv);
3439 getitem = PyList_GetItem;
3440 }
3441 else if (PyTuple_Check(argv)) {
3442 argc = PyTuple_Size(argv);
3443 getitem = PyTuple_GetItem;
3444 }
3445 else {
3446 PyErr_SetString(PyExc_TypeError,
3447 "spawnv() arg 2 must be a tuple or list");
3448 release_bytes(opath);
3449 return NULL;
3450 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003451
Victor Stinner97b89882010-05-06 00:25:39 +00003452 argvlist = PyMem_NEW(char *, argc+1);
3453 if (argvlist == NULL) {
3454 release_bytes(opath);
3455 return PyErr_NoMemory();
3456 }
3457 for (i = 0; i < argc; i++) {
3458 if (!fsconvert_strdup((*getitem)(argv, i),
3459 &argvlist[i])) {
3460 free_string_array(argvlist, i);
3461 PyErr_SetString(
3462 PyExc_TypeError,
3463 "spawnv() arg 2 must contain only strings");
3464 release_bytes(opath);
3465 return NULL;
3466 }
3467 }
3468 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003469
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003470#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner97b89882010-05-06 00:25:39 +00003471 Py_BEGIN_ALLOW_THREADS
3472 spawnval = spawnv(mode, path, argvlist);
3473 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003474#else
Victor Stinner97b89882010-05-06 00:25:39 +00003475 if (mode == _OLD_P_OVERLAY)
3476 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003477
Victor Stinner97b89882010-05-06 00:25:39 +00003478 Py_BEGIN_ALLOW_THREADS
3479 spawnval = _spawnv(mode, path, argvlist);
3480 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003481#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003482
Victor Stinner97b89882010-05-06 00:25:39 +00003483 free_string_array(argvlist, argc);
3484 release_bytes(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003485
Victor Stinner97b89882010-05-06 00:25:39 +00003486 if (spawnval == -1)
3487 return posix_error();
3488 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003489#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner97b89882010-05-06 00:25:39 +00003490 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003491#else
Victor Stinner97b89882010-05-06 00:25:39 +00003492 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003493#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003494}
3495
3496
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003497PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003498"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003499Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003500\n\
Victor Stinner97b89882010-05-06 00:25:39 +00003501 mode: mode of process creation\n\
3502 path: path of executable file\n\
3503 args: tuple or list of arguments\n\
3504 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003505
3506static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003507posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003508{
Victor Stinner97b89882010-05-06 00:25:39 +00003509 PyObject *opath;
3510 char *path;
3511 PyObject *argv, *env;
3512 char **argvlist;
3513 char **envlist;
3514 PyObject *res = NULL;
Antoine Pitrou835b4452010-08-15 18:32:16 +00003515 int mode;
3516 Py_ssize_t argc, i, envc;
Victor Stinner97b89882010-05-06 00:25:39 +00003517 Py_intptr_t spawnval;
3518 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3519 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003520
Victor Stinner97b89882010-05-06 00:25:39 +00003521 /* spawnve has four arguments: (mode, path, argv, env), where
3522 argv is a list or tuple of strings and env is a dictionary
3523 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003524
Victor Stinner97b89882010-05-06 00:25:39 +00003525 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3526 PyUnicode_FSConverter,
3527 &opath, &argv, &env))
3528 return NULL;
3529 path = bytes2str(opath, 1);
3530 if (PyList_Check(argv)) {
3531 argc = PyList_Size(argv);
3532 getitem = PyList_GetItem;
3533 }
3534 else if (PyTuple_Check(argv)) {
3535 argc = PyTuple_Size(argv);
3536 getitem = PyTuple_GetItem;
3537 }
3538 else {
3539 PyErr_SetString(PyExc_TypeError,
3540 "spawnve() arg 2 must be a tuple or list");
3541 goto fail_0;
3542 }
3543 if (!PyMapping_Check(env)) {
3544 PyErr_SetString(PyExc_TypeError,
3545 "spawnve() arg 3 must be a mapping object");
3546 goto fail_0;
3547 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003548
Victor Stinner97b89882010-05-06 00:25:39 +00003549 argvlist = PyMem_NEW(char *, argc+1);
3550 if (argvlist == NULL) {
3551 PyErr_NoMemory();
3552 goto fail_0;
3553 }
3554 for (i = 0; i < argc; i++) {
3555 if (!fsconvert_strdup((*getitem)(argv, i),
3556 &argvlist[i]))
3557 {
3558 lastarg = i;
3559 goto fail_1;
3560 }
3561 }
3562 lastarg = argc;
3563 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003564
Victor Stinner97b89882010-05-06 00:25:39 +00003565 envlist = parse_envlist(env, &envc);
3566 if (envlist == NULL)
3567 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003568
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003569#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner97b89882010-05-06 00:25:39 +00003570 Py_BEGIN_ALLOW_THREADS
3571 spawnval = spawnve(mode, path, argvlist, envlist);
3572 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003573#else
Victor Stinner97b89882010-05-06 00:25:39 +00003574 if (mode == _OLD_P_OVERLAY)
3575 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003576
Victor Stinner97b89882010-05-06 00:25:39 +00003577 Py_BEGIN_ALLOW_THREADS
3578 spawnval = _spawnve(mode, path, argvlist, envlist);
3579 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003580#endif
Tim Peters25059d32001-12-07 20:35:43 +00003581
Victor Stinner97b89882010-05-06 00:25:39 +00003582 if (spawnval == -1)
3583 (void) posix_error();
3584 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003585#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner97b89882010-05-06 00:25:39 +00003586 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003587#else
Victor Stinner97b89882010-05-06 00:25:39 +00003588 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003589#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003590
Victor Stinner97b89882010-05-06 00:25:39 +00003591 while (--envc >= 0)
3592 PyMem_DEL(envlist[envc]);
3593 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003594 fail_1:
Victor Stinner97b89882010-05-06 00:25:39 +00003595 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003596 fail_0:
Victor Stinner97b89882010-05-06 00:25:39 +00003597 release_bytes(opath);
3598 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003599}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003600
3601/* OS/2 supports spawnvp & spawnvpe natively */
3602#if defined(PYOS_OS2)
3603PyDoc_STRVAR(posix_spawnvp__doc__,
3604"spawnvp(mode, file, args)\n\n\
3605Execute the program 'file' in a new process, using the environment\n\
3606search path to find the file.\n\
3607\n\
Victor Stinner97b89882010-05-06 00:25:39 +00003608 mode: mode of process creation\n\
3609 file: executable file name\n\
3610 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003611
3612static PyObject *
3613posix_spawnvp(PyObject *self, PyObject *args)
3614{
Victor Stinner97b89882010-05-06 00:25:39 +00003615 PyObject *opath;
3616 char *path;
3617 PyObject *argv;
3618 char **argvlist;
3619 int mode, i, argc;
3620 Py_intptr_t spawnval;
3621 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003622
Victor Stinner97b89882010-05-06 00:25:39 +00003623 /* spawnvp has three arguments: (mode, path, argv), where
3624 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003625
Victor Stinner97b89882010-05-06 00:25:39 +00003626 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3627 PyUnicode_FSConverter,
3628 &opath, &argv))
3629 return NULL;
3630 path = bytes2str(opath);
3631 if (PyList_Check(argv)) {
3632 argc = PyList_Size(argv);
3633 getitem = PyList_GetItem;
3634 }
3635 else if (PyTuple_Check(argv)) {
3636 argc = PyTuple_Size(argv);
3637 getitem = PyTuple_GetItem;
3638 }
3639 else {
3640 PyErr_SetString(PyExc_TypeError,
3641 "spawnvp() arg 2 must be a tuple or list");
3642 release_bytes(opath);
3643 return NULL;
3644 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003645
Victor Stinner97b89882010-05-06 00:25:39 +00003646 argvlist = PyMem_NEW(char *, argc+1);
3647 if (argvlist == NULL) {
3648 release_bytes(opath);
3649 return PyErr_NoMemory();
3650 }
3651 for (i = 0; i < argc; i++) {
3652 if (!fsconvert_strdup((*getitem)(argv, i),
3653 &argvlist[i])) {
3654 free_string_array(argvlist, i);
3655 PyErr_SetString(
3656 PyExc_TypeError,
3657 "spawnvp() arg 2 must contain only strings");
3658 release_bytes(opath);
3659 return NULL;
3660 }
3661 }
3662 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003663
Victor Stinner97b89882010-05-06 00:25:39 +00003664 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003665#if defined(PYCC_GCC)
Victor Stinner97b89882010-05-06 00:25:39 +00003666 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003667#else
Victor Stinner97b89882010-05-06 00:25:39 +00003668 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003669#endif
Victor Stinner97b89882010-05-06 00:25:39 +00003670 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003671
Victor Stinner97b89882010-05-06 00:25:39 +00003672 free_string_array(argvlist, argc);
3673 release_bytes(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003674
Victor Stinner97b89882010-05-06 00:25:39 +00003675 if (spawnval == -1)
3676 return posix_error();
3677 else
3678 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003679}
3680
3681
3682PyDoc_STRVAR(posix_spawnvpe__doc__,
3683"spawnvpe(mode, file, args, env)\n\n\
3684Execute the program 'file' in a new process, using the environment\n\
3685search path to find the file.\n\
3686\n\
Victor Stinner97b89882010-05-06 00:25:39 +00003687 mode: mode of process creation\n\
3688 file: executable file name\n\
3689 args: tuple or list of arguments\n\
3690 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003691
3692static PyObject *
3693posix_spawnvpe(PyObject *self, PyObject *args)
3694{
Victor Stinner97b89882010-05-06 00:25:39 +00003695 PyObject *opath
3696 char *path;
3697 PyObject *argv, *env;
3698 char **argvlist;
3699 char **envlist;
3700 PyObject *res=NULL;
Antoine Pitrou835b4452010-08-15 18:32:16 +00003701 int mode;
3702 Py_ssize_t argc, i, envc;
Victor Stinner97b89882010-05-06 00:25:39 +00003703 Py_intptr_t spawnval;
3704 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3705 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003706
Victor Stinner97b89882010-05-06 00:25:39 +00003707 /* spawnvpe has four arguments: (mode, path, argv, env), where
3708 argv is a list or tuple of strings and env is a dictionary
3709 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003710
Victor Stinner97b89882010-05-06 00:25:39 +00003711 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3712 PyUnicode_FSConverter,
3713 &opath, &argv, &env))
3714 return NULL;
3715 path = bytes2str(opath);
3716 if (PyList_Check(argv)) {
3717 argc = PyList_Size(argv);
3718 getitem = PyList_GetItem;
3719 }
3720 else if (PyTuple_Check(argv)) {
3721 argc = PyTuple_Size(argv);
3722 getitem = PyTuple_GetItem;
3723 }
3724 else {
3725 PyErr_SetString(PyExc_TypeError,
3726 "spawnvpe() arg 2 must be a tuple or list");
3727 goto fail_0;
3728 }
3729 if (!PyMapping_Check(env)) {
3730 PyErr_SetString(PyExc_TypeError,
3731 "spawnvpe() arg 3 must be a mapping object");
3732 goto fail_0;
3733 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003734
Victor Stinner97b89882010-05-06 00:25:39 +00003735 argvlist = PyMem_NEW(char *, argc+1);
3736 if (argvlist == NULL) {
3737 PyErr_NoMemory();
3738 goto fail_0;
3739 }
3740 for (i = 0; i < argc; i++) {
3741 if (!fsconvert_strdup((*getitem)(argv, i),
3742 &argvlist[i]))
3743 {
3744 lastarg = i;
3745 goto fail_1;
3746 }
3747 }
3748 lastarg = argc;
3749 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003750
Victor Stinner97b89882010-05-06 00:25:39 +00003751 envlist = parse_envlist(env, &envc);
3752 if (envlist == NULL)
3753 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003754
Victor Stinner97b89882010-05-06 00:25:39 +00003755 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003756#if defined(PYCC_GCC)
Victor Stinner97b89882010-05-06 00:25:39 +00003757 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003758#else
Victor Stinner97b89882010-05-06 00:25:39 +00003759 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003760#endif
Victor Stinner97b89882010-05-06 00:25:39 +00003761 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003762
Victor Stinner97b89882010-05-06 00:25:39 +00003763 if (spawnval == -1)
3764 (void) posix_error();
3765 else
3766 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003767
Victor Stinner97b89882010-05-06 00:25:39 +00003768 while (--envc >= 0)
3769 PyMem_DEL(envlist[envc]);
3770 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003771 fail_1:
Victor Stinner97b89882010-05-06 00:25:39 +00003772 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003773 fail_0:
Victor Stinner97b89882010-05-06 00:25:39 +00003774 release_bytes(opath);
3775 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003776}
3777#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003778#endif /* HAVE_SPAWNV */
3779
3780
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003781#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003782PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003783"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003784Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3785\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003786Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003787
3788static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003789posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003790{
Victor Stinner97b89882010-05-06 00:25:39 +00003791 pid_t pid;
3792 int result;
3793 _PyImport_AcquireLock();
3794 pid = fork1();
3795 result = _PyImport_ReleaseLock();
3796 if (pid == -1)
3797 return posix_error();
3798 if (pid == 0)
3799 PyOS_AfterFork();
3800 if (result < 0) {
3801 /* Don't clobber the OSError if the fork failed. */
3802 PyErr_SetString(PyExc_RuntimeError,
3803 "not holding the import lock");
3804 return NULL;
3805 }
3806 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003807}
3808#endif
3809
3810
Guido van Rossumad0ee831995-03-01 10:34:45 +00003811#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003812PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003813"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003814Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003815Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003816
Barry Warsaw53699e91996-12-10 23:23:01 +00003817static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003818posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003819{
Victor Stinner97b89882010-05-06 00:25:39 +00003820 pid_t pid;
3821 int result;
3822 _PyImport_AcquireLock();
3823 pid = fork();
3824 result = _PyImport_ReleaseLock();
3825 if (pid == -1)
3826 return posix_error();
3827 if (pid == 0)
3828 PyOS_AfterFork();
3829 if (result < 0) {
3830 /* Don't clobber the OSError if the fork failed. */
3831 PyErr_SetString(PyExc_RuntimeError,
3832 "not holding the import lock");
3833 return NULL;
3834 }
3835 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003836}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003837#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003838
Neal Norwitzb59798b2003-03-21 01:43:31 +00003839/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003840/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3841#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003842#define DEV_PTY_FILE "/dev/ptc"
3843#define HAVE_DEV_PTMX
3844#else
3845#define DEV_PTY_FILE "/dev/ptmx"
3846#endif
3847
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003848#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003849#ifdef HAVE_PTY_H
3850#include <pty.h>
3851#else
3852#ifdef HAVE_LIBUTIL_H
3853#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003854#endif /* HAVE_LIBUTIL_H */
3855#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003856#ifdef HAVE_STROPTS_H
3857#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003858#endif
3859#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003860
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003861#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003862PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003863"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003864Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003865
3866static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003867posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003868{
Victor Stinner97b89882010-05-06 00:25:39 +00003869 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003870#ifndef HAVE_OPENPTY
Victor Stinner97b89882010-05-06 00:25:39 +00003871 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003872#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003873#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner97b89882010-05-06 00:25:39 +00003874 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003875#ifdef sun
Victor Stinner97b89882010-05-06 00:25:39 +00003876 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003877#endif
3878#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003879
Thomas Wouters70c21a12000-07-14 14:28:33 +00003880#ifdef HAVE_OPENPTY
Victor Stinner97b89882010-05-06 00:25:39 +00003881 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3882 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003883#elif defined(HAVE__GETPTY)
Victor Stinner97b89882010-05-06 00:25:39 +00003884 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3885 if (slave_name == NULL)
3886 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00003887
Victor Stinner97b89882010-05-06 00:25:39 +00003888 slave_fd = open(slave_name, O_RDWR);
3889 if (slave_fd < 0)
3890 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003891#else
Victor Stinner97b89882010-05-06 00:25:39 +00003892 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3893 if (master_fd < 0)
3894 return posix_error();
3895 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3896 /* change permission of slave */
3897 if (grantpt(master_fd) < 0) {
3898 PyOS_setsig(SIGCHLD, sig_saved);
3899 return posix_error();
3900 }
3901 /* unlock slave */
3902 if (unlockpt(master_fd) < 0) {
3903 PyOS_setsig(SIGCHLD, sig_saved);
3904 return posix_error();
3905 }
3906 PyOS_setsig(SIGCHLD, sig_saved);
3907 slave_name = ptsname(master_fd); /* get name of slave */
3908 if (slave_name == NULL)
3909 return posix_error();
3910 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3911 if (slave_fd < 0)
3912 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003913#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner97b89882010-05-06 00:25:39 +00003914 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3915 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003916#ifndef __hpux
Victor Stinner97b89882010-05-06 00:25:39 +00003917 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003918#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003919#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003920#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003921
Victor Stinner97b89882010-05-06 00:25:39 +00003922 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003923
Fred Drake8cef4cf2000-06-28 16:40:38 +00003924}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003925#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003926
3927#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003928PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003929"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003930Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3931Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003932To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003933
3934static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003935posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003936{
Victor Stinner97b89882010-05-06 00:25:39 +00003937 int master_fd = -1, result;
3938 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003939
Victor Stinner97b89882010-05-06 00:25:39 +00003940 _PyImport_AcquireLock();
3941 pid = forkpty(&master_fd, NULL, NULL, NULL);
3942 result = _PyImport_ReleaseLock();
3943 if (pid == -1)
3944 return posix_error();
3945 if (pid == 0)
3946 PyOS_AfterFork();
3947 if (result < 0) {
3948 /* Don't clobber the OSError if the fork failed. */
3949 PyErr_SetString(PyExc_RuntimeError,
3950 "not holding the import lock");
3951 return NULL;
3952 }
3953 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003954}
3955#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003956
Guido van Rossumad0ee831995-03-01 10:34:45 +00003957#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003958PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003959"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003960Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003961
Barry Warsaw53699e91996-12-10 23:23:01 +00003962static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003963posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003964{
Victor Stinner97b89882010-05-06 00:25:39 +00003965 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003966}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003967#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003968
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003969
Guido van Rossumad0ee831995-03-01 10:34:45 +00003970#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003971PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003972"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003973Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003974
Barry Warsaw53699e91996-12-10 23:23:01 +00003975static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003976posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003977{
Victor Stinner97b89882010-05-06 00:25:39 +00003978 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003979}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003980#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003981
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003982
Guido van Rossumad0ee831995-03-01 10:34:45 +00003983#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003984PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003985"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003986Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003987
Barry Warsaw53699e91996-12-10 23:23:01 +00003988static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003989posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003990{
Victor Stinner97b89882010-05-06 00:25:39 +00003991 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003992}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003993#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003994
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003995
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003996PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003997"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003998Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003999
Barry Warsaw53699e91996-12-10 23:23:01 +00004000static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004001posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004002{
Victor Stinner97b89882010-05-06 00:25:39 +00004003 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004004}
4005
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004006
Fred Drakec9680921999-12-13 16:37:25 +00004007#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004008PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004009"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004010Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004011
4012static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004013posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004014{
4015 PyObject *result = NULL;
4016
Fred Drakec9680921999-12-13 16:37:25 +00004017#ifdef NGROUPS_MAX
4018#define MAX_GROUPS NGROUPS_MAX
4019#else
Victor Stinner97b89882010-05-06 00:25:39 +00004020 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004021#define MAX_GROUPS 64
4022#endif
Victor Stinner97b89882010-05-06 00:25:39 +00004023 gid_t grouplist[MAX_GROUPS];
Ronald Oussoren47076f72010-07-23 15:46:03 +00004024
4025 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
4026 * This is a helper variable to store the intermediate result when
4027 * that happens.
4028 *
4029 * To keep the code readable the OSX behaviour is unconditional,
4030 * according to the POSIX spec this should be safe on all unix-y
4031 * systems.
4032 */
4033 gid_t* alt_grouplist = grouplist;
Victor Stinner97b89882010-05-06 00:25:39 +00004034 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004035
Victor Stinner97b89882010-05-06 00:25:39 +00004036 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussoren47076f72010-07-23 15:46:03 +00004037 if (n < 0) {
4038 if (errno == EINVAL) {
4039 n = getgroups(0, NULL);
4040 if (n == -1) {
4041 return posix_error();
4042 }
4043 if (n == 0) {
4044 /* Avoid malloc(0) */
4045 alt_grouplist = grouplist;
4046 } else {
4047 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4048 if (alt_grouplist == NULL) {
4049 errno = EINVAL;
4050 return posix_error();
4051 }
4052 n = getgroups(n, alt_grouplist);
4053 if (n == -1) {
4054 PyMem_Free(alt_grouplist);
4055 return posix_error();
4056 }
4057 }
4058 } else {
4059 return posix_error();
4060 }
4061 }
4062 result = PyList_New(n);
4063 if (result != NULL) {
Victor Stinner97b89882010-05-06 00:25:39 +00004064 int i;
4065 for (i = 0; i < n; ++i) {
Ronald Oussoren47076f72010-07-23 15:46:03 +00004066 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner97b89882010-05-06 00:25:39 +00004067 if (o == NULL) {
Stefan Krah67733312010-11-26 17:04:40 +00004068 Py_DECREF(result);
4069 result = NULL;
4070 break;
Fred Drakec9680921999-12-13 16:37:25 +00004071 }
Victor Stinner97b89882010-05-06 00:25:39 +00004072 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004073 }
Ronald Oussoren47076f72010-07-23 15:46:03 +00004074 }
4075
4076 if (alt_grouplist != grouplist) {
4077 PyMem_Free(alt_grouplist);
Victor Stinner97b89882010-05-06 00:25:39 +00004078 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004079
Fred Drakec9680921999-12-13 16:37:25 +00004080 return result;
4081}
4082#endif
4083
Martin v. Löwis606edc12002-06-13 21:09:11 +00004084#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004085PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004086"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004087Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004088
4089static PyObject *
4090posix_getpgid(PyObject *self, PyObject *args)
4091{
Victor Stinner97b89882010-05-06 00:25:39 +00004092 pid_t pid, pgid;
4093 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
4094 return NULL;
4095 pgid = getpgid(pid);
4096 if (pgid < 0)
4097 return posix_error();
4098 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004099}
4100#endif /* HAVE_GETPGID */
4101
4102
Guido van Rossumb6775db1994-08-01 11:34:53 +00004103#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004104PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004105"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004106Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004107
Barry Warsaw53699e91996-12-10 23:23:01 +00004108static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004109posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004110{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004111#ifdef GETPGRP_HAVE_ARG
Victor Stinner97b89882010-05-06 00:25:39 +00004112 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004113#else /* GETPGRP_HAVE_ARG */
Victor Stinner97b89882010-05-06 00:25:39 +00004114 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004115#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004116}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004117#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004118
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004119
Guido van Rossumb6775db1994-08-01 11:34:53 +00004120#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004121PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004122"setpgrp()\n\n\
Senthil Kumaran28fdadb2010-06-17 16:51:08 +00004123Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004124
Barry Warsaw53699e91996-12-10 23:23:01 +00004125static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004126posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004127{
Guido van Rossum64933891994-10-20 21:56:42 +00004128#ifdef SETPGRP_HAVE_ARG
Victor Stinner97b89882010-05-06 00:25:39 +00004129 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004130#else /* SETPGRP_HAVE_ARG */
Victor Stinner97b89882010-05-06 00:25:39 +00004131 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004132#endif /* SETPGRP_HAVE_ARG */
Victor Stinner97b89882010-05-06 00:25:39 +00004133 return posix_error();
4134 Py_INCREF(Py_None);
4135 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004136}
4137
Guido van Rossumb6775db1994-08-01 11:34:53 +00004138#endif /* HAVE_SETPGRP */
4139
Guido van Rossumad0ee831995-03-01 10:34:45 +00004140#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004141PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004142"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004143Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004144
Barry Warsaw53699e91996-12-10 23:23:01 +00004145static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004146posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004147{
Victor Stinner97b89882010-05-06 00:25:39 +00004148 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004149}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004150#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004151
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004152
Fred Drake12c6e2d1999-12-14 21:25:03 +00004153#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004154PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004155"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004156Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004157
4158static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004159posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004160{
Victor Stinner97b89882010-05-06 00:25:39 +00004161 PyObject *result = NULL;
4162 char *name;
4163 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004164
Victor Stinner97b89882010-05-06 00:25:39 +00004165 errno = 0;
4166 name = getlogin();
4167 if (name == NULL) {
4168 if (errno)
Victor Stinner85675992010-08-15 09:35:13 +00004169 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004170 else
Victor Stinner85675992010-08-15 09:35:13 +00004171 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner97b89882010-05-06 00:25:39 +00004172 }
4173 else
Victor Stinner85675992010-08-15 09:35:13 +00004174 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner97b89882010-05-06 00:25:39 +00004175 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004176
Fred Drake12c6e2d1999-12-14 21:25:03 +00004177 return result;
4178}
4179#endif
4180
Guido van Rossumad0ee831995-03-01 10:34:45 +00004181#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004182PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004183"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004184Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004185
Barry Warsaw53699e91996-12-10 23:23:01 +00004186static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004187posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004188{
Victor Stinner97b89882010-05-06 00:25:39 +00004189 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004190}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004191#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004192
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004193
Guido van Rossumad0ee831995-03-01 10:34:45 +00004194#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004195PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004196"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004197Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004198
Barry Warsaw53699e91996-12-10 23:23:01 +00004199static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004200posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004201{
Victor Stinner97b89882010-05-06 00:25:39 +00004202 pid_t pid;
4203 int sig;
4204 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
4205 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004206#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004207 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4208 APIRET rc;
4209 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004210 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004211
4212 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4213 APIRET rc;
4214 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004215 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004216
4217 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004218 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004219#else
Victor Stinner97b89882010-05-06 00:25:39 +00004220 if (kill(pid, sig) == -1)
4221 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004222#endif
Victor Stinner97b89882010-05-06 00:25:39 +00004223 Py_INCREF(Py_None);
4224 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004225}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004226#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004227
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004228#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004229PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004230"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004231Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004232
4233static PyObject *
4234posix_killpg(PyObject *self, PyObject *args)
4235{
Victor Stinner97b89882010-05-06 00:25:39 +00004236 int sig;
4237 pid_t pgid;
4238 /* XXX some man pages make the `pgid` parameter an int, others
4239 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4240 take the same type. Moreover, pid_t is always at least as wide as
4241 int (else compilation of this module fails), which is safe. */
4242 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
4243 return NULL;
4244 if (killpg(pgid, sig) == -1)
4245 return posix_error();
4246 Py_INCREF(Py_None);
4247 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004248}
4249#endif
4250
Guido van Rossumc0125471996-06-28 18:55:32 +00004251#ifdef HAVE_PLOCK
4252
4253#ifdef HAVE_SYS_LOCK_H
4254#include <sys/lock.h>
4255#endif
4256
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004257PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004258"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004259Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004260
Barry Warsaw53699e91996-12-10 23:23:01 +00004261static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004262posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004263{
Victor Stinner97b89882010-05-06 00:25:39 +00004264 int op;
4265 if (!PyArg_ParseTuple(args, "i:plock", &op))
4266 return NULL;
4267 if (plock(op) == -1)
4268 return posix_error();
4269 Py_INCREF(Py_None);
4270 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004271}
4272#endif
4273
Guido van Rossumb6775db1994-08-01 11:34:53 +00004274#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004275PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004276"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004277Set the current process's user id.");
4278
Barry Warsaw53699e91996-12-10 23:23:01 +00004279static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004280posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004281{
Victor Stinner97b89882010-05-06 00:25:39 +00004282 long uid_arg;
4283 uid_t uid;
4284 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
4285 return NULL;
4286 uid = uid_arg;
4287 if (uid != uid_arg) {
4288 PyErr_SetString(PyExc_OverflowError, "user id too big");
4289 return NULL;
4290 }
4291 if (setuid(uid) < 0)
4292 return posix_error();
4293 Py_INCREF(Py_None);
4294 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004295}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004296#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004297
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004298
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004299#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004300PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004301"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004302Set the current process's effective user id.");
4303
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004304static PyObject *
4305posix_seteuid (PyObject *self, PyObject *args)
4306{
Victor Stinner97b89882010-05-06 00:25:39 +00004307 long euid_arg;
4308 uid_t euid;
4309 if (!PyArg_ParseTuple(args, "l", &euid_arg))
4310 return NULL;
4311 euid = euid_arg;
4312 if (euid != euid_arg) {
4313 PyErr_SetString(PyExc_OverflowError, "user id too big");
4314 return NULL;
4315 }
4316 if (seteuid(euid) < 0) {
4317 return posix_error();
4318 } else {
4319 Py_INCREF(Py_None);
4320 return Py_None;
4321 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004322}
4323#endif /* HAVE_SETEUID */
4324
4325#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004326PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004327"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004328Set the current process's effective group id.");
4329
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004330static PyObject *
4331posix_setegid (PyObject *self, PyObject *args)
4332{
Victor Stinner97b89882010-05-06 00:25:39 +00004333 long egid_arg;
4334 gid_t egid;
4335 if (!PyArg_ParseTuple(args, "l", &egid_arg))
4336 return NULL;
4337 egid = egid_arg;
4338 if (egid != egid_arg) {
4339 PyErr_SetString(PyExc_OverflowError, "group id too big");
4340 return NULL;
4341 }
4342 if (setegid(egid) < 0) {
4343 return posix_error();
4344 } else {
4345 Py_INCREF(Py_None);
4346 return Py_None;
4347 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004348}
4349#endif /* HAVE_SETEGID */
4350
4351#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004352PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004353"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004354Set the current process's real and effective user ids.");
4355
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004356static PyObject *
4357posix_setreuid (PyObject *self, PyObject *args)
4358{
Victor Stinner97b89882010-05-06 00:25:39 +00004359 long ruid_arg, euid_arg;
4360 uid_t ruid, euid;
4361 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
4362 return NULL;
4363 if (ruid_arg == -1)
4364 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
4365 else
4366 ruid = ruid_arg; /* otherwise, assign from our long */
4367 if (euid_arg == -1)
4368 euid = (uid_t)-1;
4369 else
4370 euid = euid_arg;
4371 if ((euid_arg != -1 && euid != euid_arg) ||
4372 (ruid_arg != -1 && ruid != ruid_arg)) {
4373 PyErr_SetString(PyExc_OverflowError, "user id too big");
4374 return NULL;
4375 }
4376 if (setreuid(ruid, euid) < 0) {
4377 return posix_error();
4378 } else {
4379 Py_INCREF(Py_None);
4380 return Py_None;
4381 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004382}
4383#endif /* HAVE_SETREUID */
4384
4385#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004386PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004387"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004388Set the current process's real and effective group ids.");
4389
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004390static PyObject *
4391posix_setregid (PyObject *self, PyObject *args)
4392{
Victor Stinner97b89882010-05-06 00:25:39 +00004393 long rgid_arg, egid_arg;
4394 gid_t rgid, egid;
4395 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
4396 return NULL;
4397 if (rgid_arg == -1)
4398 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
4399 else
4400 rgid = rgid_arg; /* otherwise, assign from our long */
4401 if (egid_arg == -1)
4402 egid = (gid_t)-1;
4403 else
4404 egid = egid_arg;
4405 if ((egid_arg != -1 && egid != egid_arg) ||
4406 (rgid_arg != -1 && rgid != rgid_arg)) {
4407 PyErr_SetString(PyExc_OverflowError, "group id too big");
4408 return NULL;
4409 }
4410 if (setregid(rgid, egid) < 0) {
4411 return posix_error();
4412 } else {
4413 Py_INCREF(Py_None);
4414 return Py_None;
4415 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004416}
4417#endif /* HAVE_SETREGID */
4418
Guido van Rossumb6775db1994-08-01 11:34:53 +00004419#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004420PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004421"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004422Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004423
Barry Warsaw53699e91996-12-10 23:23:01 +00004424static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004425posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004426{
Victor Stinner97b89882010-05-06 00:25:39 +00004427 long gid_arg;
4428 gid_t gid;
4429 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
4430 return NULL;
4431 gid = gid_arg;
4432 if (gid != gid_arg) {
4433 PyErr_SetString(PyExc_OverflowError, "group id too big");
4434 return NULL;
4435 }
4436 if (setgid(gid) < 0)
4437 return posix_error();
4438 Py_INCREF(Py_None);
4439 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004440}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004441#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004442
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004443#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004444PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004445"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004446Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004447
4448static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004449posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004450{
Victor Stinner97b89882010-05-06 00:25:39 +00004451 int i, len;
4452 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004453
Victor Stinner97b89882010-05-06 00:25:39 +00004454 if (!PySequence_Check(groups)) {
4455 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4456 return NULL;
4457 }
4458 len = PySequence_Size(groups);
4459 if (len > MAX_GROUPS) {
4460 PyErr_SetString(PyExc_ValueError, "too many groups");
4461 return NULL;
4462 }
4463 for(i = 0; i < len; i++) {
4464 PyObject *elem;
4465 elem = PySequence_GetItem(groups, i);
4466 if (!elem)
4467 return NULL;
4468 if (!PyLong_Check(elem)) {
4469 PyErr_SetString(PyExc_TypeError,
4470 "groups must be integers");
4471 Py_DECREF(elem);
4472 return NULL;
4473 } else {
4474 unsigned long x = PyLong_AsUnsignedLong(elem);
4475 if (PyErr_Occurred()) {
4476 PyErr_SetString(PyExc_TypeError,
4477 "group id too big");
4478 Py_DECREF(elem);
4479 return NULL;
4480 }
4481 grouplist[i] = x;
4482 /* read back the value to see if it fitted in gid_t */
4483 if (grouplist[i] != x) {
4484 PyErr_SetString(PyExc_TypeError,
4485 "group id too big");
4486 Py_DECREF(elem);
4487 return NULL;
4488 }
4489 }
4490 Py_DECREF(elem);
4491 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004492
Victor Stinner97b89882010-05-06 00:25:39 +00004493 if (setgroups(len, grouplist) < 0)
4494 return posix_error();
4495 Py_INCREF(Py_None);
4496 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004497}
4498#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004499
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004500#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4501static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004502wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004503{
Victor Stinner97b89882010-05-06 00:25:39 +00004504 PyObject *result;
4505 static PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004506
Victor Stinner97b89882010-05-06 00:25:39 +00004507 if (pid == -1)
4508 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004509
Victor Stinner97b89882010-05-06 00:25:39 +00004510 if (struct_rusage == NULL) {
4511 PyObject *m = PyImport_ImportModuleNoBlock("resource");
4512 if (m == NULL)
4513 return NULL;
4514 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4515 Py_DECREF(m);
4516 if (struct_rusage == NULL)
4517 return NULL;
4518 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004519
Victor Stinner97b89882010-05-06 00:25:39 +00004520 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4521 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4522 if (!result)
4523 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004524
4525#ifndef doubletime
4526#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4527#endif
4528
Victor Stinner97b89882010-05-06 00:25:39 +00004529 PyStructSequence_SET_ITEM(result, 0,
4530 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4531 PyStructSequence_SET_ITEM(result, 1,
4532 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004533#define SET_INT(result, index, value)\
Victor Stinner97b89882010-05-06 00:25:39 +00004534 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
4535 SET_INT(result, 2, ru->ru_maxrss);
4536 SET_INT(result, 3, ru->ru_ixrss);
4537 SET_INT(result, 4, ru->ru_idrss);
4538 SET_INT(result, 5, ru->ru_isrss);
4539 SET_INT(result, 6, ru->ru_minflt);
4540 SET_INT(result, 7, ru->ru_majflt);
4541 SET_INT(result, 8, ru->ru_nswap);
4542 SET_INT(result, 9, ru->ru_inblock);
4543 SET_INT(result, 10, ru->ru_oublock);
4544 SET_INT(result, 11, ru->ru_msgsnd);
4545 SET_INT(result, 12, ru->ru_msgrcv);
4546 SET_INT(result, 13, ru->ru_nsignals);
4547 SET_INT(result, 14, ru->ru_nvcsw);
4548 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004549#undef SET_INT
4550
Victor Stinner97b89882010-05-06 00:25:39 +00004551 if (PyErr_Occurred()) {
4552 Py_DECREF(result);
4553 return NULL;
4554 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004555
Victor Stinner97b89882010-05-06 00:25:39 +00004556 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004557}
4558#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4559
4560#ifdef HAVE_WAIT3
4561PyDoc_STRVAR(posix_wait3__doc__,
4562"wait3(options) -> (pid, status, rusage)\n\n\
4563Wait for completion of a child process.");
4564
4565static PyObject *
4566posix_wait3(PyObject *self, PyObject *args)
4567{
Victor Stinner97b89882010-05-06 00:25:39 +00004568 pid_t pid;
4569 int options;
4570 struct rusage ru;
4571 WAIT_TYPE status;
4572 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004573
Victor Stinner97b89882010-05-06 00:25:39 +00004574 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4575 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004576
Victor Stinner97b89882010-05-06 00:25:39 +00004577 Py_BEGIN_ALLOW_THREADS
4578 pid = wait3(&status, options, &ru);
4579 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004580
Victor Stinner97b89882010-05-06 00:25:39 +00004581 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004582}
4583#endif /* HAVE_WAIT3 */
4584
4585#ifdef HAVE_WAIT4
4586PyDoc_STRVAR(posix_wait4__doc__,
4587"wait4(pid, options) -> (pid, status, rusage)\n\n\
4588Wait for completion of a given child process.");
4589
4590static PyObject *
4591posix_wait4(PyObject *self, PyObject *args)
4592{
Victor Stinner97b89882010-05-06 00:25:39 +00004593 pid_t pid;
4594 int options;
4595 struct rusage ru;
4596 WAIT_TYPE status;
4597 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004598
Victor Stinner97b89882010-05-06 00:25:39 +00004599 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
4600 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004601
Victor Stinner97b89882010-05-06 00:25:39 +00004602 Py_BEGIN_ALLOW_THREADS
4603 pid = wait4(pid, &status, options, &ru);
4604 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004605
Victor Stinner97b89882010-05-06 00:25:39 +00004606 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004607}
4608#endif /* HAVE_WAIT4 */
4609
Guido van Rossumb6775db1994-08-01 11:34:53 +00004610#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004611PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004612"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004613Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004614
Barry Warsaw53699e91996-12-10 23:23:01 +00004615static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004616posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004617{
Victor Stinner97b89882010-05-06 00:25:39 +00004618 pid_t pid;
4619 int options;
4620 WAIT_TYPE status;
4621 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004622
Victor Stinner97b89882010-05-06 00:25:39 +00004623 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
4624 return NULL;
4625 Py_BEGIN_ALLOW_THREADS
4626 pid = waitpid(pid, &status, options);
4627 Py_END_ALLOW_THREADS
4628 if (pid == -1)
4629 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004630
Victor Stinner97b89882010-05-06 00:25:39 +00004631 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004632}
4633
Tim Petersab034fa2002-02-01 11:27:43 +00004634#elif defined(HAVE_CWAIT)
4635
4636/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004637PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004638"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004639"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004640
4641static PyObject *
4642posix_waitpid(PyObject *self, PyObject *args)
4643{
Victor Stinner97b89882010-05-06 00:25:39 +00004644 Py_intptr_t pid;
4645 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004646
Victor Stinner97b89882010-05-06 00:25:39 +00004647 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
4648 return NULL;
4649 Py_BEGIN_ALLOW_THREADS
4650 pid = _cwait(&status, pid, options);
4651 Py_END_ALLOW_THREADS
4652 if (pid == -1)
4653 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004654
Victor Stinner97b89882010-05-06 00:25:39 +00004655 /* shift the status left a byte so this is more like the POSIX waitpid */
4656 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004657}
4658#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004659
Guido van Rossumad0ee831995-03-01 10:34:45 +00004660#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004661PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004662"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004663Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004664
Barry Warsaw53699e91996-12-10 23:23:01 +00004665static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004666posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004667{
Victor Stinner97b89882010-05-06 00:25:39 +00004668 pid_t pid;
4669 WAIT_TYPE status;
4670 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004671
Victor Stinner97b89882010-05-06 00:25:39 +00004672 Py_BEGIN_ALLOW_THREADS
4673 pid = wait(&status);
4674 Py_END_ALLOW_THREADS
4675 if (pid == -1)
4676 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004677
Victor Stinner97b89882010-05-06 00:25:39 +00004678 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00004679}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004680#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004681
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004682
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004683PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004684"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004685Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004686
Barry Warsaw53699e91996-12-10 23:23:01 +00004687static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004688posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004689{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004690#ifdef HAVE_LSTAT
Victor Stinner97b89882010-05-06 00:25:39 +00004691 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004692#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004693#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00004694 return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004695#else
Victor Stinner97b89882010-05-06 00:25:39 +00004696 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004697#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004698#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004699}
4700
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004701
Guido van Rossumb6775db1994-08-01 11:34:53 +00004702#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004703PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004704"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004705Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004706
Barry Warsaw53699e91996-12-10 23:23:01 +00004707static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004708posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004709{
Victor Stinner97b89882010-05-06 00:25:39 +00004710 PyObject* v;
4711 char buf[MAXPATHLEN];
4712 PyObject *opath;
4713 char *path;
4714 int n;
4715 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004716
Victor Stinner97b89882010-05-06 00:25:39 +00004717 if (!PyArg_ParseTuple(args, "O&:readlink",
4718 PyUnicode_FSConverter, &opath))
4719 return NULL;
4720 path = bytes2str(opath, 1);
4721 v = PySequence_GetItem(args, 0);
4722 if (v == NULL) {
4723 release_bytes(opath);
4724 return NULL;
4725 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004726
Victor Stinner97b89882010-05-06 00:25:39 +00004727 if (PyUnicode_Check(v)) {
4728 arg_is_unicode = 1;
4729 }
4730 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004731
Victor Stinner97b89882010-05-06 00:25:39 +00004732 Py_BEGIN_ALLOW_THREADS
4733 n = readlink(path, buf, (int) sizeof buf);
4734 Py_END_ALLOW_THREADS
4735 if (n < 0)
4736 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004737
Victor Stinner97b89882010-05-06 00:25:39 +00004738 release_bytes(opath);
Victor Stinner203406c2010-05-14 18:07:39 +00004739 v = PyBytes_FromStringAndSize(buf, n);
4740 if (arg_is_unicode) {
4741 PyObject *w;
4742
4743 w = PyUnicode_FromEncodedObject(v,
4744 Py_FileSystemDefaultEncoding,
4745 "surrogateescape");
4746 if (w != NULL) {
4747 Py_DECREF(v);
4748 v = w;
4749 }
4750 else {
4751 v = NULL;
4752 }
4753 }
4754 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004755}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004756#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004757
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004758
Guido van Rossumb6775db1994-08-01 11:34:53 +00004759#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004760PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004761"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00004762Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004763
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004764static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004765posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004766{
Victor Stinner97b89882010-05-06 00:25:39 +00004767 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004768}
4769#endif /* HAVE_SYMLINK */
4770
4771
4772#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00004773#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4774static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004775system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004776{
4777 ULONG value = 0;
4778
4779 Py_BEGIN_ALLOW_THREADS
4780 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4781 Py_END_ALLOW_THREADS
4782
4783 return value;
4784}
4785
4786static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004787posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004788{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004789 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner97b89882010-05-06 00:25:39 +00004790 return Py_BuildValue("ddddd",
4791 (double)0 /* t.tms_utime / HZ */,
4792 (double)0 /* t.tms_stime / HZ */,
4793 (double)0 /* t.tms_cutime / HZ */,
4794 (double)0 /* t.tms_cstime / HZ */,
4795 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00004796}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004797#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00004798#define NEED_TICKS_PER_SECOND
4799static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00004800static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004801posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004802{
Victor Stinner97b89882010-05-06 00:25:39 +00004803 struct tms t;
4804 clock_t c;
4805 errno = 0;
4806 c = times(&t);
4807 if (c == (clock_t) -1)
4808 return posix_error();
4809 return Py_BuildValue("ddddd",
4810 (double)t.tms_utime / ticks_per_second,
4811 (double)t.tms_stime / ticks_per_second,
4812 (double)t.tms_cutime / ticks_per_second,
4813 (double)t.tms_cstime / ticks_per_second,
4814 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004815}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004816#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004817#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004818
4819
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004820#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00004821#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004822static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004823posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004824{
Victor Stinner97b89882010-05-06 00:25:39 +00004825 FILETIME create, exit, kernel, user;
4826 HANDLE hProc;
4827 hProc = GetCurrentProcess();
4828 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4829 /* The fields of a FILETIME structure are the hi and lo part
4830 of a 64-bit value expressed in 100 nanosecond units.
4831 1e7 is one second in such units; 1e-7 the inverse.
4832 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4833 */
4834 return Py_BuildValue(
4835 "ddddd",
4836 (double)(user.dwHighDateTime*429.4967296 +
4837 user.dwLowDateTime*1e-7),
4838 (double)(kernel.dwHighDateTime*429.4967296 +
4839 kernel.dwLowDateTime*1e-7),
4840 (double)0,
4841 (double)0,
4842 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004843}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004844#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004845
4846#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004847PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004848"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004849Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004850#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004851
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004852
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004853#ifdef HAVE_GETSID
4854PyDoc_STRVAR(posix_getsid__doc__,
4855"getsid(pid) -> sid\n\n\
4856Call the system call getsid().");
4857
4858static PyObject *
4859posix_getsid(PyObject *self, PyObject *args)
4860{
Victor Stinner97b89882010-05-06 00:25:39 +00004861 pid_t pid;
4862 int sid;
4863 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
4864 return NULL;
4865 sid = getsid(pid);
4866 if (sid < 0)
4867 return posix_error();
4868 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004869}
4870#endif /* HAVE_GETSID */
4871
4872
Guido van Rossumb6775db1994-08-01 11:34:53 +00004873#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004874PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004875"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004876Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004877
Barry Warsaw53699e91996-12-10 23:23:01 +00004878static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004879posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004880{
Victor Stinner97b89882010-05-06 00:25:39 +00004881 if (setsid() < 0)
4882 return posix_error();
4883 Py_INCREF(Py_None);
4884 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004885}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004886#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004887
Guido van Rossumb6775db1994-08-01 11:34:53 +00004888#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004889PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004890"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004891Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004892
Barry Warsaw53699e91996-12-10 23:23:01 +00004893static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004894posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004895{
Victor Stinner97b89882010-05-06 00:25:39 +00004896 pid_t pid;
4897 int pgrp;
4898 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
4899 return NULL;
4900 if (setpgid(pid, pgrp) < 0)
4901 return posix_error();
4902 Py_INCREF(Py_None);
4903 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004904}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004905#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004906
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004907
Guido van Rossumb6775db1994-08-01 11:34:53 +00004908#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004909PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004910"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004911Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004912
Barry Warsaw53699e91996-12-10 23:23:01 +00004913static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004914posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004915{
Victor Stinner97b89882010-05-06 00:25:39 +00004916 int fd;
4917 pid_t pgid;
4918 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
4919 return NULL;
4920 pgid = tcgetpgrp(fd);
4921 if (pgid < 0)
4922 return posix_error();
4923 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004924}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004925#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004926
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004927
Guido van Rossumb6775db1994-08-01 11:34:53 +00004928#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004929PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004930"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004931Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004932
Barry Warsaw53699e91996-12-10 23:23:01 +00004933static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004934posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004935{
Victor Stinner97b89882010-05-06 00:25:39 +00004936 int fd;
4937 pid_t pgid;
4938 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
4939 return NULL;
4940 if (tcsetpgrp(fd, pgid) < 0)
4941 return posix_error();
4942 Py_INCREF(Py_None);
4943 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004944}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004945#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004946
Guido van Rossum687dd131993-05-17 08:34:16 +00004947/* Functions acting on file descriptors */
4948
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004949PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004950"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004951Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004952
Barry Warsaw53699e91996-12-10 23:23:01 +00004953static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004954posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004955{
Victor Stinner97b89882010-05-06 00:25:39 +00004956 PyObject *ofile;
4957 char *file;
4958 int flag;
4959 int mode = 0777;
4960 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004961
4962#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00004963 if (unicode_file_names()) {
4964 PyUnicodeObject *po;
4965 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4966 Py_BEGIN_ALLOW_THREADS
4967 /* PyUnicode_AS_UNICODE OK without thread
4968 lock as it is a simple dereference. */
4969 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4970 Py_END_ALLOW_THREADS
4971 if (fd < 0)
4972 return posix_error();
4973 return PyLong_FromLong((long)fd);
4974 }
4975 /* Drop the argument parsing error as narrow strings
4976 are also valid. */
4977 PyErr_Clear();
4978 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004979#endif
4980
Victor Stinner97b89882010-05-06 00:25:39 +00004981 if (!PyArg_ParseTuple(args, "O&i|i",
4982 PyUnicode_FSConverter, &ofile,
4983 &flag, &mode))
4984 return NULL;
4985 file = bytes2str(ofile, 1);
4986 Py_BEGIN_ALLOW_THREADS
4987 fd = open(file, flag, mode);
4988 Py_END_ALLOW_THREADS
4989 if (fd < 0)
4990 return posix_error_with_allocated_filename(ofile);
4991 release_bytes(ofile);
4992 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004993}
4994
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004995
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004996PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004997"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004998Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004999
Barry Warsaw53699e91996-12-10 23:23:01 +00005000static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005001posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005002{
Victor Stinner97b89882010-05-06 00:25:39 +00005003 int fd, res;
5004 if (!PyArg_ParseTuple(args, "i:close", &fd))
5005 return NULL;
5006 if (!_PyVerify_fd(fd))
5007 return posix_error();
5008 Py_BEGIN_ALLOW_THREADS
5009 res = close(fd);
5010 Py_END_ALLOW_THREADS
5011 if (res < 0)
5012 return posix_error();
5013 Py_INCREF(Py_None);
5014 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005015}
5016
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005017
Victor Stinner97b89882010-05-06 00:25:39 +00005018PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00005019"closerange(fd_low, fd_high)\n\n\
5020Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
5021
5022static PyObject *
5023posix_closerange(PyObject *self, PyObject *args)
5024{
Victor Stinner97b89882010-05-06 00:25:39 +00005025 int fd_from, fd_to, i;
5026 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
5027 return NULL;
5028 Py_BEGIN_ALLOW_THREADS
5029 for (i = fd_from; i < fd_to; i++)
5030 if (_PyVerify_fd(i))
5031 close(i);
5032 Py_END_ALLOW_THREADS
5033 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00005034}
5035
5036
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005037PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005038"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005039Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005040
Barry Warsaw53699e91996-12-10 23:23:01 +00005041static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005042posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005043{
Victor Stinner97b89882010-05-06 00:25:39 +00005044 int fd;
5045 if (!PyArg_ParseTuple(args, "i:dup", &fd))
5046 return NULL;
5047 if (!_PyVerify_fd(fd))
5048 return posix_error();
5049 Py_BEGIN_ALLOW_THREADS
5050 fd = dup(fd);
5051 Py_END_ALLOW_THREADS
5052 if (fd < 0)
5053 return posix_error();
5054 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005055}
5056
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005057
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005058PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005059"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005060Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005061
Barry Warsaw53699e91996-12-10 23:23:01 +00005062static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005063posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005064{
Victor Stinner97b89882010-05-06 00:25:39 +00005065 int fd, fd2, res;
5066 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5067 return NULL;
5068 if (!_PyVerify_fd_dup2(fd, fd2))
5069 return posix_error();
5070 Py_BEGIN_ALLOW_THREADS
5071 res = dup2(fd, fd2);
5072 Py_END_ALLOW_THREADS
5073 if (res < 0)
5074 return posix_error();
5075 Py_INCREF(Py_None);
5076 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005077}
5078
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005079
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005080PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005081"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005082Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005083
Barry Warsaw53699e91996-12-10 23:23:01 +00005084static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005085posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005086{
Victor Stinner97b89882010-05-06 00:25:39 +00005087 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005088#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner97b89882010-05-06 00:25:39 +00005089 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005090#else
Victor Stinner97b89882010-05-06 00:25:39 +00005091 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005092#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005093 PyObject *posobj;
5094 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5095 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005096#ifdef SEEK_SET
Victor Stinner97b89882010-05-06 00:25:39 +00005097 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5098 switch (how) {
5099 case 0: how = SEEK_SET; break;
5100 case 1: how = SEEK_CUR; break;
5101 case 2: how = SEEK_END; break;
5102 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005103#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005104
5105#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner97b89882010-05-06 00:25:39 +00005106 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005107#else
Victor Stinner97b89882010-05-06 00:25:39 +00005108 pos = PyLong_Check(posobj) ?
5109 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005110#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005111 if (PyErr_Occurred())
5112 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005113
Victor Stinner97b89882010-05-06 00:25:39 +00005114 if (!_PyVerify_fd(fd))
5115 return posix_error();
5116 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005117#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner97b89882010-05-06 00:25:39 +00005118 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005119#else
Victor Stinner97b89882010-05-06 00:25:39 +00005120 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005121#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005122 Py_END_ALLOW_THREADS
5123 if (res < 0)
5124 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005125
5126#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner97b89882010-05-06 00:25:39 +00005127 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005128#else
Victor Stinner97b89882010-05-06 00:25:39 +00005129 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005130#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005131}
5132
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005133
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005134PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005135"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005136Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005137
Barry Warsaw53699e91996-12-10 23:23:01 +00005138static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005139posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005140{
Victor Stinner97b89882010-05-06 00:25:39 +00005141 int fd, size;
5142 Py_ssize_t n;
5143 PyObject *buffer;
5144 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5145 return NULL;
5146 if (size < 0) {
5147 errno = EINVAL;
5148 return posix_error();
5149 }
5150 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
5151 if (buffer == NULL)
5152 return NULL;
Stefan Krah40b61232010-11-26 15:08:59 +00005153 if (!_PyVerify_fd(fd)) {
5154 Py_DECREF(buffer);
Victor Stinner97b89882010-05-06 00:25:39 +00005155 return posix_error();
Stefan Krah40b61232010-11-26 15:08:59 +00005156 }
Victor Stinner97b89882010-05-06 00:25:39 +00005157 Py_BEGIN_ALLOW_THREADS
5158 n = read(fd, PyBytes_AS_STRING(buffer), size);
5159 Py_END_ALLOW_THREADS
5160 if (n < 0) {
5161 Py_DECREF(buffer);
5162 return posix_error();
5163 }
5164 if (n != size)
5165 _PyBytes_Resize(&buffer, n);
5166 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00005167}
5168
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005169
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005170PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005171"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005172Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005173
Barry Warsaw53699e91996-12-10 23:23:01 +00005174static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005175posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005176{
Victor Stinner97b89882010-05-06 00:25:39 +00005177 Py_buffer pbuf;
5178 int fd;
5179 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005180
Victor Stinner97b89882010-05-06 00:25:39 +00005181 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
5182 return NULL;
Stefan Krah40b61232010-11-26 15:08:59 +00005183 if (!_PyVerify_fd(fd)) {
5184 PyBuffer_Release(&pbuf);
Victor Stinner97b89882010-05-06 00:25:39 +00005185 return posix_error();
Stefan Krah40b61232010-11-26 15:08:59 +00005186 }
Victor Stinner97b89882010-05-06 00:25:39 +00005187 Py_BEGIN_ALLOW_THREADS
5188 size = write(fd, pbuf.buf, (size_t)pbuf.len);
5189 Py_END_ALLOW_THREADS
Stefan Krah40b61232010-11-26 15:08:59 +00005190 PyBuffer_Release(&pbuf);
Victor Stinner97b89882010-05-06 00:25:39 +00005191 if (size < 0)
5192 return posix_error();
5193 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005194}
5195
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005196
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005197PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005198"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005199Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005200
Barry Warsaw53699e91996-12-10 23:23:01 +00005201static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005202posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005203{
Victor Stinner97b89882010-05-06 00:25:39 +00005204 int fd;
5205 STRUCT_STAT st;
5206 int res;
5207 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5208 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005209#ifdef __VMS
Victor Stinner97b89882010-05-06 00:25:39 +00005210 /* on OpenVMS we must ensure that all bytes are written to the file */
5211 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005212#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005213 if (!_PyVerify_fd(fd))
5214 return posix_error();
5215 Py_BEGIN_ALLOW_THREADS
5216 res = FSTAT(fd, &st);
5217 Py_END_ALLOW_THREADS
5218 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00005219#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00005220 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00005221#else
Victor Stinner97b89882010-05-06 00:25:39 +00005222 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005223#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005224 }
Tim Peters5aa91602002-01-30 05:46:57 +00005225
Victor Stinner97b89882010-05-06 00:25:39 +00005226 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005227}
5228
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005229PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005230"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005231Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005232connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005233
5234static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005235posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005236{
Victor Stinner97b89882010-05-06 00:25:39 +00005237 int fd;
5238 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5239 return NULL;
5240 if (!_PyVerify_fd(fd))
5241 return PyBool_FromLong(0);
5242 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005243}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005244
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005245#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005246PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005247"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005248Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005249
Barry Warsaw53699e91996-12-10 23:23:01 +00005250static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005251posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005252{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005253#if defined(PYOS_OS2)
5254 HFILE read, write;
5255 APIRET rc;
5256
Victor Stinner97b89882010-05-06 00:25:39 +00005257 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005258 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinner97b89882010-05-06 00:25:39 +00005259 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005260 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005261 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005262
5263 return Py_BuildValue("(ii)", read, write);
5264#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005265#if !defined(MS_WINDOWS)
Victor Stinner97b89882010-05-06 00:25:39 +00005266 int fds[2];
5267 int res;
5268 Py_BEGIN_ALLOW_THREADS
5269 res = pipe(fds);
5270 Py_END_ALLOW_THREADS
5271 if (res != 0)
5272 return posix_error();
5273 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005274#else /* MS_WINDOWS */
Victor Stinner97b89882010-05-06 00:25:39 +00005275 HANDLE read, write;
5276 int read_fd, write_fd;
5277 BOOL ok;
5278 Py_BEGIN_ALLOW_THREADS
5279 ok = CreatePipe(&read, &write, NULL, 0);
5280 Py_END_ALLOW_THREADS
5281 if (!ok)
5282 return win32_error("CreatePipe", NULL);
5283 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5284 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5285 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005286#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005287#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005288}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005289#endif /* HAVE_PIPE */
5290
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005291
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005292#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005293PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005294"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005295Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005296
Barry Warsaw53699e91996-12-10 23:23:01 +00005297static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005298posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005299{
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005300 PyObject *opath;
Victor Stinner97b89882010-05-06 00:25:39 +00005301 char *filename;
5302 int mode = 0666;
5303 int res;
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005304 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
5305 &mode))
Victor Stinner97b89882010-05-06 00:25:39 +00005306 return NULL;
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005307 filename = PyBytes_AS_STRING(opath);
Victor Stinner97b89882010-05-06 00:25:39 +00005308 Py_BEGIN_ALLOW_THREADS
5309 res = mkfifo(filename, mode);
5310 Py_END_ALLOW_THREADS
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005311 Py_DECREF(opath);
Victor Stinner97b89882010-05-06 00:25:39 +00005312 if (res < 0)
5313 return posix_error();
5314 Py_INCREF(Py_None);
5315 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005316}
5317#endif
5318
5319
Neal Norwitz11690112002-07-30 01:08:28 +00005320#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005321PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005322"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005323Create a filesystem node (file, device special file or named pipe)\n\
5324named filename. mode specifies both the permissions to use and the\n\
5325type of node to be created, being combined (bitwise OR) with one of\n\
5326S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005327device defines the newly created device special file (probably using\n\
5328os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005329
5330
5331static PyObject *
5332posix_mknod(PyObject *self, PyObject *args)
5333{
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005334 PyObject *opath;
Victor Stinner97b89882010-05-06 00:25:39 +00005335 char *filename;
5336 int mode = 0600;
5337 int device = 0;
5338 int res;
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005339 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
5340 &mode, &device))
Victor Stinner97b89882010-05-06 00:25:39 +00005341 return NULL;
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005342 filename = PyBytes_AS_STRING(opath);
Victor Stinner97b89882010-05-06 00:25:39 +00005343 Py_BEGIN_ALLOW_THREADS
5344 res = mknod(filename, mode, device);
5345 Py_END_ALLOW_THREADS
Benjamin Peterson9ecbc072010-08-11 19:24:27 +00005346 Py_DECREF(opath);
Victor Stinner97b89882010-05-06 00:25:39 +00005347 if (res < 0)
5348 return posix_error();
5349 Py_INCREF(Py_None);
5350 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005351}
5352#endif
5353
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005354#ifdef HAVE_DEVICE_MACROS
5355PyDoc_STRVAR(posix_major__doc__,
5356"major(device) -> major number\n\
5357Extracts a device major number from a raw device number.");
5358
5359static PyObject *
5360posix_major(PyObject *self, PyObject *args)
5361{
Victor Stinner97b89882010-05-06 00:25:39 +00005362 int device;
5363 if (!PyArg_ParseTuple(args, "i:major", &device))
5364 return NULL;
5365 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005366}
5367
5368PyDoc_STRVAR(posix_minor__doc__,
5369"minor(device) -> minor number\n\
5370Extracts a device minor number from a raw device number.");
5371
5372static PyObject *
5373posix_minor(PyObject *self, PyObject *args)
5374{
Victor Stinner97b89882010-05-06 00:25:39 +00005375 int device;
5376 if (!PyArg_ParseTuple(args, "i:minor", &device))
5377 return NULL;
5378 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005379}
5380
5381PyDoc_STRVAR(posix_makedev__doc__,
5382"makedev(major, minor) -> device number\n\
5383Composes a raw device number from the major and minor device numbers.");
5384
5385static PyObject *
5386posix_makedev(PyObject *self, PyObject *args)
5387{
Victor Stinner97b89882010-05-06 00:25:39 +00005388 int major, minor;
5389 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5390 return NULL;
5391 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005392}
5393#endif /* device macros */
5394
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005395
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005396#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005397PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005398"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005399Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005400
Barry Warsaw53699e91996-12-10 23:23:01 +00005401static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005402posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005403{
Victor Stinner97b89882010-05-06 00:25:39 +00005404 int fd;
5405 off_t length;
5406 int res;
5407 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005408
Victor Stinner97b89882010-05-06 00:25:39 +00005409 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
5410 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005411
5412#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner97b89882010-05-06 00:25:39 +00005413 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005414#else
Victor Stinner97b89882010-05-06 00:25:39 +00005415 length = PyLong_Check(lenobj) ?
5416 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005417#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005418 if (PyErr_Occurred())
5419 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005420
Victor Stinner97b89882010-05-06 00:25:39 +00005421 Py_BEGIN_ALLOW_THREADS
5422 res = ftruncate(fd, length);
5423 Py_END_ALLOW_THREADS
5424 if (res < 0)
5425 return posix_error();
5426 Py_INCREF(Py_None);
5427 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005428}
5429#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005430
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005431#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005432PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005433"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005434Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005435
Fred Drake762e2061999-08-26 17:23:54 +00005436/* Save putenv() parameters as values here, so we can collect them when they
5437 * get re-set with another call for the same key. */
5438static PyObject *posix_putenv_garbage;
5439
Tim Peters5aa91602002-01-30 05:46:57 +00005440static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005441posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005442{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005443#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00005444 wchar_t *s1, *s2;
5445 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005446#else
Victor Stinner97b89882010-05-06 00:25:39 +00005447 PyObject *os1, *os2;
5448 char *s1, *s2;
5449 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005450#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005451 PyObject *newstr;
5452 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005453
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005454#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00005455 if (!PyArg_ParseTuple(args,
5456 "uu:putenv",
5457 &s1, &s2))
5458 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005459#else
Victor Stinner97b89882010-05-06 00:25:39 +00005460 if (!PyArg_ParseTuple(args,
5461 "O&O&:putenv",
5462 PyUnicode_FSConverter, &os1,
5463 PyUnicode_FSConverter, &os2))
5464 return NULL;
5465 s1 = bytes2str(os1, 1);
5466 s2 = bytes2str(os2, 1);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005467#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005468
5469#if defined(PYOS_OS2)
5470 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5471 APIRET rc;
5472
Guido van Rossumd48f2521997-12-05 22:19:34 +00005473 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5474 if (rc != NO_ERROR)
5475 return os2_error(rc);
5476
5477 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5478 APIRET rc;
5479
Guido van Rossumd48f2521997-12-05 22:19:34 +00005480 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5481 if (rc != NO_ERROR)
5482 return os2_error(rc);
5483 } else {
5484#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005485 /* XXX This can leak memory -- not easy to fix :-( */
5486 /* len includes space for a trailing \0; the size arg to
5487 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005488#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00005489 len = wcslen(s1) + wcslen(s2) + 2;
5490 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005491#else
Victor Stinner97b89882010-05-06 00:25:39 +00005492 len = strlen(s1) + strlen(s2) + 2;
5493 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005494#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005495 if (newstr == NULL)
5496 return PyErr_NoMemory();
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005497#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00005498 newenv = PyUnicode_AsUnicode(newstr);
5499 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5500 if (_wputenv(newenv)) {
5501 Py_DECREF(newstr);
5502 posix_error();
5503 return NULL;
5504 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005505#else
Victor Stinner97b89882010-05-06 00:25:39 +00005506 newenv = PyBytes_AS_STRING(newstr);
5507 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5508 if (putenv(newenv)) {
5509 Py_DECREF(newstr);
5510 release_bytes(os1);
5511 release_bytes(os2);
5512 posix_error();
5513 return NULL;
5514 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005515#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005516 /* Install the first arg and newstr in posix_putenv_garbage;
5517 * this will cause previous value to be collected. This has to
5518 * happen after the real putenv() call because the old value
5519 * was still accessible until then. */
5520 if (PyDict_SetItem(posix_putenv_garbage,
5521 PyTuple_GET_ITEM(args, 0), newstr)) {
5522 /* really not much we can do; just leak */
5523 PyErr_Clear();
5524 }
5525 else {
5526 Py_DECREF(newstr);
5527 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005528
5529#if defined(PYOS_OS2)
5530 }
5531#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00005532#ifndef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00005533 release_bytes(os1);
5534 release_bytes(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005535#endif
Victor Stinner97b89882010-05-06 00:25:39 +00005536 Py_INCREF(Py_None);
5537 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005538}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005539#endif /* putenv */
5540
Guido van Rossumc524d952001-10-19 01:31:59 +00005541#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005542PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005543"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005544Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005545
5546static PyObject *
5547posix_unsetenv(PyObject *self, PyObject *args)
5548{
Victor Stinner97b89882010-05-06 00:25:39 +00005549 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00005550
Victor Stinner97b89882010-05-06 00:25:39 +00005551 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5552 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00005553
Victor Stinner97b89882010-05-06 00:25:39 +00005554 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00005555
Victor Stinner97b89882010-05-06 00:25:39 +00005556 /* Remove the key from posix_putenv_garbage;
5557 * this will cause it to be collected. This has to
5558 * happen after the real unsetenv() call because the
5559 * old value was still accessible until then.
5560 */
5561 if (PyDict_DelItem(posix_putenv_garbage,
5562 PyTuple_GET_ITEM(args, 0))) {
5563 /* really not much we can do; just leak */
5564 PyErr_Clear();
5565 }
Guido van Rossumc524d952001-10-19 01:31:59 +00005566
Victor Stinner97b89882010-05-06 00:25:39 +00005567 Py_INCREF(Py_None);
5568 return Py_None;
Guido van Rossumc524d952001-10-19 01:31:59 +00005569}
5570#endif /* unsetenv */
5571
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005572PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005573"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005574Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005575
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005576static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005577posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005578{
Victor Stinner97b89882010-05-06 00:25:39 +00005579 int code;
5580 char *message;
5581 if (!PyArg_ParseTuple(args, "i:strerror", &code))
5582 return NULL;
5583 message = strerror(code);
5584 if (message == NULL) {
5585 PyErr_SetString(PyExc_ValueError,
5586 "strerror() argument out of range");
5587 return NULL;
5588 }
5589 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00005590}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005591
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005592
Guido van Rossumc9641791998-08-04 15:26:23 +00005593#ifdef HAVE_SYS_WAIT_H
5594
Fred Drake106c1a02002-04-23 15:58:02 +00005595#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005596PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005597"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005598Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005599
5600static PyObject *
5601posix_WCOREDUMP(PyObject *self, PyObject *args)
5602{
Victor Stinner97b89882010-05-06 00:25:39 +00005603 WAIT_TYPE status;
5604 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005605
Victor Stinner97b89882010-05-06 00:25:39 +00005606 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
5607 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005608
Victor Stinner97b89882010-05-06 00:25:39 +00005609 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005610}
5611#endif /* WCOREDUMP */
5612
5613#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005614PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005615"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005616Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005617job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005618
5619static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005620posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005621{
Victor Stinner97b89882010-05-06 00:25:39 +00005622 WAIT_TYPE status;
5623 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005624
Victor Stinner97b89882010-05-06 00:25:39 +00005625 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
5626 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005627
Victor Stinner97b89882010-05-06 00:25:39 +00005628 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005629}
5630#endif /* WIFCONTINUED */
5631
Guido van Rossumc9641791998-08-04 15:26:23 +00005632#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005633PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005634"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005635Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005636
5637static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005638posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005639{
Victor Stinner97b89882010-05-06 00:25:39 +00005640 WAIT_TYPE status;
5641 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005642
Victor Stinner97b89882010-05-06 00:25:39 +00005643 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
5644 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005645
Victor Stinner97b89882010-05-06 00:25:39 +00005646 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005647}
5648#endif /* WIFSTOPPED */
5649
5650#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005651PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005652"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005653Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005654
5655static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005656posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005657{
Victor Stinner97b89882010-05-06 00:25:39 +00005658 WAIT_TYPE status;
5659 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005660
Victor Stinner97b89882010-05-06 00:25:39 +00005661 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
5662 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005663
Victor Stinner97b89882010-05-06 00:25:39 +00005664 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005665}
5666#endif /* WIFSIGNALED */
5667
5668#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005669PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005670"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005671Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005672system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005673
5674static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005675posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005676{
Victor Stinner97b89882010-05-06 00:25:39 +00005677 WAIT_TYPE status;
5678 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005679
Victor Stinner97b89882010-05-06 00:25:39 +00005680 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
5681 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005682
Victor Stinner97b89882010-05-06 00:25:39 +00005683 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005684}
5685#endif /* WIFEXITED */
5686
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005687#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005688PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005689"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005690Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005691
5692static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005693posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005694{
Victor Stinner97b89882010-05-06 00:25:39 +00005695 WAIT_TYPE status;
5696 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005697
Victor Stinner97b89882010-05-06 00:25:39 +00005698 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
5699 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005700
Victor Stinner97b89882010-05-06 00:25:39 +00005701 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005702}
5703#endif /* WEXITSTATUS */
5704
5705#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005706PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005707"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005708Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005709value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005710
5711static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005712posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005713{
Victor Stinner97b89882010-05-06 00:25:39 +00005714 WAIT_TYPE status;
5715 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005716
Victor Stinner97b89882010-05-06 00:25:39 +00005717 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
5718 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005719
Victor Stinner97b89882010-05-06 00:25:39 +00005720 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005721}
5722#endif /* WTERMSIG */
5723
5724#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005725PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005726"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005727Return the signal that stopped the process that provided\n\
5728the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005729
5730static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005731posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005732{
Victor Stinner97b89882010-05-06 00:25:39 +00005733 WAIT_TYPE status;
5734 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005735
Victor Stinner97b89882010-05-06 00:25:39 +00005736 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
5737 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005738
Victor Stinner97b89882010-05-06 00:25:39 +00005739 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005740}
5741#endif /* WSTOPSIG */
5742
5743#endif /* HAVE_SYS_WAIT_H */
5744
5745
Thomas Wouters477c8d52006-05-27 19:21:47 +00005746#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005747#ifdef _SCO_DS
5748/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5749 needed definitions in sys/statvfs.h */
5750#define _SVID3
5751#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005752#include <sys/statvfs.h>
5753
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005754static PyObject*
5755_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner97b89882010-05-06 00:25:39 +00005756 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5757 if (v == NULL)
5758 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005759
5760#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner97b89882010-05-06 00:25:39 +00005761 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5762 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
5763 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
5764 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
5765 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
5766 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
5767 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
5768 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
5769 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5770 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005771#else
Victor Stinner97b89882010-05-06 00:25:39 +00005772 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5773 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
5774 PyStructSequence_SET_ITEM(v, 2,
5775 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
5776 PyStructSequence_SET_ITEM(v, 3,
5777 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
5778 PyStructSequence_SET_ITEM(v, 4,
5779 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
5780 PyStructSequence_SET_ITEM(v, 5,
5781 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
5782 PyStructSequence_SET_ITEM(v, 6,
5783 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
5784 PyStructSequence_SET_ITEM(v, 7,
5785 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
5786 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5787 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005788#endif
5789
Victor Stinner97b89882010-05-06 00:25:39 +00005790 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005791}
5792
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005793PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005794"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005795Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005796
5797static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005798posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005799{
Victor Stinner97b89882010-05-06 00:25:39 +00005800 int fd, res;
5801 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005802
Victor Stinner97b89882010-05-06 00:25:39 +00005803 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
5804 return NULL;
5805 Py_BEGIN_ALLOW_THREADS
5806 res = fstatvfs(fd, &st);
5807 Py_END_ALLOW_THREADS
5808 if (res != 0)
5809 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005810
Victor Stinner97b89882010-05-06 00:25:39 +00005811 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005812}
Thomas Wouters477c8d52006-05-27 19:21:47 +00005813#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005814
5815
Thomas Wouters477c8d52006-05-27 19:21:47 +00005816#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005817#include <sys/statvfs.h>
5818
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005819PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005820"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005821Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005822
5823static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005824posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005825{
Victor Stinner97b89882010-05-06 00:25:39 +00005826 char *path;
5827 int res;
5828 struct statvfs st;
5829 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
5830 return NULL;
5831 Py_BEGIN_ALLOW_THREADS
5832 res = statvfs(path, &st);
5833 Py_END_ALLOW_THREADS
5834 if (res != 0)
5835 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005836
Victor Stinner97b89882010-05-06 00:25:39 +00005837 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005838}
5839#endif /* HAVE_STATVFS */
5840
Fred Drakec9680921999-12-13 16:37:25 +00005841/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5842 * It maps strings representing configuration variable names to
5843 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005844 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005845 * rarely-used constants. There are three separate tables that use
5846 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005847 *
5848 * This code is always included, even if none of the interfaces that
5849 * need it are included. The #if hackery needed to avoid it would be
5850 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005851 */
5852struct constdef {
5853 char *name;
5854 long value;
5855};
5856
Fred Drake12c6e2d1999-12-14 21:25:03 +00005857static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005858conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005859 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005860{
Christian Heimes217cfd12007-12-02 14:31:20 +00005861 if (PyLong_Check(arg)) {
Stefan Krah67733312010-11-26 17:04:40 +00005862 *valuep = PyLong_AS_LONG(arg);
5863 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005864 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00005865 else {
Stefan Krah67733312010-11-26 17:04:40 +00005866 /* look up the value in the table using a binary search */
5867 size_t lo = 0;
5868 size_t mid;
5869 size_t hi = tablesize;
5870 int cmp;
5871 const char *confname;
5872 if (!PyUnicode_Check(arg)) {
5873 PyErr_SetString(PyExc_TypeError,
5874 "configuration names must be strings or integers");
5875 return 0;
Victor Stinner97b89882010-05-06 00:25:39 +00005876 }
Stefan Krah67733312010-11-26 17:04:40 +00005877 confname = _PyUnicode_AsString(arg);
5878 if (confname == NULL)
5879 return 0;
5880 while (lo < hi) {
5881 mid = (lo + hi) / 2;
5882 cmp = strcmp(confname, table[mid].name);
5883 if (cmp < 0)
5884 hi = mid;
5885 else if (cmp > 0)
5886 lo = mid + 1;
5887 else {
5888 *valuep = table[mid].value;
5889 return 1;
5890 }
5891 }
5892 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5893 return 0;
Victor Stinner97b89882010-05-06 00:25:39 +00005894 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00005895}
5896
5897
5898#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5899static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005900#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00005901 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00005902#endif
5903#ifdef _PC_ABI_ASYNC_IO
Victor Stinner97b89882010-05-06 00:25:39 +00005904 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00005905#endif
Fred Drakec9680921999-12-13 16:37:25 +00005906#ifdef _PC_ASYNC_IO
Victor Stinner97b89882010-05-06 00:25:39 +00005907 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00005908#endif
5909#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner97b89882010-05-06 00:25:39 +00005910 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00005911#endif
5912#ifdef _PC_FILESIZEBITS
Victor Stinner97b89882010-05-06 00:25:39 +00005913 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00005914#endif
5915#ifdef _PC_LAST
Victor Stinner97b89882010-05-06 00:25:39 +00005916 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00005917#endif
5918#ifdef _PC_LINK_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00005919 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00005920#endif
5921#ifdef _PC_MAX_CANON
Victor Stinner97b89882010-05-06 00:25:39 +00005922 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00005923#endif
5924#ifdef _PC_MAX_INPUT
Victor Stinner97b89882010-05-06 00:25:39 +00005925 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00005926#endif
5927#ifdef _PC_NAME_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00005928 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00005929#endif
5930#ifdef _PC_NO_TRUNC
Victor Stinner97b89882010-05-06 00:25:39 +00005931 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00005932#endif
5933#ifdef _PC_PATH_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00005934 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00005935#endif
5936#ifdef _PC_PIPE_BUF
Victor Stinner97b89882010-05-06 00:25:39 +00005937 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00005938#endif
5939#ifdef _PC_PRIO_IO
Victor Stinner97b89882010-05-06 00:25:39 +00005940 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00005941#endif
5942#ifdef _PC_SOCK_MAXBUF
Victor Stinner97b89882010-05-06 00:25:39 +00005943 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00005944#endif
5945#ifdef _PC_SYNC_IO
Victor Stinner97b89882010-05-06 00:25:39 +00005946 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00005947#endif
5948#ifdef _PC_VDISABLE
Victor Stinner97b89882010-05-06 00:25:39 +00005949 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00005950#endif
5951};
5952
Fred Drakec9680921999-12-13 16:37:25 +00005953static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005954conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005955{
5956 return conv_confname(arg, valuep, posix_constants_pathconf,
5957 sizeof(posix_constants_pathconf)
5958 / sizeof(struct constdef));
5959}
5960#endif
5961
5962#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005963PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005964"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005965Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005966If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005967
5968static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005969posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005970{
5971 PyObject *result = NULL;
5972 int name, fd;
5973
Fred Drake12c6e2d1999-12-14 21:25:03 +00005974 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5975 conv_path_confname, &name)) {
Stefan Krah67733312010-11-26 17:04:40 +00005976 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00005977
Stefan Krah67733312010-11-26 17:04:40 +00005978 errno = 0;
5979 limit = fpathconf(fd, name);
5980 if (limit == -1 && errno != 0)
5981 posix_error();
5982 else
5983 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00005984 }
5985 return result;
5986}
5987#endif
5988
5989
5990#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005991PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005992"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005993Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005994If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005995
5996static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005997posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005998{
5999 PyObject *result = NULL;
6000 int name;
6001 char *path;
6002
6003 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6004 conv_path_confname, &name)) {
Victor Stinner97b89882010-05-06 00:25:39 +00006005 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006006
Victor Stinner97b89882010-05-06 00:25:39 +00006007 errno = 0;
6008 limit = pathconf(path, name);
6009 if (limit == -1 && errno != 0) {
6010 if (errno == EINVAL)
Stefan Krah40b61232010-11-26 15:08:59 +00006011 /* could be a path or name problem */
6012 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00006013 else
Stefan Krah40b61232010-11-26 15:08:59 +00006014 posix_error_with_filename(path);
Victor Stinner97b89882010-05-06 00:25:39 +00006015 }
6016 else
6017 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006018 }
6019 return result;
6020}
6021#endif
6022
6023#ifdef HAVE_CONFSTR
6024static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006025#ifdef _CS_ARCHITECTURE
Victor Stinner97b89882010-05-06 00:25:39 +00006026 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00006027#endif
Mark Dickinson466e9262010-04-16 16:32:49 +00006028#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006029 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson466e9262010-04-16 16:32:49 +00006030#endif
6031#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006032 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson466e9262010-04-16 16:32:49 +00006033#endif
Fred Draked86ed291999-12-15 15:34:33 +00006034#ifdef _CS_HOSTNAME
Victor Stinner97b89882010-05-06 00:25:39 +00006035 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006036#endif
6037#ifdef _CS_HW_PROVIDER
Victor Stinner97b89882010-05-06 00:25:39 +00006038 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006039#endif
6040#ifdef _CS_HW_SERIAL
Victor Stinner97b89882010-05-06 00:25:39 +00006041 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006042#endif
6043#ifdef _CS_INITTAB_NAME
Victor Stinner97b89882010-05-06 00:25:39 +00006044 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006045#endif
Fred Drakec9680921999-12-13 16:37:25 +00006046#ifdef _CS_LFS64_CFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006047 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006048#endif
6049#ifdef _CS_LFS64_LDFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006050 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006051#endif
6052#ifdef _CS_LFS64_LIBS
Victor Stinner97b89882010-05-06 00:25:39 +00006053 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006054#endif
6055#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006056 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006057#endif
6058#ifdef _CS_LFS_CFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006059 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006060#endif
6061#ifdef _CS_LFS_LDFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006062 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006063#endif
6064#ifdef _CS_LFS_LIBS
Victor Stinner97b89882010-05-06 00:25:39 +00006065 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006066#endif
6067#ifdef _CS_LFS_LINTFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006068 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006069#endif
Fred Draked86ed291999-12-15 15:34:33 +00006070#ifdef _CS_MACHINE
Victor Stinner97b89882010-05-06 00:25:39 +00006071 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00006072#endif
Fred Drakec9680921999-12-13 16:37:25 +00006073#ifdef _CS_PATH
Victor Stinner97b89882010-05-06 00:25:39 +00006074 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00006075#endif
Fred Draked86ed291999-12-15 15:34:33 +00006076#ifdef _CS_RELEASE
Victor Stinner97b89882010-05-06 00:25:39 +00006077 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00006078#endif
6079#ifdef _CS_SRPC_DOMAIN
Victor Stinner97b89882010-05-06 00:25:39 +00006080 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00006081#endif
6082#ifdef _CS_SYSNAME
Victor Stinner97b89882010-05-06 00:25:39 +00006083 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006084#endif
6085#ifdef _CS_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006086 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00006087#endif
Fred Drakec9680921999-12-13 16:37:25 +00006088#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006089 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006090#endif
6091#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006092 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006093#endif
6094#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner97b89882010-05-06 00:25:39 +00006095 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006096#endif
6097#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006098 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006099#endif
6100#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006101 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006102#endif
6103#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006104 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006105#endif
6106#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner97b89882010-05-06 00:25:39 +00006107 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006108#endif
6109#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006110 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006111#endif
6112#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006113 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006114#endif
6115#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006116 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006117#endif
6118#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner97b89882010-05-06 00:25:39 +00006119 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006120#endif
6121#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006122 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006123#endif
6124#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006125 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006126#endif
6127#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006128 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006129#endif
6130#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner97b89882010-05-06 00:25:39 +00006131 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006132#endif
6133#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00006134 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006135#endif
Fred Draked86ed291999-12-15 15:34:33 +00006136#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner97b89882010-05-06 00:25:39 +00006137 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006138#endif
6139#ifdef _MIPS_CS_BASE
Victor Stinner97b89882010-05-06 00:25:39 +00006140 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00006141#endif
6142#ifdef _MIPS_CS_HOSTID
Victor Stinner97b89882010-05-06 00:25:39 +00006143 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00006144#endif
6145#ifdef _MIPS_CS_HW_NAME
Victor Stinner97b89882010-05-06 00:25:39 +00006146 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006147#endif
6148#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner97b89882010-05-06 00:25:39 +00006149 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006150#endif
6151#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner97b89882010-05-06 00:25:39 +00006152 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00006153#endif
6154#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner97b89882010-05-06 00:25:39 +00006155 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00006156#endif
6157#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner97b89882010-05-06 00:25:39 +00006158 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00006159#endif
6160#ifdef _MIPS_CS_OS_NAME
Victor Stinner97b89882010-05-06 00:25:39 +00006161 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006162#endif
6163#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner97b89882010-05-06 00:25:39 +00006164 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006165#endif
6166#ifdef _MIPS_CS_PROCESSORS
Victor Stinner97b89882010-05-06 00:25:39 +00006167 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006168#endif
6169#ifdef _MIPS_CS_SERIAL
Victor Stinner97b89882010-05-06 00:25:39 +00006170 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006171#endif
6172#ifdef _MIPS_CS_VENDOR
Victor Stinner97b89882010-05-06 00:25:39 +00006173 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00006174#endif
Fred Drakec9680921999-12-13 16:37:25 +00006175};
6176
6177static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006178conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006179{
6180 return conv_confname(arg, valuep, posix_constants_confstr,
6181 sizeof(posix_constants_confstr)
6182 / sizeof(struct constdef));
6183}
6184
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006185PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006186"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006187Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006188
6189static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006190posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006191{
6192 PyObject *result = NULL;
6193 int name;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006194 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00006195
6196 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Stefan Krah40b61232010-11-26 15:08:59 +00006197 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006198
Fred Drakec9680921999-12-13 16:37:25 +00006199 errno = 0;
Victor Stinner97b89882010-05-06 00:25:39 +00006200 len = confstr(name, buffer, sizeof(buffer));
6201 if (len == 0) {
6202 if (errno) {
6203 posix_error();
6204 }
6205 else {
6206 result = Py_None;
6207 Py_INCREF(Py_None);
6208 }
Fred Drakec9680921999-12-13 16:37:25 +00006209 }
6210 else {
Victor Stinner97b89882010-05-06 00:25:39 +00006211 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz93c56822007-08-26 07:10:06 +00006212 result = PyUnicode_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006213 if (result != NULL)
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00006214 confstr(name, _PyUnicode_AsString(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00006215 }
6216 else
Neal Norwitz93c56822007-08-26 07:10:06 +00006217 result = PyUnicode_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006218 }
6219 }
6220 return result;
6221}
6222#endif
6223
6224
6225#ifdef HAVE_SYSCONF
6226static struct constdef posix_constants_sysconf[] = {
6227#ifdef _SC_2_CHAR_TERM
Victor Stinner97b89882010-05-06 00:25:39 +00006228 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00006229#endif
6230#ifdef _SC_2_C_BIND
Victor Stinner97b89882010-05-06 00:25:39 +00006231 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00006232#endif
6233#ifdef _SC_2_C_DEV
Victor Stinner97b89882010-05-06 00:25:39 +00006234 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006235#endif
6236#ifdef _SC_2_C_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006237 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006238#endif
6239#ifdef _SC_2_FORT_DEV
Victor Stinner97b89882010-05-06 00:25:39 +00006240 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006241#endif
6242#ifdef _SC_2_FORT_RUN
Victor Stinner97b89882010-05-06 00:25:39 +00006243 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00006244#endif
6245#ifdef _SC_2_LOCALEDEF
Victor Stinner97b89882010-05-06 00:25:39 +00006246 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00006247#endif
6248#ifdef _SC_2_SW_DEV
Victor Stinner97b89882010-05-06 00:25:39 +00006249 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006250#endif
6251#ifdef _SC_2_UPE
Victor Stinner97b89882010-05-06 00:25:39 +00006252 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00006253#endif
6254#ifdef _SC_2_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006255 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006256#endif
Fred Draked86ed291999-12-15 15:34:33 +00006257#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner97b89882010-05-06 00:25:39 +00006258 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006259#endif
6260#ifdef _SC_ACL
Victor Stinner97b89882010-05-06 00:25:39 +00006261 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00006262#endif
Fred Drakec9680921999-12-13 16:37:25 +00006263#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006264 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006265#endif
Fred Drakec9680921999-12-13 16:37:25 +00006266#ifdef _SC_AIO_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006267 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006268#endif
6269#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006270 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006271#endif
6272#ifdef _SC_ARG_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006273 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006274#endif
6275#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner97b89882010-05-06 00:25:39 +00006276 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006277#endif
6278#ifdef _SC_ATEXIT_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006279 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006280#endif
Fred Draked86ed291999-12-15 15:34:33 +00006281#ifdef _SC_AUDIT
Victor Stinner97b89882010-05-06 00:25:39 +00006282 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00006283#endif
Fred Drakec9680921999-12-13 16:37:25 +00006284#ifdef _SC_AVPHYS_PAGES
Victor Stinner97b89882010-05-06 00:25:39 +00006285 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006286#endif
6287#ifdef _SC_BC_BASE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006288 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006289#endif
6290#ifdef _SC_BC_DIM_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006291 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006292#endif
6293#ifdef _SC_BC_SCALE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006294 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006295#endif
6296#ifdef _SC_BC_STRING_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006297 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006298#endif
Fred Draked86ed291999-12-15 15:34:33 +00006299#ifdef _SC_CAP
Victor Stinner97b89882010-05-06 00:25:39 +00006300 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00006301#endif
Fred Drakec9680921999-12-13 16:37:25 +00006302#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006303 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006304#endif
6305#ifdef _SC_CHAR_BIT
Victor Stinner97b89882010-05-06 00:25:39 +00006306 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006307#endif
6308#ifdef _SC_CHAR_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006309 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006310#endif
6311#ifdef _SC_CHAR_MIN
Victor Stinner97b89882010-05-06 00:25:39 +00006312 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006313#endif
6314#ifdef _SC_CHILD_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006315 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006316#endif
6317#ifdef _SC_CLK_TCK
Victor Stinner97b89882010-05-06 00:25:39 +00006318 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00006319#endif
6320#ifdef _SC_COHER_BLKSZ
Victor Stinner97b89882010-05-06 00:25:39 +00006321 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006322#endif
6323#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006324 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006325#endif
6326#ifdef _SC_DCACHE_ASSOC
Victor Stinner97b89882010-05-06 00:25:39 +00006327 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006328#endif
6329#ifdef _SC_DCACHE_BLKSZ
Victor Stinner97b89882010-05-06 00:25:39 +00006330 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006331#endif
6332#ifdef _SC_DCACHE_LINESZ
Victor Stinner97b89882010-05-06 00:25:39 +00006333 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006334#endif
6335#ifdef _SC_DCACHE_SZ
Victor Stinner97b89882010-05-06 00:25:39 +00006336 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006337#endif
6338#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner97b89882010-05-06 00:25:39 +00006339 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006340#endif
6341#ifdef _SC_DELAYTIMER_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006342 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006343#endif
6344#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006345 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006346#endif
6347#ifdef _SC_EXPR_NEST_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006348 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006349#endif
6350#ifdef _SC_FSYNC
Victor Stinner97b89882010-05-06 00:25:39 +00006351 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00006352#endif
6353#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006354 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006355#endif
6356#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006357 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006358#endif
6359#ifdef _SC_ICACHE_ASSOC
Victor Stinner97b89882010-05-06 00:25:39 +00006360 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006361#endif
6362#ifdef _SC_ICACHE_BLKSZ
Victor Stinner97b89882010-05-06 00:25:39 +00006363 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006364#endif
6365#ifdef _SC_ICACHE_LINESZ
Victor Stinner97b89882010-05-06 00:25:39 +00006366 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006367#endif
6368#ifdef _SC_ICACHE_SZ
Victor Stinner97b89882010-05-06 00:25:39 +00006369 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006370#endif
Fred Draked86ed291999-12-15 15:34:33 +00006371#ifdef _SC_INF
Victor Stinner97b89882010-05-06 00:25:39 +00006372 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00006373#endif
Fred Drakec9680921999-12-13 16:37:25 +00006374#ifdef _SC_INT_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006375 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006376#endif
6377#ifdef _SC_INT_MIN
Victor Stinner97b89882010-05-06 00:25:39 +00006378 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006379#endif
6380#ifdef _SC_IOV_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006381 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006382#endif
Fred Draked86ed291999-12-15 15:34:33 +00006383#ifdef _SC_IP_SECOPTS
Victor Stinner97b89882010-05-06 00:25:39 +00006384 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00006385#endif
Fred Drakec9680921999-12-13 16:37:25 +00006386#ifdef _SC_JOB_CONTROL
Victor Stinner97b89882010-05-06 00:25:39 +00006387 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00006388#endif
Fred Draked86ed291999-12-15 15:34:33 +00006389#ifdef _SC_KERN_POINTERS
Victor Stinner97b89882010-05-06 00:25:39 +00006390 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00006391#endif
6392#ifdef _SC_KERN_SIM
Victor Stinner97b89882010-05-06 00:25:39 +00006393 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00006394#endif
Fred Drakec9680921999-12-13 16:37:25 +00006395#ifdef _SC_LINE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006396 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006397#endif
6398#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006399 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006400#endif
6401#ifdef _SC_LOGNAME_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006402 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006403#endif
6404#ifdef _SC_LONG_BIT
Victor Stinner97b89882010-05-06 00:25:39 +00006405 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006406#endif
Fred Draked86ed291999-12-15 15:34:33 +00006407#ifdef _SC_MAC
Victor Stinner97b89882010-05-06 00:25:39 +00006408 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00006409#endif
Fred Drakec9680921999-12-13 16:37:25 +00006410#ifdef _SC_MAPPED_FILES
Victor Stinner97b89882010-05-06 00:25:39 +00006411 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00006412#endif
6413#ifdef _SC_MAXPID
Victor Stinner97b89882010-05-06 00:25:39 +00006414 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00006415#endif
6416#ifdef _SC_MB_LEN_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006417 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006418#endif
6419#ifdef _SC_MEMLOCK
Victor Stinner97b89882010-05-06 00:25:39 +00006420 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00006421#endif
6422#ifdef _SC_MEMLOCK_RANGE
Victor Stinner97b89882010-05-06 00:25:39 +00006423 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00006424#endif
6425#ifdef _SC_MEMORY_PROTECTION
Victor Stinner97b89882010-05-06 00:25:39 +00006426 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00006427#endif
6428#ifdef _SC_MESSAGE_PASSING
Victor Stinner97b89882010-05-06 00:25:39 +00006429 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00006430#endif
Fred Draked86ed291999-12-15 15:34:33 +00006431#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner97b89882010-05-06 00:25:39 +00006432 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00006433#endif
Fred Drakec9680921999-12-13 16:37:25 +00006434#ifdef _SC_MQ_OPEN_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006435 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006436#endif
6437#ifdef _SC_MQ_PRIO_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006438 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006439#endif
Fred Draked86ed291999-12-15 15:34:33 +00006440#ifdef _SC_NACLS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006441 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006442#endif
Fred Drakec9680921999-12-13 16:37:25 +00006443#ifdef _SC_NGROUPS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006444 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006445#endif
6446#ifdef _SC_NL_ARGMAX
Victor Stinner97b89882010-05-06 00:25:39 +00006447 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006448#endif
6449#ifdef _SC_NL_LANGMAX
Victor Stinner97b89882010-05-06 00:25:39 +00006450 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006451#endif
6452#ifdef _SC_NL_MSGMAX
Victor Stinner97b89882010-05-06 00:25:39 +00006453 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006454#endif
6455#ifdef _SC_NL_NMAX
Victor Stinner97b89882010-05-06 00:25:39 +00006456 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006457#endif
6458#ifdef _SC_NL_SETMAX
Victor Stinner97b89882010-05-06 00:25:39 +00006459 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006460#endif
6461#ifdef _SC_NL_TEXTMAX
Victor Stinner97b89882010-05-06 00:25:39 +00006462 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006463#endif
6464#ifdef _SC_NPROCESSORS_CONF
Victor Stinner97b89882010-05-06 00:25:39 +00006465 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00006466#endif
6467#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner97b89882010-05-06 00:25:39 +00006468 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00006469#endif
Fred Draked86ed291999-12-15 15:34:33 +00006470#ifdef _SC_NPROC_CONF
Victor Stinner97b89882010-05-06 00:25:39 +00006471 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00006472#endif
6473#ifdef _SC_NPROC_ONLN
Victor Stinner97b89882010-05-06 00:25:39 +00006474 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00006475#endif
Fred Drakec9680921999-12-13 16:37:25 +00006476#ifdef _SC_NZERO
Victor Stinner97b89882010-05-06 00:25:39 +00006477 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00006478#endif
6479#ifdef _SC_OPEN_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006480 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006481#endif
6482#ifdef _SC_PAGESIZE
Victor Stinner97b89882010-05-06 00:25:39 +00006483 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006484#endif
6485#ifdef _SC_PAGE_SIZE
Victor Stinner97b89882010-05-06 00:25:39 +00006486 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006487#endif
6488#ifdef _SC_PASS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006489 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006490#endif
6491#ifdef _SC_PHYS_PAGES
Victor Stinner97b89882010-05-06 00:25:39 +00006492 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006493#endif
6494#ifdef _SC_PII
Victor Stinner97b89882010-05-06 00:25:39 +00006495 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00006496#endif
6497#ifdef _SC_PII_INTERNET
Victor Stinner97b89882010-05-06 00:25:39 +00006498 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00006499#endif
6500#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner97b89882010-05-06 00:25:39 +00006501 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00006502#endif
6503#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner97b89882010-05-06 00:25:39 +00006504 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00006505#endif
6506#ifdef _SC_PII_OSI
Victor Stinner97b89882010-05-06 00:25:39 +00006507 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00006508#endif
6509#ifdef _SC_PII_OSI_CLTS
Victor Stinner97b89882010-05-06 00:25:39 +00006510 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00006511#endif
6512#ifdef _SC_PII_OSI_COTS
Victor Stinner97b89882010-05-06 00:25:39 +00006513 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00006514#endif
6515#ifdef _SC_PII_OSI_M
Victor Stinner97b89882010-05-06 00:25:39 +00006516 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00006517#endif
6518#ifdef _SC_PII_SOCKET
Victor Stinner97b89882010-05-06 00:25:39 +00006519 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00006520#endif
6521#ifdef _SC_PII_XTI
Victor Stinner97b89882010-05-06 00:25:39 +00006522 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00006523#endif
6524#ifdef _SC_POLL
Victor Stinner97b89882010-05-06 00:25:39 +00006525 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00006526#endif
6527#ifdef _SC_PRIORITIZED_IO
Victor Stinner97b89882010-05-06 00:25:39 +00006528 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006529#endif
6530#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner97b89882010-05-06 00:25:39 +00006531 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00006532#endif
6533#ifdef _SC_REALTIME_SIGNALS
Victor Stinner97b89882010-05-06 00:25:39 +00006534 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00006535#endif
6536#ifdef _SC_RE_DUP_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006537 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006538#endif
6539#ifdef _SC_RTSIG_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006540 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006541#endif
6542#ifdef _SC_SAVED_IDS
Victor Stinner97b89882010-05-06 00:25:39 +00006543 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00006544#endif
6545#ifdef _SC_SCHAR_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006546 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006547#endif
6548#ifdef _SC_SCHAR_MIN
Victor Stinner97b89882010-05-06 00:25:39 +00006549 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006550#endif
6551#ifdef _SC_SELECT
Victor Stinner97b89882010-05-06 00:25:39 +00006552 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00006553#endif
6554#ifdef _SC_SEMAPHORES
Victor Stinner97b89882010-05-06 00:25:39 +00006555 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00006556#endif
6557#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006558 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006559#endif
6560#ifdef _SC_SEM_VALUE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006561 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006562#endif
6563#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner97b89882010-05-06 00:25:39 +00006564 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00006565#endif
6566#ifdef _SC_SHRT_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006567 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006568#endif
6569#ifdef _SC_SHRT_MIN
Victor Stinner97b89882010-05-06 00:25:39 +00006570 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006571#endif
6572#ifdef _SC_SIGQUEUE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006573 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006574#endif
6575#ifdef _SC_SIGRT_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006576 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006577#endif
6578#ifdef _SC_SIGRT_MIN
Victor Stinner97b89882010-05-06 00:25:39 +00006579 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006580#endif
Fred Draked86ed291999-12-15 15:34:33 +00006581#ifdef _SC_SOFTPOWER
Victor Stinner97b89882010-05-06 00:25:39 +00006582 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00006583#endif
Fred Drakec9680921999-12-13 16:37:25 +00006584#ifdef _SC_SPLIT_CACHE
Victor Stinner97b89882010-05-06 00:25:39 +00006585 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00006586#endif
6587#ifdef _SC_SSIZE_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006588 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006589#endif
6590#ifdef _SC_STACK_PROT
Victor Stinner97b89882010-05-06 00:25:39 +00006591 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00006592#endif
6593#ifdef _SC_STREAM_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006594 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006595#endif
6596#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner97b89882010-05-06 00:25:39 +00006597 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006598#endif
6599#ifdef _SC_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00006600 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00006601#endif
6602#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner97b89882010-05-06 00:25:39 +00006603 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00006604#endif
6605#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner97b89882010-05-06 00:25:39 +00006606 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006607#endif
6608#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner97b89882010-05-06 00:25:39 +00006609 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00006610#endif
6611#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006612 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006613#endif
6614#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner97b89882010-05-06 00:25:39 +00006615 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00006616#endif
6617#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner97b89882010-05-06 00:25:39 +00006618 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00006619#endif
6620#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner97b89882010-05-06 00:25:39 +00006621 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00006622#endif
6623#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner97b89882010-05-06 00:25:39 +00006624 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00006625#endif
6626#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner97b89882010-05-06 00:25:39 +00006627 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00006628#endif
6629#ifdef _SC_THREAD_STACK_MIN
Victor Stinner97b89882010-05-06 00:25:39 +00006630 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006631#endif
6632#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006633 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006634#endif
6635#ifdef _SC_TIMERS
Victor Stinner97b89882010-05-06 00:25:39 +00006636 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00006637#endif
6638#ifdef _SC_TIMER_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006639 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006640#endif
6641#ifdef _SC_TTY_NAME_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006642 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006643#endif
6644#ifdef _SC_TZNAME_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006645 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006646#endif
6647#ifdef _SC_T_IOV_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006648 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006649#endif
6650#ifdef _SC_UCHAR_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006651 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006652#endif
6653#ifdef _SC_UINT_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006654 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006655#endif
6656#ifdef _SC_UIO_MAXIOV
Victor Stinner97b89882010-05-06 00:25:39 +00006657 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00006658#endif
6659#ifdef _SC_ULONG_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006660 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006661#endif
6662#ifdef _SC_USHRT_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00006663 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006664#endif
6665#ifdef _SC_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006666 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006667#endif
6668#ifdef _SC_WORD_BIT
Victor Stinner97b89882010-05-06 00:25:39 +00006669 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006670#endif
6671#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner97b89882010-05-06 00:25:39 +00006672 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00006673#endif
6674#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner97b89882010-05-06 00:25:39 +00006675 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00006676#endif
6677#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner97b89882010-05-06 00:25:39 +00006678 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00006679#endif
6680#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner97b89882010-05-06 00:25:39 +00006681 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00006682#endif
6683#ifdef _SC_XOPEN_CRYPT
Victor Stinner97b89882010-05-06 00:25:39 +00006684 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00006685#endif
6686#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner97b89882010-05-06 00:25:39 +00006687 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00006688#endif
6689#ifdef _SC_XOPEN_LEGACY
Victor Stinner97b89882010-05-06 00:25:39 +00006690 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00006691#endif
6692#ifdef _SC_XOPEN_REALTIME
Victor Stinner97b89882010-05-06 00:25:39 +00006693 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00006694#endif
6695#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner97b89882010-05-06 00:25:39 +00006696 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00006697#endif
6698#ifdef _SC_XOPEN_SHM
Victor Stinner97b89882010-05-06 00:25:39 +00006699 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00006700#endif
6701#ifdef _SC_XOPEN_UNIX
Victor Stinner97b89882010-05-06 00:25:39 +00006702 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00006703#endif
6704#ifdef _SC_XOPEN_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006705 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006706#endif
6707#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner97b89882010-05-06 00:25:39 +00006708 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006709#endif
6710#ifdef _SC_XOPEN_XPG2
Victor Stinner97b89882010-05-06 00:25:39 +00006711 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00006712#endif
6713#ifdef _SC_XOPEN_XPG3
Victor Stinner97b89882010-05-06 00:25:39 +00006714 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00006715#endif
6716#ifdef _SC_XOPEN_XPG4
Victor Stinner97b89882010-05-06 00:25:39 +00006717 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00006718#endif
6719};
6720
6721static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006722conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006723{
6724 return conv_confname(arg, valuep, posix_constants_sysconf,
6725 sizeof(posix_constants_sysconf)
6726 / sizeof(struct constdef));
6727}
6728
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006729PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006730"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006731Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006732
6733static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006734posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006735{
6736 PyObject *result = NULL;
6737 int name;
6738
6739 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6740 int value;
6741
6742 errno = 0;
6743 value = sysconf(name);
6744 if (value == -1 && errno != 0)
6745 posix_error();
6746 else
Christian Heimes217cfd12007-12-02 14:31:20 +00006747 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00006748 }
6749 return result;
6750}
6751#endif
6752
6753
Fred Drakebec628d1999-12-15 18:31:10 +00006754/* This code is used to ensure that the tables of configuration value names
6755 * are in sorted order as required by conv_confname(), and also to build the
6756 * the exported dictionaries that are used to publish information about the
6757 * names available on the host platform.
6758 *
6759 * Sorting the table at runtime ensures that the table is properly ordered
6760 * when used, even for platforms we're not able to test on. It also makes
6761 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006762 */
Fred Drakebec628d1999-12-15 18:31:10 +00006763
6764static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006765cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006766{
6767 const struct constdef *c1 =
Victor Stinner97b89882010-05-06 00:25:39 +00006768 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00006769 const struct constdef *c2 =
Victor Stinner97b89882010-05-06 00:25:39 +00006770 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00006771
6772 return strcmp(c1->name, c2->name);
6773}
6774
6775static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006776setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner97b89882010-05-06 00:25:39 +00006777 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006778{
Fred Drakebec628d1999-12-15 18:31:10 +00006779 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006780 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006781
6782 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6783 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006784 if (d == NULL)
Victor Stinner97b89882010-05-06 00:25:39 +00006785 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006786
Barry Warsaw3155db32000-04-13 15:20:40 +00006787 for (i=0; i < tablesize; ++i) {
Victor Stinner97b89882010-05-06 00:25:39 +00006788 PyObject *o = PyLong_FromLong(table[i].value);
6789 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6790 Py_XDECREF(o);
6791 Py_DECREF(d);
6792 return -1;
6793 }
6794 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006795 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006796 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006797}
6798
Fred Drakebec628d1999-12-15 18:31:10 +00006799/* Return -1 on failure, 0 on success. */
6800static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006801setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006802{
6803#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006804 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006805 sizeof(posix_constants_pathconf)
6806 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006807 "pathconf_names", module))
Stefan Krah67733312010-11-26 17:04:40 +00006808 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006809#endif
6810#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006811 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006812 sizeof(posix_constants_confstr)
6813 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006814 "confstr_names", module))
Stefan Krah67733312010-11-26 17:04:40 +00006815 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006816#endif
6817#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006818 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006819 sizeof(posix_constants_sysconf)
6820 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006821 "sysconf_names", module))
Stefan Krah67733312010-11-26 17:04:40 +00006822 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006823#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006824 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006825}
Fred Draked86ed291999-12-15 15:34:33 +00006826
6827
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006828PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006829"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006830Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006831in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006832
6833static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006834posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006835{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006836 abort();
6837 /*NOTREACHED*/
6838 Py_FatalError("abort() called from Python code didn't abort!");
6839 return NULL;
6840}
Fred Drakebec628d1999-12-15 18:31:10 +00006841
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006842#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006843PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00006844"startfile(filepath [, operation]) - Start a file with its associated\n\
6845application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006846\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00006847When \"operation\" is not specified or \"open\", this acts like\n\
6848double-clicking the file in Explorer, or giving the file name as an\n\
6849argument to the DOS \"start\" command: the file is opened with whatever\n\
6850application (if any) its extension is associated.\n\
6851When another \"operation\" is given, it specifies what should be done with\n\
6852the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006853\n\
6854startfile returns as soon as the associated application is launched.\n\
6855There is no option to wait for the application to close, and no way\n\
6856to retrieve the application's exit status.\n\
6857\n\
6858The filepath is relative to the current directory. If you want to use\n\
6859an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006860the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006861
6862static PyObject *
6863win32_startfile(PyObject *self, PyObject *args)
6864{
Victor Stinner97b89882010-05-06 00:25:39 +00006865 PyObject *ofilepath;
6866 char *filepath;
6867 char *operation = NULL;
6868 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00006869
Victor Stinner97b89882010-05-06 00:25:39 +00006870 if (unicode_file_names()) {
6871 PyObject *unipath, *woperation = NULL;
6872 if (!PyArg_ParseTuple(args, "U|s:startfile",
6873 &unipath, &operation)) {
6874 PyErr_Clear();
6875 goto normal;
6876 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006877
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006878
Victor Stinner97b89882010-05-06 00:25:39 +00006879 if (operation) {
6880 woperation = PyUnicode_DecodeASCII(operation,
6881 strlen(operation), NULL);
6882 if (!woperation) {
6883 PyErr_Clear();
6884 operation = NULL;
6885 goto normal;
6886 }
6887 }
6888
6889 Py_BEGIN_ALLOW_THREADS
6890 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
6891 PyUnicode_AS_UNICODE(unipath),
6892 NULL, NULL, SW_SHOWNORMAL);
6893 Py_END_ALLOW_THREADS
6894
6895 Py_XDECREF(woperation);
6896 if (rc <= (HINSTANCE)32) {
6897 PyObject *errval = win32_error_unicode("startfile",
6898 PyUnicode_AS_UNICODE(unipath));
6899 return errval;
6900 }
6901 Py_INCREF(Py_None);
6902 return Py_None;
6903 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006904
6905normal:
Victor Stinner97b89882010-05-06 00:25:39 +00006906 if (!PyArg_ParseTuple(args, "O&|s:startfile",
6907 PyUnicode_FSConverter, &ofilepath,
6908 &operation))
6909 return NULL;
6910 filepath = bytes2str(ofilepath, 1);
6911 Py_BEGIN_ALLOW_THREADS
6912 rc = ShellExecute((HWND)0, operation, filepath,
6913 NULL, NULL, SW_SHOWNORMAL);
6914 Py_END_ALLOW_THREADS
6915 if (rc <= (HINSTANCE)32) {
6916 PyObject *errval = win32_error("startfile", filepath);
6917 release_bytes(ofilepath);
6918 return errval;
6919 }
6920 release_bytes(ofilepath);
6921 Py_INCREF(Py_None);
6922 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00006923}
6924#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006925
Martin v. Löwis438b5342002-12-27 10:16:42 +00006926#ifdef HAVE_GETLOADAVG
6927PyDoc_STRVAR(posix_getloadavg__doc__,
6928"getloadavg() -> (float, float, float)\n\n\
6929Return the number of processes in the system run queue averaged over\n\
6930the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6931was unobtainable");
6932
6933static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006934posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006935{
6936 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006937 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah67733312010-11-26 17:04:40 +00006938 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6939 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00006940 } else
Stefan Krah67733312010-11-26 17:04:40 +00006941 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00006942}
6943#endif
6944
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006945#ifdef MS_WINDOWS
6946
6947PyDoc_STRVAR(win32_urandom__doc__,
6948"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006949Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006950
6951typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
6952 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
6953 DWORD dwFlags );
6954typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
6955 BYTE *pbBuffer );
6956
6957static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00006958/* This handle is never explicitly released. Instead, the operating
6959 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006960static HCRYPTPROV hCryptProv = 0;
6961
Tim Peters4ad82172004-08-30 17:02:04 +00006962static PyObject*
6963win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006964{
Victor Stinner97b89882010-05-06 00:25:39 +00006965 int howMany;
6966 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006967
Victor Stinner97b89882010-05-06 00:25:39 +00006968 /* Read arguments */
6969 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
6970 return NULL;
6971 if (howMany < 0)
6972 return PyErr_Format(PyExc_ValueError,
6973 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006974
Victor Stinner97b89882010-05-06 00:25:39 +00006975 if (hCryptProv == 0) {
6976 HINSTANCE hAdvAPI32 = NULL;
6977 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006978
Victor Stinner97b89882010-05-06 00:25:39 +00006979 /* Obtain handle to the DLL containing CryptoAPI
6980 This should not fail */
6981 hAdvAPI32 = GetModuleHandle("advapi32.dll");
6982 if(hAdvAPI32 == NULL)
6983 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006984
Victor Stinner97b89882010-05-06 00:25:39 +00006985 /* Obtain pointers to the CryptoAPI functions
6986 This will fail on some early versions of Win95 */
6987 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
6988 hAdvAPI32,
6989 "CryptAcquireContextA");
6990 if (pCryptAcquireContext == NULL)
6991 return PyErr_Format(PyExc_NotImplementedError,
6992 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006993
Victor Stinner97b89882010-05-06 00:25:39 +00006994 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
6995 hAdvAPI32, "CryptGenRandom");
6996 if (pCryptGenRandom == NULL)
6997 return PyErr_Format(PyExc_NotImplementedError,
6998 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006999
Victor Stinner97b89882010-05-06 00:25:39 +00007000 /* Acquire context */
7001 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7002 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7003 return win32_error("CryptAcquireContext", NULL);
7004 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007005
Victor Stinner97b89882010-05-06 00:25:39 +00007006 /* Allocate bytes */
7007 result = PyBytes_FromStringAndSize(NULL, howMany);
7008 if (result != NULL) {
7009 /* Get random data */
7010 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
7011 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7012 PyBytes_AS_STRING(result))) {
7013 Py_DECREF(result);
7014 return win32_error("CryptGenRandom", NULL);
7015 }
7016 }
7017 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007018}
7019#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007020
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007021PyDoc_STRVAR(device_encoding__doc__,
7022"device_encoding(fd) -> str\n\n\
7023Return a string describing the encoding of the device\n\
7024if the output is a terminal; else return None.");
7025
7026static PyObject *
7027device_encoding(PyObject *self, PyObject *args)
7028{
Victor Stinner97b89882010-05-06 00:25:39 +00007029 int fd;
7030 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
7031 return NULL;
7032 if (!_PyVerify_fd(fd) || !isatty(fd)) {
7033 Py_INCREF(Py_None);
7034 return Py_None;
7035 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007036#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner97b89882010-05-06 00:25:39 +00007037 if (fd == 0) {
7038 char buf[100];
7039 sprintf(buf, "cp%d", GetConsoleCP());
7040 return PyUnicode_FromString(buf);
7041 }
7042 if (fd == 1 || fd == 2) {
7043 char buf[100];
7044 sprintf(buf, "cp%d", GetConsoleOutputCP());
7045 return PyUnicode_FromString(buf);
7046 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007047#elif defined(CODESET)
Victor Stinner97b89882010-05-06 00:25:39 +00007048 {
7049 char *codeset = nl_langinfo(CODESET);
7050 if (codeset != NULL && codeset[0] != 0)
7051 return PyUnicode_FromString(codeset);
7052 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007053#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007054 Py_INCREF(Py_None);
7055 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007056}
7057
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007058#ifdef __VMS
7059/* Use openssl random routine */
7060#include <openssl/rand.h>
7061PyDoc_STRVAR(vms_urandom__doc__,
7062"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007063Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007064
7065static PyObject*
7066vms_urandom(PyObject *self, PyObject *args)
7067{
Victor Stinner97b89882010-05-06 00:25:39 +00007068 int howMany;
7069 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007070
Victor Stinner97b89882010-05-06 00:25:39 +00007071 /* Read arguments */
7072 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7073 return NULL;
7074 if (howMany < 0)
7075 return PyErr_Format(PyExc_ValueError,
7076 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007077
Victor Stinner97b89882010-05-06 00:25:39 +00007078 /* Allocate bytes */
7079 result = PyBytes_FromStringAndSize(NULL, howMany);
7080 if (result != NULL) {
7081 /* Get random data */
7082 if (RAND_pseudo_bytes((unsigned char*)
7083 PyBytes_AS_STRING(result),
7084 howMany) < 0) {
7085 Py_DECREF(result);
7086 return PyErr_Format(PyExc_ValueError,
7087 "RAND_pseudo_bytes");
7088 }
7089 }
7090 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007091}
7092#endif
7093
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007094static PyMethodDef posix_methods[] = {
Victor Stinner97b89882010-05-06 00:25:39 +00007095 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007096#ifdef HAVE_TTYNAME
Victor Stinner97b89882010-05-06 00:25:39 +00007097 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007098#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007099 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007100#ifdef HAVE_CHFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00007101 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007102#endif /* HAVE_CHFLAGS */
Victor Stinner97b89882010-05-06 00:25:39 +00007103 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007104#ifdef HAVE_FCHMOD
Victor Stinner97b89882010-05-06 00:25:39 +00007105 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007106#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007107#ifdef HAVE_CHOWN
Victor Stinner97b89882010-05-06 00:25:39 +00007108 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007109#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00007110#ifdef HAVE_LCHMOD
Victor Stinner97b89882010-05-06 00:25:39 +00007111 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007112#endif /* HAVE_LCHMOD */
7113#ifdef HAVE_FCHOWN
Victor Stinner97b89882010-05-06 00:25:39 +00007114 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007115#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00007116#ifdef HAVE_LCHFLAGS
Victor Stinner97b89882010-05-06 00:25:39 +00007117 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007118#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007119#ifdef HAVE_LCHOWN
Victor Stinner97b89882010-05-06 00:25:39 +00007120 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007121#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007122#ifdef HAVE_CHROOT
Victor Stinner97b89882010-05-06 00:25:39 +00007123 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00007124#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007125#ifdef HAVE_CTERMID
Victor Stinner97b89882010-05-06 00:25:39 +00007126 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007127#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007128#ifdef HAVE_GETCWD
Victor Stinner97b89882010-05-06 00:25:39 +00007129 {"getcwd", (PyCFunction)posix_getcwd_unicode,
7130 METH_NOARGS, posix_getcwd__doc__},
7131 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
7132 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007133#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007134#ifdef HAVE_LINK
Victor Stinner97b89882010-05-06 00:25:39 +00007135 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007136#endif /* HAVE_LINK */
Victor Stinner97b89882010-05-06 00:25:39 +00007137 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7138 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7139 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007140#ifdef HAVE_NICE
Victor Stinner97b89882010-05-06 00:25:39 +00007141 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007142#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007143#ifdef HAVE_READLINK
Victor Stinner97b89882010-05-06 00:25:39 +00007144 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007145#endif /* HAVE_READLINK */
Victor Stinner97b89882010-05-06 00:25:39 +00007146 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7147 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7148 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
7149 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007150#ifdef HAVE_SYMLINK
Victor Stinner97b89882010-05-06 00:25:39 +00007151 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007152#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007153#ifdef HAVE_SYSTEM
Victor Stinner97b89882010-05-06 00:25:39 +00007154 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007155#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007156 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007157#ifdef HAVE_UNAME
Victor Stinner97b89882010-05-06 00:25:39 +00007158 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007159#endif /* HAVE_UNAME */
Victor Stinner97b89882010-05-06 00:25:39 +00007160 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7161 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7162 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007163#ifdef HAVE_TIMES
Victor Stinner97b89882010-05-06 00:25:39 +00007164 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007165#endif /* HAVE_TIMES */
Victor Stinner97b89882010-05-06 00:25:39 +00007166 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007167#ifdef HAVE_EXECV
Victor Stinner97b89882010-05-06 00:25:39 +00007168 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7169 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007170#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007171#ifdef HAVE_SPAWNV
Victor Stinner97b89882010-05-06 00:25:39 +00007172 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7173 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007174#if defined(PYOS_OS2)
Victor Stinner97b89882010-05-06 00:25:39 +00007175 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7176 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007177#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007178#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007179#ifdef HAVE_FORK1
Victor Stinner97b89882010-05-06 00:25:39 +00007180 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007181#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007182#ifdef HAVE_FORK
Victor Stinner97b89882010-05-06 00:25:39 +00007183 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007184#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007185#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner97b89882010-05-06 00:25:39 +00007186 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007187#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007188#ifdef HAVE_FORKPTY
Victor Stinner97b89882010-05-06 00:25:39 +00007189 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007190#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007191#ifdef HAVE_GETEGID
Victor Stinner97b89882010-05-06 00:25:39 +00007192 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007193#endif /* HAVE_GETEGID */
7194#ifdef HAVE_GETEUID
Victor Stinner97b89882010-05-06 00:25:39 +00007195 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007196#endif /* HAVE_GETEUID */
7197#ifdef HAVE_GETGID
Victor Stinner97b89882010-05-06 00:25:39 +00007198 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007199#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007200#ifdef HAVE_GETGROUPS
Victor Stinner97b89882010-05-06 00:25:39 +00007201 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007202#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007203 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007204#ifdef HAVE_GETPGRP
Victor Stinner97b89882010-05-06 00:25:39 +00007205 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007206#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007207#ifdef HAVE_GETPPID
Victor Stinner97b89882010-05-06 00:25:39 +00007208 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007209#endif /* HAVE_GETPPID */
7210#ifdef HAVE_GETUID
Victor Stinner97b89882010-05-06 00:25:39 +00007211 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007212#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007213#ifdef HAVE_GETLOGIN
Victor Stinner97b89882010-05-06 00:25:39 +00007214 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007215#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007216#ifdef HAVE_KILL
Victor Stinner97b89882010-05-06 00:25:39 +00007217 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007218#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007219#ifdef HAVE_KILLPG
Victor Stinner97b89882010-05-06 00:25:39 +00007220 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007221#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007222#ifdef HAVE_PLOCK
Victor Stinner97b89882010-05-06 00:25:39 +00007223 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007224#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007225#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00007226 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +00007227#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007228#ifdef HAVE_SETUID
Victor Stinner97b89882010-05-06 00:25:39 +00007229 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007230#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007231#ifdef HAVE_SETEUID
Victor Stinner97b89882010-05-06 00:25:39 +00007232 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007233#endif /* HAVE_SETEUID */
7234#ifdef HAVE_SETEGID
Victor Stinner97b89882010-05-06 00:25:39 +00007235 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007236#endif /* HAVE_SETEGID */
7237#ifdef HAVE_SETREUID
Victor Stinner97b89882010-05-06 00:25:39 +00007238 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007239#endif /* HAVE_SETREUID */
7240#ifdef HAVE_SETREGID
Victor Stinner97b89882010-05-06 00:25:39 +00007241 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007242#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007243#ifdef HAVE_SETGID
Victor Stinner97b89882010-05-06 00:25:39 +00007244 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007245#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007246#ifdef HAVE_SETGROUPS
Victor Stinner97b89882010-05-06 00:25:39 +00007247 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007248#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007249#ifdef HAVE_GETPGID
Victor Stinner97b89882010-05-06 00:25:39 +00007250 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00007251#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007252#ifdef HAVE_SETPGRP
Victor Stinner97b89882010-05-06 00:25:39 +00007253 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007254#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007255#ifdef HAVE_WAIT
Victor Stinner97b89882010-05-06 00:25:39 +00007256 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007257#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007258#ifdef HAVE_WAIT3
Victor Stinner97b89882010-05-06 00:25:39 +00007259 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007260#endif /* HAVE_WAIT3 */
7261#ifdef HAVE_WAIT4
Victor Stinner97b89882010-05-06 00:25:39 +00007262 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007263#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007264#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner97b89882010-05-06 00:25:39 +00007265 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007266#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007267#ifdef HAVE_GETSID
Victor Stinner97b89882010-05-06 00:25:39 +00007268 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007269#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007270#ifdef HAVE_SETSID
Victor Stinner97b89882010-05-06 00:25:39 +00007271 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007272#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007273#ifdef HAVE_SETPGID
Victor Stinner97b89882010-05-06 00:25:39 +00007274 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007275#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007276#ifdef HAVE_TCGETPGRP
Victor Stinner97b89882010-05-06 00:25:39 +00007277 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007278#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007279#ifdef HAVE_TCSETPGRP
Victor Stinner97b89882010-05-06 00:25:39 +00007280 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007281#endif /* HAVE_TCSETPGRP */
Victor Stinner97b89882010-05-06 00:25:39 +00007282 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7283 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7284 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
7285 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
7286 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7287 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7288 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7289 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7290 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7291 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7292 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007293#ifdef HAVE_PIPE
Victor Stinner97b89882010-05-06 00:25:39 +00007294 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007295#endif
7296#ifdef HAVE_MKFIFO
Victor Stinner97b89882010-05-06 00:25:39 +00007297 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007298#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007299#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner97b89882010-05-06 00:25:39 +00007300 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007301#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007302#ifdef HAVE_DEVICE_MACROS
Victor Stinner97b89882010-05-06 00:25:39 +00007303 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7304 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7305 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007306#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007307#ifdef HAVE_FTRUNCATE
Victor Stinner97b89882010-05-06 00:25:39 +00007308 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007309#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007310#ifdef HAVE_PUTENV
Victor Stinner97b89882010-05-06 00:25:39 +00007311 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007312#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007313#ifdef HAVE_UNSETENV
Victor Stinner97b89882010-05-06 00:25:39 +00007314 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00007315#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007316 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007317#ifdef HAVE_FCHDIR
Victor Stinner97b89882010-05-06 00:25:39 +00007318 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007319#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007320#ifdef HAVE_FSYNC
Victor Stinner97b89882010-05-06 00:25:39 +00007321 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007322#endif
7323#ifdef HAVE_FDATASYNC
Victor Stinner97b89882010-05-06 00:25:39 +00007324 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007325#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007326#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007327#ifdef WCOREDUMP
Victor Stinner97b89882010-05-06 00:25:39 +00007328 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00007329#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007330#ifdef WIFCONTINUED
Victor Stinner97b89882010-05-06 00:25:39 +00007331 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007332#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007333#ifdef WIFSTOPPED
Victor Stinner97b89882010-05-06 00:25:39 +00007334 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007335#endif /* WIFSTOPPED */
7336#ifdef WIFSIGNALED
Victor Stinner97b89882010-05-06 00:25:39 +00007337 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007338#endif /* WIFSIGNALED */
7339#ifdef WIFEXITED
Victor Stinner97b89882010-05-06 00:25:39 +00007340 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007341#endif /* WIFEXITED */
7342#ifdef WEXITSTATUS
Victor Stinner97b89882010-05-06 00:25:39 +00007343 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007344#endif /* WEXITSTATUS */
7345#ifdef WTERMSIG
Victor Stinner97b89882010-05-06 00:25:39 +00007346 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007347#endif /* WTERMSIG */
7348#ifdef WSTOPSIG
Victor Stinner97b89882010-05-06 00:25:39 +00007349 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007350#endif /* WSTOPSIG */
7351#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007352#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner97b89882010-05-06 00:25:39 +00007353 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007354#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007355#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner97b89882010-05-06 00:25:39 +00007356 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007357#endif
Fred Drakec9680921999-12-13 16:37:25 +00007358#ifdef HAVE_CONFSTR
Victor Stinner97b89882010-05-06 00:25:39 +00007359 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007360#endif
7361#ifdef HAVE_SYSCONF
Victor Stinner97b89882010-05-06 00:25:39 +00007362 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007363#endif
7364#ifdef HAVE_FPATHCONF
Victor Stinner97b89882010-05-06 00:25:39 +00007365 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007366#endif
7367#ifdef HAVE_PATHCONF
Victor Stinner97b89882010-05-06 00:25:39 +00007368 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007369#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007370 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007371#ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00007372 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Mark Hammondef8b6542001-05-13 08:04:26 +00007373#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007374#ifdef HAVE_GETLOADAVG
Victor Stinner97b89882010-05-06 00:25:39 +00007375 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007376#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007377 #ifdef MS_WINDOWS
Victor Stinner97b89882010-05-06 00:25:39 +00007378 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007379 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007380 #ifdef __VMS
Victor Stinner97b89882010-05-06 00:25:39 +00007381 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007382 #endif
Victor Stinner97b89882010-05-06 00:25:39 +00007383 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007384};
7385
7386
Barry Warsaw4a342091996-12-19 23:50:02 +00007387static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007388ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007389{
Victor Stinner97b89882010-05-06 00:25:39 +00007390 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007391}
7392
Guido van Rossumd48f2521997-12-05 22:19:34 +00007393#if defined(PYOS_OS2)
7394/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007395static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007396{
7397 APIRET rc;
7398 ULONG values[QSV_MAX+1];
7399 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007400 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007401
7402 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007403 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007404 Py_END_ALLOW_THREADS
7405
7406 if (rc != NO_ERROR) {
7407 os2_error(rc);
7408 return -1;
7409 }
7410
Fred Drake4d1e64b2002-04-15 19:40:07 +00007411 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7412 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7413 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7414 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7415 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7416 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7417 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007418
7419 switch (values[QSV_VERSION_MINOR]) {
7420 case 0: ver = "2.00"; break;
7421 case 10: ver = "2.10"; break;
7422 case 11: ver = "2.11"; break;
7423 case 30: ver = "3.00"; break;
7424 case 40: ver = "4.00"; break;
7425 case 50: ver = "5.00"; break;
7426 default:
Tim Peters885d4572001-11-28 20:27:42 +00007427 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner97b89882010-05-06 00:25:39 +00007428 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00007429 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007430 ver = &tmp[0];
7431 }
7432
7433 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007434 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007435 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007436
7437 /* Add Indicator of Which Drive was Used to Boot the System */
7438 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7439 tmp[1] = ':';
7440 tmp[2] = '\0';
7441
Fred Drake4d1e64b2002-04-15 19:40:07 +00007442 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007443}
7444#endif
7445
Barry Warsaw4a342091996-12-19 23:50:02 +00007446static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007447all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007448{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007449#ifdef F_OK
Victor Stinner97b89882010-05-06 00:25:39 +00007450 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007451#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007452#ifdef R_OK
Victor Stinner97b89882010-05-06 00:25:39 +00007453 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007454#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007455#ifdef W_OK
Victor Stinner97b89882010-05-06 00:25:39 +00007456 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007457#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007458#ifdef X_OK
Victor Stinner97b89882010-05-06 00:25:39 +00007459 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007460#endif
Fred Drakec9680921999-12-13 16:37:25 +00007461#ifdef NGROUPS_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00007462 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00007463#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007464#ifdef TMP_MAX
Victor Stinner97b89882010-05-06 00:25:39 +00007465 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007466#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007467#ifdef WCONTINUED
Victor Stinner97b89882010-05-06 00:25:39 +00007468 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00007469#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007470#ifdef WNOHANG
Victor Stinner97b89882010-05-06 00:25:39 +00007471 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007472#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007473#ifdef WUNTRACED
Victor Stinner97b89882010-05-06 00:25:39 +00007474 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00007475#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007476#ifdef O_RDONLY
Victor Stinner97b89882010-05-06 00:25:39 +00007477 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007478#endif
7479#ifdef O_WRONLY
Victor Stinner97b89882010-05-06 00:25:39 +00007480 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007481#endif
7482#ifdef O_RDWR
Victor Stinner97b89882010-05-06 00:25:39 +00007483 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007484#endif
7485#ifdef O_NDELAY
Victor Stinner97b89882010-05-06 00:25:39 +00007486 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007487#endif
7488#ifdef O_NONBLOCK
Victor Stinner97b89882010-05-06 00:25:39 +00007489 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007490#endif
7491#ifdef O_APPEND
Victor Stinner97b89882010-05-06 00:25:39 +00007492 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007493#endif
7494#ifdef O_DSYNC
Victor Stinner97b89882010-05-06 00:25:39 +00007495 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007496#endif
7497#ifdef O_RSYNC
Victor Stinner97b89882010-05-06 00:25:39 +00007498 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007499#endif
7500#ifdef O_SYNC
Victor Stinner97b89882010-05-06 00:25:39 +00007501 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007502#endif
7503#ifdef O_NOCTTY
Victor Stinner97b89882010-05-06 00:25:39 +00007504 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007505#endif
7506#ifdef O_CREAT
Victor Stinner97b89882010-05-06 00:25:39 +00007507 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007508#endif
7509#ifdef O_EXCL
Victor Stinner97b89882010-05-06 00:25:39 +00007510 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007511#endif
7512#ifdef O_TRUNC
Victor Stinner97b89882010-05-06 00:25:39 +00007513 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00007514#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007515#ifdef O_BINARY
Victor Stinner97b89882010-05-06 00:25:39 +00007516 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00007517#endif
7518#ifdef O_TEXT
Victor Stinner97b89882010-05-06 00:25:39 +00007519 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00007520#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007521#ifdef O_LARGEFILE
Victor Stinner97b89882010-05-06 00:25:39 +00007522 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007523#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007524#ifdef O_SHLOCK
Victor Stinner97b89882010-05-06 00:25:39 +00007525 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00007526#endif
7527#ifdef O_EXLOCK
Victor Stinner97b89882010-05-06 00:25:39 +00007528 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00007529#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007530
Tim Peters5aa91602002-01-30 05:46:57 +00007531/* MS Windows */
7532#ifdef O_NOINHERIT
Victor Stinner97b89882010-05-06 00:25:39 +00007533 /* Don't inherit in child processes. */
7534 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007535#endif
7536#ifdef _O_SHORT_LIVED
Victor Stinner97b89882010-05-06 00:25:39 +00007537 /* Optimize for short life (keep in memory). */
7538 /* MS forgot to define this one with a non-underscore form too. */
7539 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007540#endif
7541#ifdef O_TEMPORARY
Victor Stinner97b89882010-05-06 00:25:39 +00007542 /* Automatically delete when last handle is closed. */
7543 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007544#endif
7545#ifdef O_RANDOM
Victor Stinner97b89882010-05-06 00:25:39 +00007546 /* Optimize for random access. */
7547 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007548#endif
7549#ifdef O_SEQUENTIAL
Victor Stinner97b89882010-05-06 00:25:39 +00007550 /* Optimize for sequential access. */
7551 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007552#endif
7553
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007554/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00007555#ifdef O_ASYNC
Victor Stinner97b89882010-05-06 00:25:39 +00007556 /* Send a SIGIO signal whenever input or output
7557 becomes available on file descriptor */
7558 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +00007559#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007560#ifdef O_DIRECT
Victor Stinner97b89882010-05-06 00:25:39 +00007561 /* Direct disk access. */
7562 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007563#endif
7564#ifdef O_DIRECTORY
Victor Stinner97b89882010-05-06 00:25:39 +00007565 /* Must be a directory. */
7566 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007567#endif
7568#ifdef O_NOFOLLOW
Victor Stinner97b89882010-05-06 00:25:39 +00007569 /* Do not follow links. */
7570 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007571#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00007572#ifdef O_NOATIME
Victor Stinner97b89882010-05-06 00:25:39 +00007573 /* Do not update the access time. */
7574 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00007575#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007576
Victor Stinner97b89882010-05-06 00:25:39 +00007577 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007578#ifdef EX_OK
Victor Stinner97b89882010-05-06 00:25:39 +00007579 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007580#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007581#ifdef EX_USAGE
Victor Stinner97b89882010-05-06 00:25:39 +00007582 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007583#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007584#ifdef EX_DATAERR
Victor Stinner97b89882010-05-06 00:25:39 +00007585 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007586#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007587#ifdef EX_NOINPUT
Victor Stinner97b89882010-05-06 00:25:39 +00007588 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007589#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007590#ifdef EX_NOUSER
Victor Stinner97b89882010-05-06 00:25:39 +00007591 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007592#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007593#ifdef EX_NOHOST
Victor Stinner97b89882010-05-06 00:25:39 +00007594 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007595#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007596#ifdef EX_UNAVAILABLE
Victor Stinner97b89882010-05-06 00:25:39 +00007597 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007598#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007599#ifdef EX_SOFTWARE
Victor Stinner97b89882010-05-06 00:25:39 +00007600 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007601#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007602#ifdef EX_OSERR
Victor Stinner97b89882010-05-06 00:25:39 +00007603 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007604#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007605#ifdef EX_OSFILE
Victor Stinner97b89882010-05-06 00:25:39 +00007606 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007607#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007608#ifdef EX_CANTCREAT
Victor Stinner97b89882010-05-06 00:25:39 +00007609 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007610#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007611#ifdef EX_IOERR
Victor Stinner97b89882010-05-06 00:25:39 +00007612 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007613#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007614#ifdef EX_TEMPFAIL
Victor Stinner97b89882010-05-06 00:25:39 +00007615 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007616#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007617#ifdef EX_PROTOCOL
Victor Stinner97b89882010-05-06 00:25:39 +00007618 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007619#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007620#ifdef EX_NOPERM
Victor Stinner97b89882010-05-06 00:25:39 +00007621 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007622#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007623#ifdef EX_CONFIG
Victor Stinner97b89882010-05-06 00:25:39 +00007624 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007625#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007626#ifdef EX_NOTFOUND
Victor Stinner97b89882010-05-06 00:25:39 +00007627 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007628#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007629
Guido van Rossum246bc171999-02-01 23:54:31 +00007630#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007631#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner97b89882010-05-06 00:25:39 +00007632 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7633 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7634 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7635 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7636 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7637 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7638 if (ins(d, "P_PM", (long)P_PM)) return -1;
7639 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7640 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7641 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7642 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7643 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7644 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7645 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7646 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7647 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7648 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7649 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7650 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7651 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007652#else
Victor Stinner97b89882010-05-06 00:25:39 +00007653 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7654 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7655 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7656 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7657 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007658#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007659#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007660
Guido van Rossumd48f2521997-12-05 22:19:34 +00007661#if defined(PYOS_OS2)
Victor Stinner97b89882010-05-06 00:25:39 +00007662 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007663#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007664 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00007665}
7666
7667
Tim Peters5aa91602002-01-30 05:46:57 +00007668#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007669#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007670#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007671
7672#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007673#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007674#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007675
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007676#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00007677#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007678#define MODNAME "posix"
7679#endif
7680
Martin v. Löwis1a214512008-06-11 05:26:20 +00007681static struct PyModuleDef posixmodule = {
Victor Stinner97b89882010-05-06 00:25:39 +00007682 PyModuleDef_HEAD_INIT,
7683 MODNAME,
7684 posix__doc__,
7685 -1,
7686 posix_methods,
7687 NULL,
7688 NULL,
7689 NULL,
7690 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00007691};
7692
7693
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007694PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007695INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007696{
Victor Stinner97b89882010-05-06 00:25:39 +00007697 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007698
Victor Stinner97b89882010-05-06 00:25:39 +00007699 m = PyModule_Create(&posixmodule);
7700 if (m == NULL)
7701 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007702
Victor Stinner97b89882010-05-06 00:25:39 +00007703 /* Initialize environ dictionary */
7704 v = convertenviron();
7705 Py_XINCREF(v);
7706 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
7707 return NULL;
7708 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007709
Victor Stinner97b89882010-05-06 00:25:39 +00007710 if (all_ins(m))
7711 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00007712
Victor Stinner97b89882010-05-06 00:25:39 +00007713 if (setup_confname_tables(m))
7714 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00007715
Victor Stinner97b89882010-05-06 00:25:39 +00007716 Py_INCREF(PyExc_OSError);
7717 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007718
Guido van Rossumb3d39562000-01-31 18:41:26 +00007719#ifdef HAVE_PUTENV
Victor Stinner97b89882010-05-06 00:25:39 +00007720 if (posix_putenv_garbage == NULL)
7721 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007722#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007723
Victor Stinner97b89882010-05-06 00:25:39 +00007724 if (!initialized) {
7725 stat_result_desc.name = MODNAME ".stat_result";
7726 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7727 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7728 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
7729 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
7730 structseq_new = StatResultType.tp_new;
7731 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007732
Victor Stinner97b89882010-05-06 00:25:39 +00007733 statvfs_result_desc.name = MODNAME ".statvfs_result";
7734 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007735#ifdef NEED_TICKS_PER_SECOND
7736# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner97b89882010-05-06 00:25:39 +00007737 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007738# elif defined(HZ)
Victor Stinner97b89882010-05-06 00:25:39 +00007739 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007740# else
Victor Stinner97b89882010-05-06 00:25:39 +00007741 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007742# endif
7743#endif
Victor Stinner97b89882010-05-06 00:25:39 +00007744 }
7745 Py_INCREF((PyObject*) &StatResultType);
7746 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
7747 Py_INCREF((PyObject*) &StatVFSResultType);
7748 PyModule_AddObject(m, "statvfs_result",
7749 (PyObject*) &StatVFSResultType);
7750 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007751
7752#ifdef __APPLE__
Victor Stinner97b89882010-05-06 00:25:39 +00007753 /*
7754 * Step 2 of weak-linking support on Mac OS X.
7755 *
7756 * The code below removes functions that are not available on the
7757 * currently active platform.
7758 *
7759 * This block allow one to use a python binary that was build on
7760 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
7761 * OSX 10.4.
7762 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007763#ifdef HAVE_FSTATVFS
Victor Stinner97b89882010-05-06 00:25:39 +00007764 if (fstatvfs == NULL) {
7765 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
7766 return NULL;
7767 }
7768 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00007769#endif /* HAVE_FSTATVFS */
7770
7771#ifdef HAVE_STATVFS
Victor Stinner97b89882010-05-06 00:25:39 +00007772 if (statvfs == NULL) {
7773 if (PyObject_DelAttrString(m, "statvfs") == -1) {
7774 return NULL;
7775 }
7776 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00007777#endif /* HAVE_STATVFS */
7778
7779# ifdef HAVE_LCHOWN
Victor Stinner97b89882010-05-06 00:25:39 +00007780 if (lchown == NULL) {
7781 if (PyObject_DelAttrString(m, "lchown") == -1) {
7782 return NULL;
7783 }
7784 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00007785#endif /* HAVE_LCHOWN */
7786
7787
7788#endif /* __APPLE__ */
Victor Stinner97b89882010-05-06 00:25:39 +00007789 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007790
Guido van Rossumb6775db1994-08-01 11:34:53 +00007791}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007792
7793#ifdef __cplusplus
7794}
7795#endif